py api: BMesh.from_object() was using the derivedFinal, which isn't always available...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 21 Nov 2012 00:31:47 +0000 (00:31 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 21 Nov 2012 00:31:47 +0000 (00:31 +0000)
update the function to calculate the derived mesh with bmesh data-mask each time.

resolves bug [#33205] Bmesh "from_object" gives "no usable mesh data".

also found 'mesh_build_data' could run with non mesh objects and fail silently - add an assert.

source/blender/blenkernel/intern/DerivedMesh.c
source/blender/python/bmesh/bmesh_py_types.c

index cca425a63d8fe756f02ac2a5ce37ed9a323b92a9..3736395313ddf80b003eb28cb01d5d87616f2a2b 100644 (file)
@@ -2167,6 +2167,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
        /* weight paint and face select need original indices because of selection buffer drawing */
        int needMapping = (ob == obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)));
 
+       BLI_assert(ob->type == OB_MESH);
+
        clear_mesh_caches(ob);
 
        mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
index f98e7c71ec0c7d0c3c3880dc4be58341ede91c51..ee4528df50d3e631b499e06a8dc64f333d8c06fc 100644 (file)
@@ -801,34 +801,92 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-/* note: rna_Object_to_mesh() also has apply_modifiers arg that works the same way */
 PyDoc_STRVAR(bpy_bmesh_from_object_doc,
-".. method:: from_object(mesh, apply_modifiers=True)\n"
+".. method:: from_object(object, scene, deform=True, render=False, cage=False)\n"
 "\n"
-"   Initialize this bmesh from existing object datablock.\n"
+"   Initialize this bmesh from existing object datablock (currently only meshes are supported).\n"
 "\n"
 "   :arg object: The object data to load.\n"
 "   :type object: :class:`Object`\n"
-"   :arg apply_modifiers: Use the final display mesh rather then the deformed cage.\n"
-"   :type apply_modifiers: boolean\n"
+"   :arg deform: Apply deformation modifiers.\n"
+"   :type deform: boolean\n"
+"   :arg render: Use render settings.\n"
+"   :type render: boolean\n"
+"   :arg cage: Get the mesh as a deformed cage.\n"
+"   :type cage: boolean\n"
 );
 static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
 {
        PyObject *py_object;
+       PyObject *py_scene;
        Object *ob;
+       struct Scene *scene;
        BMesh *bm;
-       int apply_modifiers = TRUE;
+       int use_deform = TRUE;
+       int use_render = FALSE;
+       int use_cage   = FALSE;
        DerivedMesh *dm;
+       const int mask = CD_MASK_BMESH;
 
        BPY_BM_CHECK_OBJ(self);
 
-       if (!PyArg_ParseTuple(args, "O|i:from_object", &py_object, &apply_modifiers) ||
-           !(ob = PyC_RNA_AsPointer(py_object, "Object")))
+       if (!PyArg_ParseTuple(args, "OO|iii:from_object", &py_object, &py_scene, &use_render, &use_cage) ||
+           !(ob    = PyC_RNA_AsPointer(py_object, "Object")) ||
+           !(scene = PyC_RNA_AsPointer(py_scene,  "Scene")))
        {
                return NULL;
        }
 
-       dm = apply_modifiers ? ob->derivedFinal : ob->derivedDeform;
+       if (ob->type != OB_MESH) {
+               PyErr_SetString(PyExc_ValueError,
+                               "from_object(...): currently only mesh objects are supported");
+               return NULL;
+       }
+
+       /* Write the display mesh into the dummy mesh */
+       if (use_deform) {
+               if (use_render) {
+                       if (use_cage) {
+                               PyErr_SetString(PyExc_ValueError,
+                                               "from_object(...): cage arg is unsupported when (render=True)");
+                               return NULL;
+                       }
+                       else {
+                               dm = mesh_create_derived_render(scene, ob, mask);
+                       }
+               }
+               else {
+                       if (use_cage) {
+                               dm = mesh_get_derived_deform(scene, ob, mask);  /* ob->derivedDeform */
+                       }
+                       else {
+                               dm = mesh_get_derived_final(scene, ob, mask);  /* ob->derivedFinal */
+                       }
+               }
+       }
+       else {
+               /* !use_deform */
+               if (use_render) {
+                       if (use_cage) {
+                               PyErr_SetString(PyExc_ValueError,
+                                               "from_object(...): cage arg is unsupported when (render=True)");
+                               return NULL;
+                       }
+                       else {
+                               dm = mesh_create_derived_no_deform_render(scene, ob, NULL, mask);
+                       }
+               }
+               else {
+                       if (use_cage) {
+                               PyErr_SetString(PyExc_ValueError,
+                                               "from_object(...): cage arg is unsupported when (deform=False, render=False)");
+                               return NULL;
+                       }
+                       else {
+                               dm = mesh_create_derived_no_deform(scene, ob, NULL, mask);
+                       }
+               }
+       }
 
        if (dm == NULL) {
                PyErr_Format(PyExc_ValueError,
@@ -840,6 +898,8 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
 
        DM_to_bmesh_ex(dm, bm);
 
+       dm->release(dm);
+
        Py_RETURN_NONE;
 }