Revision: 48897
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48897
Author: mont29
Date: 2012-07-13 20:50:32 +0000 (Fri, 13 Jul 2012)
Log Message:
-----------
Fix [#32013] Crash loading a 2.49b model
Problems were in the old multires loading system.
Actually, the sigsev itself was the easy part of the job (simply had to convert
from tesselated data to polys/loops), but after that I was getting a horrible
bunch of wild stray faces...
It finally turned out it was a mismatch in two different subsurf structs used
while computing a mdisps layer from the multires DM, leading to getting
complete random normals (null ones, NAN ones...), leading to complete dummy
tangent space matrix, leading to absurds mdisps values...
Note: I also moved the copy of first layer's vertex and face data from old
me->mr to mesh's v/fdata earlier in multire_load_old(), to be able to use
general face_to_poly conversion function (later on we would have to do it by
hand, the general function would erase our newly computed mdisps layer...).
Took me the whole week (something like 20h) to track this down: multires +
subsurf = C nightmare!
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/multires.c
Modified: trunk/blender/source/blender/blenkernel/intern/multires.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/multires.c 2012-07-13
19:59:38 UTC (rev 48896)
+++ trunk/blender/source/blender/blenkernel/intern/multires.c 2012-07-13
20:50:32 UTC (rev 48897)
@@ -992,6 +992,9 @@
copy_v3_v3(mat[2], CCG_grid_elem_no(key, grid, x, y));
}
+/* XXX WARNING: subsurf elements from dm and oldGridData *must* be of the same
format (size),
+ * because this code uses CCGKey's info from dm to access
oldGridData's normals
+ * (through the call to grid_tangent_matrix())! */
static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh
*dm2, DispOp op, CCGElem **oldGridData, int totlvl)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
@@ -2069,6 +2072,21 @@
me->mface[i].mat_nr = lvl->faces[i].mat_nr;
}
+ /* Copy the first-level data to the mesh */
+ /* XXX We must do this before converting tessfaces to polys/lopps! */
+ for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i,
++l)
+ CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE,
l->data, me->totvert);
+ for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i,
++l)
+ CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE,
l->data, me->totface);
+ memset(&me->mr->vdata, 0, sizeof(CustomData));
+ memset(&me->mr->fdata, 0, sizeof(CustomData));
+
+ multires_load_old_vcols(me);
+ multires_load_old_face_flags(me);
+
+ /* multiresModifier_subdivide (actually, multires_subdivide) expects
polys, not tessfaces! */
+ BKE_mesh_convert_mfaces_to_mpolys(me);
+
/* Add a multires modifier to the object */
md = ob->modifiers.first;
while (md && modifierType_getInfo(md->type)->type ==
eModifierTypeType_OnlyDeform)
@@ -2081,25 +2099,19 @@
mmd->lvl = mmd->totlvl;
orig = CDDM_from_mesh(me, NULL);
- dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
-
+ /* XXX We *must* alloc paint mask here, else we have some kind of
mismatch in
+ * multires_modifier_update_mdisps() (called by dm->release(dm)),
which always creates the
+ * reference subsurfed dm with this option, before calling
multiresModifier_disp_run(),
+ * which implitely expects both subsurfs from its first dm and
oldGridData parameters to
+ * be of the same "format"! */
+ dm = multires_make_derived_from_derived(orig, mmd, ob,
MULTIRES_ALLOC_PAINT_MASK);
+
multires_load_old_dm(dm, me, mmd->totlvl + 1);
multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED);
dm->release(dm);
orig->release(orig);
- /* Copy the first-level data to the mesh */
- for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; ++i,
++l)
- CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE,
l->data, me->totvert);
- for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i,
++l)
- CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE,
l->data, me->totface);
- memset(&me->mr->vdata, 0, sizeof(CustomData));
- memset(&me->mr->fdata, 0, sizeof(CustomData));
-
- multires_load_old_vcols(me);
- multires_load_old_face_flags(me);
-
/* Remove the old multires */
multires_free(me->mr);
me->mr = NULL;
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs