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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-06-03 03:20:49 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-06-03 03:20:49 +0400
commitdfad9b0c09eed2de2c3bedd64691bf11f637725c (patch)
tree86298761e9883ca7dc83b3b5a24a859bdd07bfce /source
parent99b55ef6eb7d677ead66b4166afe45688147a5b3 (diff)
fix [#35555] Collada: export destroys mesh in some cases
add arguments to calculate normals when converting to bmesh: BM_mesh_bm_from_me, DM_to_bmesh This gives some speedup to undo (which didnt need to re-calculate vertex normals), and array modifier which doesnt need to calculate face normals at all
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h6
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c22
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c7
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h3
-rw-r--r--source/blender/bmesh/operators/bmo_mesh_conv.c2
-rw-r--r--source/blender/collada/collada_utils.cpp5
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c3
-rw-r--r--source/blender/modifiers/intern/MOD_array.c4
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c2
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c6
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c3
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c20
16 files changed, 54 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 668eac5e8bc..bd2a9423649 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -474,11 +474,11 @@ int DM_release(DerivedMesh *dm);
void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask);
struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm,
- struct BMEditMesh *existing, int do_tessellate);
+ struct BMEditMesh *existing, const bool do_tessellate);
/* conversion to bmesh only */
-void DM_to_bmesh_ex(struct DerivedMesh *dm, struct BMesh *bm);
-struct BMesh *DM_to_bmesh(struct DerivedMesh *dm);
+void DM_to_bmesh_ex(struct DerivedMesh *dm, struct BMesh *bm, const bool calc_face_normal);
+struct BMesh *DM_to_bmesh(struct DerivedMesh *dm, const bool calc_face_normal);
/** Utility function to convert a DerivedMesh to a shape key block */
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index babaadf2d17..2eb318c316f 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -539,7 +539,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
bm = BM_mesh_create(&bm_mesh_allocsize_default);
- BM_mesh_bm_from_me(bm, me, true, ob->shapenr);
+ BM_mesh_bm_from_me(bm, me, false, true, ob->shapenr);
return bm;
}
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index b5f07176e2b..b7257028316 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -61,7 +61,7 @@ static BMFace *bm_face_create_from_mpoly(MPoly *mp, MLoop *ml,
*
* \note The mesh may already have geometry. see 'is_init'
*/
-void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
+void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm, const bool calc_face_normal)
{
MVert *mv, *mvert;
MEdge *me, *medge;
@@ -182,11 +182,13 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data, true);
- if (face_normals) {
- copy_v3_v3(f->no, face_normals[i]);
- }
- else {
- BM_face_normal_update(f);
+ if (calc_face_normal) {
+ if (face_normals) {
+ copy_v3_v3(f->no, face_normals[i]);
+ }
+ else {
+ BM_face_normal_update(f);
+ }
}
if (UNLIKELY(has_orig_hflag & BM_FACE)) {
@@ -202,7 +204,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
/* converts a cddm to a BMEditMesh. if existing is non-NULL, the
* new geometry will be put in there.*/
-BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, int do_tessellate)
+BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, const bool do_tessellate)
{
BMEditMesh *em = existing;
BMesh *bm;
@@ -214,7 +216,7 @@ BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, int do_tessel
bm = BM_mesh_create(&bm_mesh_allocsize_default);
}
- DM_to_bmesh_ex(dm, bm);
+ DM_to_bmesh_ex(dm, bm, do_tessellate);
if (!em) {
em = BKE_editmesh_create(bm, do_tessellate);
@@ -228,13 +230,13 @@ BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, int do_tessel
return em;
}
-BMesh *DM_to_bmesh(DerivedMesh *dm)
+BMesh *DM_to_bmesh(DerivedMesh *dm, const bool calc_face_normal)
{
BMesh *bm;
bm = BM_mesh_create(&bm_mesh_allocsize_default);
- DM_to_bmesh_ex(dm, bm);
+ DM_to_bmesh_ex(dm, bm, calc_face_normal);
return bm;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 6d1db98f32e..9d330075a3a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -185,7 +185,8 @@ static BMFace *bm_face_create_from_mpoly(MPoly *mp, MLoop *ml,
*
* \warning This function doesn't calculate face normals.
*/
-void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr)
+void BM_mesh_bm_from_me(BMesh *bm, Mesh *me,
+ const bool calc_face_normal, const bool set_key, int act_key_nr)
{
MVert *mvert;
MEdge *medge;
@@ -397,6 +398,10 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr)
/* Copy Custom Data */
CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
+
+ if (calc_face_normal) {
+ BM_face_normal_update(f);
+ }
}
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index 7fe4b8fe58b..754ae8bcad4 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -38,7 +38,8 @@ void BM_mesh_cd_flag_ensure(BMesh *bm, struct Mesh *mesh, const char cd_flag);
void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag);
char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
-void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me, bool set_key, int act_key_nr);
+void BM_mesh_bm_from_me(BMesh *bm, struct Mesh *me,
+ const bool calc_face_normal, const bool set_key, int act_key_nr);
void BM_mesh_bm_to_me(BMesh *bm, struct Mesh *me, bool do_tessface);
#endif /* __BMESH_MESH_CONV_H__ */
diff --git a/source/blender/bmesh/operators/bmo_mesh_conv.c b/source/blender/bmesh/operators/bmo_mesh_conv.c
index a75d0353079..d124aaaf80e 100644
--- a/source/blender/bmesh/operators/bmo_mesh_conv.c
+++ b/source/blender/bmesh/operators/bmo_mesh_conv.c
@@ -45,7 +45,7 @@ void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op)
Mesh *me = BMO_slot_ptr_get(op->slots_in, "mesh");
bool set_key = BMO_slot_bool_get(op->slots_in, "use_shapekey");
- BM_mesh_bm_from_me(bm, me, set_key, ob->shapenr);
+ BM_mesh_bm_from_me(bm, me, false, set_key, ob->shapenr);
if (me->key && ob->shapenr > me->key->totkey) {
ob->shapenr = me->key->totkey - 1;
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 65d6a13dd18..7e9ecb95f7a 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -383,12 +383,13 @@ void bc_match_scale(std::vector<Object *> *objects_done,
}
-void bc_triangulate_mesh(Mesh *me) {
+void bc_triangulate_mesh(Mesh *me)
+{
bool use_beauty = false;
bool tag_only = false;
BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default);
- BM_mesh_bm_from_me(bm, me, FALSE, 0);
+ BM_mesh_bm_from_me(bm, me, true, false, 0);
BM_mesh_triangulate(bm, use_beauty, tag_only, NULL, NULL);
BM_mesh_bm_to_me(bm, me, FALSE);
BM_mesh_free(bm);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 350da905015..8bbb0e8489e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2598,7 +2598,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
bm_old = BM_mesh_create(&bm_mesh_allocsize_default);
- BM_mesh_bm_from_me(bm_old, me, false, 0);
+ BM_mesh_bm_from_me(bm_old, me, false, false, 0);
if (type == 1) retval_iter = mesh_separate_material(bmain, scene, base_iter, bm_old);
else if (type == 2) retval_iter = mesh_separate_loose(bmain, scene, base_iter, bm_old);
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 40fda072180..c2c79d337ea 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -655,10 +655,7 @@ static void undoMesh_to_editbtMesh(void *umv, void *em_v, void *UNUSED(obdata))
bm = BM_mesh_create(&allocsize);
- BM_mesh_bm_from_me(bm, &um->me, false, ob->shapenr);
-
- /* face normals need recalculation since we are not calling through an operator */
- BM_mesh_normals_update(bm);
+ BM_mesh_bm_from_me(bm, &um->me, true, false, ob->shapenr);
em_tmp = BKE_editmesh_create(bm, true);
*em = *em_tmp;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 5647a8562c7..35bc006bb98 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4570,8 +4570,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
/* Create triangles-only BMesh */
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
- BM_mesh_bm_from_me(ss->bm, me, TRUE, ob->shapenr);
- BM_mesh_normals_update(ss->bm);
+ BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr);
sculpt_dynamic_topology_triangulate(ss->bm);
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
BM_mesh_normals_update(ss->bm);
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 36461851162..e09fa18ffc5 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -228,7 +228,7 @@ static void bm_merge_dm_transform(BMesh *bm, DerivedMesh *dm, float mat[4][4],
/* Add the DerivedMesh's elements to the BMesh. The pre-existing
* elements were already tagged, so the new elements can be
* identified by not having the BM_ELEM_TAG flag set. */
- DM_to_bmesh_ex(dm, bm);
+ DM_to_bmesh_ex(dm, bm, false);
if (amd->flags & MOD_ARR_MERGE) {
/* if merging is enabled, find doubles */
@@ -330,7 +330,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
int UNUSED(initFlags))
{
DerivedMesh *result;
- BMesh *bm = DM_to_bmesh(dm);
+ BMesh *bm = DM_to_bmesh(dm, false);
BMOperator first_dupe_op, dupe_op, old_dupe_op, weld_op;
BMVert **first_geom = NULL;
int i, j;
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index cbb0e05aa4a..3713cb817f5 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -113,7 +113,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
const bool vertex_only = (bmd->flags & BME_BEVEL_VERT) != 0;
const bool do_clamp = !(bmd->flags & BME_BEVEL_OVERLAP_OK);
- bm = DM_to_bmesh(dm);
+ bm = DM_to_bmesh(dm, true);
if (vertex_only) {
if ((bmd->lim_flags & BME_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index b8dccd9ffbe..aacf622c185 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -97,6 +97,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DecimateModifierData *dmd = (DecimateModifierData *) md;
DerivedMesh *dm = derivedData, *result = NULL;
BMesh *bm;
+ bool calc_face_normal;
float *vweights = NULL;
@@ -112,16 +113,19 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (dmd->percent == 1.0f) {
return dm;
}
+ calc_face_normal = true;
break;
case MOD_DECIM_MODE_UNSUBDIV:
if (dmd->iter == 0) {
return dm;
}
+ calc_face_normal = false;
break;
case MOD_DECIM_MODE_DISSOLVE:
if (dmd->angle == 0.0f) {
return dm;
}
+ calc_face_normal = true;
break;
}
@@ -159,7 +163,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
}
- bm = DM_to_bmesh(dm);
+ bm = DM_to_bmesh(dm, calc_face_normal);
switch (dmd->mode) {
case MOD_DECIM_MODE_COLLAPSE:
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index 0c50d4d3323..d877932b81d 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -56,8 +56,9 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
BMIter iter;
BMEdge *e;
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
+ const bool calc_face_normals = (emd->flags & MOD_EDGESPLIT_FROMANGLE) != 0;
- bm = DM_to_bmesh(dm);
+ bm = DM_to_bmesh(dm, calc_face_normals);
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index fd0bc218bc4..9155aa0044b 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -40,7 +40,7 @@ static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int flag)
int total_edges, i;
MEdge *me;
- bm = DM_to_bmesh(dm);
+ bm = DM_to_bmesh(dm, true);
BM_mesh_triangulate(bm, (flag & MOD_TRIANGULATE_BEAUTY), false, NULL, NULL);
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 23631017256..6ea8d6c68ce 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -917,7 +917,7 @@ static PyObject *bpy_bmesh_to_mesh(BPy_BMesh *self, PyObject *args)
}
PyDoc_STRVAR(bpy_bmesh_from_object_doc,
-".. method:: from_object(object, scene, deform=True, render=False, cage=False)\n"
+".. method:: from_object(object, scene, deform=True, render=False, cage=False, face_normals=True)\n"
"\n"
" Initialize this bmesh from existing object datablock (currently only meshes are supported).\n"
"\n"
@@ -929,6 +929,8 @@ PyDoc_STRVAR(bpy_bmesh_from_object_doc,
" :type render: boolean\n"
" :arg cage: Get the mesh as a deformed cage.\n"
" :type cage: boolean\n"
+" :arg face_normals: Calculate face normals.\n"
+" :type face_normals: boolean\n"
);
static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
{
@@ -940,12 +942,13 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
int use_deform = true;
int use_render = false;
int use_cage = false;
+ int use_fnorm = true;
DerivedMesh *dm;
const int mask = CD_MASK_BMESH;
BPY_BM_CHECK_OBJ(self);
- if (!PyArg_ParseTuple(args, "OO|iii:from_object", &py_object, &py_scene, &use_render, &use_cage) ||
+ if (!PyArg_ParseTuple(args, "OO|iiii:from_object", &py_object, &py_scene, &use_render, &use_cage, &use_fnorm) ||
!(ob = PyC_RNA_AsPointer(py_object, "Object")) ||
!(scene = PyC_RNA_AsPointer(py_scene, "Scene")))
{
@@ -1011,7 +1014,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
bm = self->bm;
- DM_to_bmesh_ex(dm, bm);
+ DM_to_bmesh_ex(dm, bm, use_fnorm);
dm->release(dm);
@@ -1020,7 +1023,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args)
PyDoc_STRVAR(bpy_bmesh_from_mesh_doc,
-".. method:: from_mesh(mesh, use_shape_key=False, shape_key_index=0)\n"
+".. method:: from_mesh(mesh, face_normals=True, use_shape_key=False, shape_key_index=0)\n"
"\n"
" Initialize this bmesh from existing mesh datablock.\n"
"\n"
@@ -1033,15 +1036,16 @@ PyDoc_STRVAR(bpy_bmesh_from_mesh_doc,
);
static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *kw)
{
- static const char *kwlist[] = {"mesh", "use_shape_key", "shape_key_index", NULL};
+ static const char *kwlist[] = {"mesh", "face_normals", "use_shape_key", "shape_key_index", NULL};
BMesh *bm;
PyObject *py_mesh;
Mesh *me;
+ int use_fnorm = true;
int use_shape_key = false;
int shape_key_index = 0;
- if (!PyArg_ParseTupleAndKeywords(args, kw, "O|ii:from_mesh", (char **)kwlist,
- &py_mesh, &use_shape_key, &shape_key_index) ||
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "O|iii:from_mesh", (char **)kwlist,
+ &py_mesh, &use_fnorm, &use_shape_key, &shape_key_index) ||
!(me = PyC_RNA_AsPointer(py_mesh, "Mesh")))
{
return NULL;
@@ -1049,7 +1053,7 @@ static PyObject *bpy_bmesh_from_mesh(BPy_BMesh *self, PyObject *args, PyObject *
bm = self->bm;
- BM_mesh_bm_from_me(bm, me, use_shape_key, shape_key_index + 1);
+ BM_mesh_bm_from_me(bm, me, use_fnorm, use_shape_key, shape_key_index + 1);
Py_RETURN_NONE;
}