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:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-08-19 13:36:40 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-08-19 13:36:40 +0400
commit7ef3f98de1339f9b25ce5670b9b5d5e5ef798327 (patch)
treebfdd9b53c3c6a382b8eb915e8cc4d1812c88a4fc /source/blender/blenkernel
parent345fff872b19a48ea674815165c7e8a0bd57f2ba (diff)
Made curves almost thread-safe
Now modifier stack wouldn't modify original curve's nurbs and will operate on a copy of nurbs. This makes it possible to process curve object update with shared curve datablocks from multiple threads. There's no big overhead for creating a copy of nurbs comparing to old behavior which was allocating original vertex array and apply coordinates on curve after all modifier are applied. The only remained issue with curves is curve's bounding box and texture space. It's not thread-safe, but it wouldn't lead to crashes -- it just could lead to either memory leak or wrong texture coordinates due to difference in modifiers stacks of objects which shares the same curve. -- svn merge -r57959:57961 ^/branches/soc-2013-depsgraph_mt
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_anim.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h2
-rw-r--r--source/blender/blenkernel/intern/anim.c4
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c10
-rw-r--r--source/blender/blenkernel/intern/displist.c83
-rw-r--r--source/blender/blenkernel/intern/mesh.c4
7 files changed, 44 insertions, 63 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 539c5780cd5..7de7a745ed6 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -59,7 +59,7 @@ void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets);
/* Curve Paths */
void free_path(struct Path *path);
-void calc_curvepath(struct Object *ob);
+void calc_curvepath(struct Object *ob, struct ListBase *nurbs);
int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], float quat[4], float *radius, float *weight);
/* ---------------------------------------------------- */
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index f468415ef3d..b2daf1ff732 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -94,7 +94,7 @@ struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob, int *r_numVerts);
float *BKE_curve_surf_make_orco(struct Object *ob);
-void BKE_curve_bevelList_make(struct Object *ob);
+void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp, int forRender, int renderResolution);
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index f3e2b118f2e..b5a56024976 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -488,7 +488,7 @@ void free_path(Path *path)
/* calculate a curve-deform path for a curve
* - only called from displist.c -> do_makeDispListCurveTypes
*/
-void calc_curvepath(Object *ob)
+void calc_curvepath(Object *ob, ListBase *nurbs)
{
BevList *bl;
BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
@@ -499,7 +499,6 @@ void calc_curvepath(Object *ob)
float *fp, *dist, *maxdist, xyz[3];
float fac, d = 0, fac1, fac2;
int a, tot, cycl = 0;
- ListBase *nurbs;
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
@@ -518,7 +517,6 @@ void calc_curvepath(Object *ob)
return;
}
- nurbs = BKE_curve_nurbs_get(cu);
nu = nurbs->first;
ob->curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 5ab618c4001..00a2c45d8fd 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1814,7 +1814,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
DerivedMesh *CDDM_from_curve(Object *ob)
{
- ListBase disp = {NULL};
+ ListBase disp = {NULL, NULL};
if (ob->curve_cache) {
disp = ob->curve_cache->disp;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 8f6b4e002bd..120080665d7 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2417,7 +2417,7 @@ static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl)
}
}
-void BKE_curve_bevelList_make(Object *ob)
+void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
{
/*
* - convert all curves to polys, with indication of resol and flags for double-vertices
@@ -2449,14 +2449,10 @@ void BKE_curve_bevelList_make(Object *ob)
/* STEP 1: MAKE POLYS */
BLI_freelistN(&(ob->curve_cache->bev));
+ nu = nurbs->first;
if (cu->editnurb && ob->type != OB_FONT) {
- ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- nu = nurbs->first;
is_editmode = 1;
}
- else {
- nu = cu->nurb.first;
- }
for (; nu; nu = nu->next) {
@@ -2477,7 +2473,7 @@ void BKE_curve_bevelList_make(Object *ob)
bl->charidx = nu->charidx;
}
else {
- if (G.is_rendering && cu->resolu_ren != 0)
+ if (for_render && cu->resolu_ren != 0)
resolu = cu->resolu_ren;
else
resolu = nu->resolu;
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 755068b53bb..6bcf6b148a3 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -786,19 +786,16 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int re
return pretessellatePoint;
}
-static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, int renderResolution,
- float (**originalVerts_r)[3],
- float (**deformedVerts_r)[3], int *numVerts_r)
+static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb,
+ int forRender, int renderResolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
ModifierData *pretessellatePoint;
Curve *cu = ob->data;
- ListBase *nurb = BKE_curve_nurbs_get(cu);
int numVerts = 0;
const int editmode = (!forRender && (cu->editnurb || cu->editfont));
ModifierApplyFlag app_flag = 0;
- float (*originalVerts)[3] = NULL;
float (*deformedVerts)[3] = NULL;
float *keyVerts = NULL;
int required_mode;
@@ -826,7 +823,6 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, in
* this is also the reason curves do not use a virtual
* shape key modifier yet. */
deformedVerts = BKE_curve_nurbs_keyVertexCos_get(nurb, keyVerts);
- originalVerts = MEM_dupallocN(deformedVerts);
BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts);
}
}
@@ -844,7 +840,6 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, in
if (!deformedVerts) {
deformedVerts = BKE_curve_nurbs_vertexCos_get(nurb, &numVerts);
- originalVerts = MEM_dupallocN(deformedVerts);
}
mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, app_flag);
@@ -854,17 +849,15 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, in
}
}
- if (deformedVerts)
+ if (deformedVerts) {
BK_curve_nurbs_vertexCos_apply(nurb, deformedVerts);
+ MEM_freeN(deformedVerts);
+ }
if (keyVerts) /* these are not passed through modifier stack */
BKE_curve_nurbs_keyVertexTilts_apply(nurb, keyVerts);
if (keyVerts)
MEM_freeN(keyVerts);
-
- *originalVerts_r = originalVerts;
- *deformedVerts_r = deformedVerts;
- *numVerts_r = numVerts;
}
static float (*displist_get_allverts(ListBase *dispbase, int *totvert))[3]
@@ -901,15 +894,14 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
}
}
-static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **derivedFinal,
- int forRender, int renderResolution,
- float (*originalVerts)[3], float (*deformedVerts)[3])
+static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
+ ListBase *dispbase, DerivedMesh **derivedFinal,
+ int forRender, int renderResolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
ModifierData *pretessellatePoint;
Curve *cu = ob->data;
- ListBase *nurb = BKE_curve_nurbs_get(cu);
int required_mode = 0, totvert = 0;
int editmode = (!forRender && (cu->editnurb || cu->editfont));
DerivedMesh *dm = NULL, *ndm;
@@ -1054,12 +1046,6 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
}
(*derivedFinal) = dm;
}
-
- if (deformedVerts) {
- BK_curve_nurbs_vertexCos_apply(nurb, originalVerts);
- MEM_freeN(originalVerts);
- MEM_freeN(deformedVerts);
- }
}
static void displist_surf_indices(DispList *dl)
@@ -1209,25 +1195,24 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina
void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution)
{
- ListBase *nubase;
+ ListBase nubase = {NULL, NULL};
Nurb *nu;
Curve *cu = ob->data;
DispList *dl;
float *data;
int len;
- int numVerts;
- float (*originalVerts)[3];
- float (*deformedVerts)[3];
- if (!forRender && cu->editnurb)
- nubase = BKE_curve_editNurbs_get(cu);
- else
- nubase = &cu->nurb;
+ if (!forRender && cu->editnurb) {
+ BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu));
+ }
+ else {
+ BKE_nurbList_duplicate(&nubase, &cu->nurb);
+ }
if (!forOrco)
- curve_calc_modifiers_pre(scene, ob, forRender, renderResolution, &originalVerts, &deformedVerts, &numVerts);
+ curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
- for (nu = nubase->first; nu; nu = nu->next) {
+ for (nu = nubase.first; nu; nu = nu->next) {
if (forRender || nu->hide == 0) {
int resolu = nu->resolu, resolv = nu->resolv;
@@ -1291,6 +1276,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
}
/* Calculate curve's boundig box from non-modified display list. */
+ /* TODO(sergey): not thread-safe. */
if (cu->bb == NULL) {
cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
}
@@ -1301,10 +1287,11 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
}
if (!forOrco) {
- curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal,
- forRender, renderResolution,
- originalVerts, deformedVerts);
+ curve_calc_modifiers_post(scene, ob, &nubase, dispbase, derivedFinal,
+ forRender, renderResolution);
}
+
+ BKE_nurbList_free(&nubase);
}
static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispList *dlb, float bev_blend, float widfac, float fac, float **data_r)
@@ -1398,12 +1385,9 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
else if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
ListBase dlbev;
- ListBase *nubase;
- float (*originalVerts)[3];
- float (*deformedVerts)[3];
- int numVerts;
+ ListBase nubase = {NULL, NULL};
- nubase = BKE_curve_nurbs_get(cu);
+ BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu));
BLI_freelistN(&(ob->curve_cache->bev));
@@ -1414,21 +1398,21 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
BKE_vfont_to_curve(G.main, scene, ob, 0);
if (!forOrco)
- curve_calc_modifiers_pre(scene, ob, forRender, renderResolution, &originalVerts, &deformedVerts, &numVerts);
+ curve_calc_modifiers_pre(scene, ob, &nubase, forRender, renderResolution);
- BKE_curve_bevelList_make(ob);
+ BKE_curve_bevelList_make(ob, &nubase, forRender != FALSE);
/* If curve has no bevel will return nothing */
BKE_curve_bevel_make(scene, ob, &dlbev, forRender, renderResolution);
/* no bevel or extrude, and no width correction? */
if (!dlbev.first && cu->width == 1.0f) {
- curve_to_displist(cu, nubase, dispbase, forRender, renderResolution);
+ curve_to_displist(cu, &nubase, dispbase, forRender, renderResolution);
}
else {
float widfac = cu->width - 1.0f;
BevList *bl = ob->curve_cache->bev.first;
- Nurb *nu = nubase->first;
+ Nurb *nu = nubase.first;
for (; bl && nu; bl = bl->next, nu = nu->next) {
DispList *dl;
@@ -1595,13 +1579,14 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
if (!(cu->flag & CU_DEFORM_FILL)) {
- curve_to_filledpoly(cu, nubase, dispbase);
+ curve_to_filledpoly(cu, &nubase, dispbase);
}
if ((cu->flag & CU_PATH) && !forOrco)
- calc_curvepath(ob);
+ calc_curvepath(ob, &nubase);
/* Calculate curve's boundig box from non-modified display list. */
+ /* TODO(sergey): not thread-safe. */
if (cu->bb == NULL) {
cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
}
@@ -1612,11 +1597,13 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
}
if (!forOrco)
- curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, renderResolution, originalVerts, deformedVerts);
+ curve_calc_modifiers_post(scene, ob, &nubase, dispbase, derivedFinal, forRender, renderResolution);
if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) {
- curve_to_filledpoly(cu, nubase, dispbase);
+ curve_to_filledpoly(cu, &nubase, dispbase);
}
+
+ BKE_nurbList_free(&nubase);
}
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index ada1dfa2a69..a5556b7e817 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1307,7 +1307,7 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
MEdge **alledge, int *totedge, MLoop **allloop, MPoly **allpoly,
int *totloop, int *totpoly)
{
- ListBase disp = {NULL};
+ ListBase disp = {NULL, NULL};
if (ob->curve_cache) {
disp = ob->curve_cache->disp;
@@ -1659,7 +1659,7 @@ void BKE_mesh_from_nurbs(Object *ob)
{
Curve *cu = (Curve *) ob->data;
bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
- ListBase disp = {NULL};
+ ListBase disp = {NULL, NULL};
if (ob->curve_cache) {
disp = ob->curve_cache->disp;