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

Reply via email to