[Bf-blender-cvs] [d586e5557be] soc-2017-normal-tools: Changed set_normals_from_faces to respect sharp edges.
Rohan Rathi
noreply at git.blender.org
Wed Jul 26 11:15:33 CEST 2017
Commit: d586e5557be5a66d19c4934c184a706f6ce894c5
Author: Rohan Rathi
Date: Wed Jul 26 14:45:15 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rBd586e5557be5a66d19c4934c184a706f6ce894c5
Changed set_normals_from_faces to respect sharp edges.
===================================================================
M release/scripts/startup/bl_operators/mesh.py
M source/blender/editors/mesh/editmesh_tools.c
M source/blender/editors/mesh/mesh_intern.h
M source/blender/editors/mesh/mesh_ops.c
M source/blender/makesdna/DNA_modifier_types.h
===================================================================
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index 4edefd7bf9b..95e1fa0a1f2 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -203,57 +203,7 @@ class MeshSelectPrev(Operator):
return {'FINISHED'}
-# XXX This is hackish (going forth and back from Object mode...), to be redone once we have proper support of
-# custom normals in BMesh/edit mode.
-class MehsSetNormalsFromFaces(Operator):
- """Set the custom vertex normals from the selected faces ones"""
- bl_idname = "mesh.set_normals_from_faces"
- bl_label = "Set Normals From Faces"
- bl_options = {'REGISTER', 'UNDO'}
-
- @classmethod
- def poll(cls, context):
- return (context.mode == 'EDIT_MESH' and context.edit_object.data.polygons)
-
- def execute(self, context):
- import mathutils
-
- bpy.ops.object.mode_set(mode='OBJECT')
- obj = context.active_object
- me = obj.data
-
- v2nors = {}
- for p in me.polygons:
- if not p.select:
- continue
- for lidx, vidx in zip(p.loop_indices, p.vertices):
- assert(me.loops[lidx].vertex_index == vidx)
- v2nors.setdefault(vidx, []).append(p.normal)
-
- for nors in v2nors.values():
- nors[:] = [sum(nors, mathutils.Vector((0, 0, 0))).normalized()]
-
- if not me.has_custom_normals:
- me.create_normals_split()
- me.calc_normals_split()
-
- normals = []
- for l in me.loops:
- nor = v2nors.get(l.vertex_index, [None])[0]
- if nor is None:
- nor = l.normal
- normals.append(nor.to_tuple())
-
- me.normals_split_custom_set(normals)
-
- me.free_normals_split()
- bpy.ops.object.mode_set(mode='EDIT')
-
- return {'FINISHED'}
-
-
classes = (
- MehsSetNormalsFromFaces,
MeshMirrorUV,
MeshSelectNext,
MeshSelectPrev,
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index a9accacfcea..fc84c4f472f 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -41,6 +41,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "BLI_bitmap.h"
#include "BLI_listbase.h"
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
@@ -6669,7 +6670,7 @@ static int edbm_copy_paste_normal_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_copy_paste_normal_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_copy_paste_normal_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return edbm_copy_paste_normal_exec(C, op);
}
@@ -6697,4 +6698,85 @@ void MESH_OT_copy_normal(struct wmOperatorType *ot)
prop = RNA_def_property(ot->srna, "normal_vector", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Copied Normal", "Normal vector of copied face or loop");
+}
+
+static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMFace *f;
+ BMVert *v;
+ BMEdge *e;
+ BMLoop *l;
+ BMIter fiter, viter, eiter, liter;
+ int index;
+
+ const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp");
+ BLI_bitmap *faces_sharp = BLI_BITMAP_NEW(bm->totface, __func__);
+
+ BM_lnorspace_update(bm);
+ BM_mesh_elem_index_ensure(bm, BM_ALL);
+
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ bool all_edge_mark = true;
+ BM_ITER_ELEM(e, &eiter, f, BM_EDGES_OF_FACE) {
+ if (BM_elem_flag_test(e, BM_ELEM_SMOOTH))
+ all_edge_mark = false;
+ }
+ if (all_edge_mark) {
+ BLI_BITMAP_ENABLE(faces_sharp, BM_elem_index_get(f));
+ }
+ }
+
+ float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, "__func__");
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM(v, &viter, f, BM_VERTS_OF_FACE) {
+ int v_index = BM_elem_index_get(v);
+ add_v3_v3(vnors[v_index], f->no);
+ }
+ }
+ }
+ for (int i = 0; i < bm->totvert; i++) {
+ if (!is_zero_v3(vnors[i]))
+ normalize_v3(vnors[i]);
+ }
+
+ int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_ITER_MESH_INDEX(v, &viter, bm, BM_VERTS_OF_MESH, index) {
+ BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (keep_sharp && BLI_BITMAP_TEST(faces_sharp, BM_elem_index_get(l->f)))
+ continue;
+
+ if (!is_zero_v3(vnors[index])) {
+ short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ int l_index = BM_elem_index_get(l);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], vnors[index], clnors);
+ }
+ }
+ }
+ MEM_freeN(faces_sharp);
+ MEM_freeN(vnors);
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Set Normals from faces";
+ ot->description = "Set the custom vertex normals from the selected faces ones";
+ ot->idname = "MESH_OT_set_normals_from_faces";
+
+ /* api callbacks */
+ ot->exec = edbm_set_normals_from_faces_exec;
+ ot->poll = ED_operator_editmesh_auto_smooth;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_boolean(ot->srna, "keep_sharp", 0, "Keep Sharp Edges", "Do not set sharp edges to face");
}
\ No newline at end of file
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 3252c0cf730..d9087d62019 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -233,6 +233,7 @@ void MESH_OT_point_normals(struct wmOperatorType *ot);
void MESH_OT_merge_loop_normals(struct wmOperatorType *ot);
void MESH_OT_split_loop_normals(struct wmOperatorType *ot);
void MESH_OT_copy_normal(struct wmOperatorType *ot);
+void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot);
#ifdef WITH_FREESTYLE
void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 211e778e79d..9817d1a7dfe 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -196,6 +196,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_merge_loop_normals);
WM_operatortype_append(MESH_OT_split_loop_normals);
WM_operatortype_append(MESH_OT_copy_normal);
+ WM_operatortype_append(MESH_OT_set_normals_from_faces);
#ifdef WITH_GAMEENGINE
WM_operatortype_append(MESH_OT_navmesh_make);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 1699ef39270..47950ced88d 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1616,8 +1616,7 @@ enum {
typedef struct WeightedNormalModifierData {
ModifierData modifier;
- short weight;
- short mode;
+ short weight, mode;
float thresh;
} WeightedNormalModifierData;
More information about the Bf-blender-cvs
mailing list