py api: BMesh.from_object() was using the derivedFinal, which isn't always available - or may not have UV data if in the wireframe view.
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.
This commit is contained in:
@@ -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 */
|
/* 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)));
|
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);
|
clear_mesh_caches(ob);
|
||||||
|
|
||||||
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
|
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
|
||||||
|
@@ -801,34 +801,92 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
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,
|
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"
|
"\n"
|
||||||
" Initialize this bmesh from existing object datablock.\n"
|
" Initialize this bmesh from existing object datablock (currently only meshes are supported).\n"
|
||||||
"\n"
|
"\n"
|
||||||
" :arg object: The object data to load.\n"
|
" :arg object: The object data to load.\n"
|
||||||
" :type object: :class:`Object`\n"
|
" :type object: :class:`Object`\n"
|
||||||
" :arg apply_modifiers: Use the final display mesh rather then the deformed cage.\n"
|
" :arg deform: Apply deformation modifiers.\n"
|
||||||
" :type apply_modifiers: boolean\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)
|
static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *py_object;
|
PyObject *py_object;
|
||||||
|
PyObject *py_scene;
|
||||||
Object *ob;
|
Object *ob;
|
||||||
|
struct Scene *scene;
|
||||||
BMesh *bm;
|
BMesh *bm;
|
||||||
int apply_modifiers = TRUE;
|
int use_deform = TRUE;
|
||||||
|
int use_render = FALSE;
|
||||||
|
int use_cage = FALSE;
|
||||||
DerivedMesh *dm;
|
DerivedMesh *dm;
|
||||||
|
const int mask = CD_MASK_BMESH;
|
||||||
|
|
||||||
BPY_BM_CHECK_OBJ(self);
|
BPY_BM_CHECK_OBJ(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|i:from_object", &py_object, &apply_modifiers) ||
|
if (!PyArg_ParseTuple(args, "OO|iii:from_object", &py_object, &py_scene, &use_render, &use_cage) ||
|
||||||
!(ob = PyC_RNA_AsPointer(py_object, "Object")))
|
!(ob = PyC_RNA_AsPointer(py_object, "Object")) ||
|
||||||
|
!(scene = PyC_RNA_AsPointer(py_scene, "Scene")))
|
||||||
{
|
{
|
||||||
return NULL;
|
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) {
|
if (dm == NULL) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
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_to_bmesh_ex(dm, bm);
|
||||||
|
|
||||||
|
dm->release(dm);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user