[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