[Bf-blender-cvs] [6a06b247d85] soc-2017-normal-tools: Added Average and weighting modes to merge.
Rohan Rathi
noreply at git.blender.org
Fri Jul 28 16:24:28 CEST 2017
Commit: 6a06b247d85145b6bbd8aadd99d80549064410e7
Author: Rohan Rathi
Date: Fri Jul 28 19:54:06 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rB6a06b247d85145b6bbd8aadd99d80549064410e7
Added Average and weighting modes to merge.
===================================================================
M release/scripts/startup/bl_ui/space_view3d_toolbar.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/makesrna/intern/rna_modifier.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index be083302f65..33a1ff8c058 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -454,6 +454,11 @@ class VIEW3D_PT_tools_normal(View3DPanel, Panel):
col.operator_menu_enum("mesh.split_loop_normals", "split_type")
col = layout.column(align=True)
+ col.label(text="Average by: ")
+
+ col.operator_menu_enum("mesh.average_loop_normals", "average_type")
+
+ col = layout.column(align=True)
col.label(text="Copy/Paste Loop")
row = col.row(align=True)
row.operator("mesh.copy_normal", text="Copy").copy = True
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index fc84c4f472f..f34c8b495fc 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -6368,12 +6368,16 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
enum {
MERGE_LOOP_AVERAGE = 1,
- SPLIT_LOOP_TO_FACE = 2,
- SPLIT_LOOP_KEEP = 3
+ MERGE_LOOP_FACE_AREA = 2,
+ MERGE_LOOP_CORNER_ANGLE = 3,
+ SPLIT_LOOP_TO_FACE = 4,
+ SPLIT_LOOP_KEEP = 5,
};
static EnumPropertyItem merge_loop_method_items[] = {
{ MERGE_LOOP_AVERAGE, "Average", 0, "Average", "Take Average of Loop Normals" },
+ { MERGE_LOOP_FACE_AREA, "Face Area", 0, "Face Area", "Merge Loops by Face Area"},
+ { MERGE_LOOP_CORNER_ANGLE, "Corner Angle", 0, "Corner Angle", "Merge Loops by Angle of Loop" },
{ 0, NULL, 0, NULL, NULL }
};
@@ -6383,15 +6387,28 @@ static EnumPropertyItem split_loop_method_items[] = {
{ 0, NULL, 0, NULL, NULL }
};
-static bool merge_loop_average(bContext *C, wmOperator *op, LoopNormalData *ld)
+static bool merge_loop(bContext *C, wmOperator *op, LoopNormalData *ld)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
+ BMFace *f;
+ BMLoop *l;
+ BMIter fiter, liter;
+ void **ltable;
TransDataLoopNormal *tld = ld->normal;
+ const int merge_type = RNA_enum_get(op->ptr, "merge_type");
+
BLI_SMALLSTACK_DECLARE(clnors, short *);
+ ltable = MEM_mallocN(sizeof(void *) * bm->totloop, "__func__"); /* temp loop index table */
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
+ ltable[BM_elem_index_get(l)] = l;
+ }
+ }
+
for (int i = 0; i < ld->totloop; i++, tld++) {
if (tld->loop_index == -1)
continue;
@@ -6410,7 +6427,23 @@ static bool merge_loop_average(bContext *C, wmOperator *op, LoopNormalData *ld)
TransDataLoopNormal *temp = ld->normal;
for (int j = 0; j < ld->totloop; j++, temp++) {
if (loop_index == temp->loop_index) {
- add_v3_v3(avg_normal, temp->nloc);
+ if (merge_type == MERGE_LOOP_AVERAGE) {
+ add_v3_v3(avg_normal, temp->nloc);
+ }
+ else {
+ BMLoop *l = ltable[loop_index];
+ float val;
+ if (merge_type == MERGE_LOOP_FACE_AREA) {
+ val = BM_face_calc_area(l->f);
+ }
+ else if (merge_type == MERGE_LOOP_CORNER_ANGLE) {
+ val = BM_loop_calc_face_angle(l);
+ }
+ float f_nor[3];
+ copy_v3_v3(f_nor, l->f->no);
+ mul_v3_fl(f_nor, val);
+ add_v3_v3(avg_normal, f_nor);
+ }
BLI_SMALLSTACK_PUSH(clnors, temp->clnors_data);
temp->loop_index = -1;
}
@@ -6430,6 +6463,8 @@ static bool merge_loop_average(bContext *C, wmOperator *op, LoopNormalData *ld)
}
}
}
+ MEM_freeN(ltable);
+
return true;
}
@@ -6499,15 +6534,7 @@ static int edbm_split_merge_loop_normals_exec(bContext *C, wmOperator *op)
bool handled = false;
if (merge) {
- switch (type) {
- case MERGE_LOOP_AVERAGE:
- handled = merge_loop_average(C, op, ld);
- break;
-
- default:
- BLI_assert(0);
- break;
- }
+ handled = merge_loop(C, op, ld);
}
else {
switch (type) {
@@ -6569,40 +6596,98 @@ void MESH_OT_split_loop_normals(struct wmOperatorType *ot)
}
/********************** Average Loop Normals **********************/
-/*
+
enum {
LOOP_AVERAGE = 1,
- FACE_AVERAGE = 2,
- AREA_AVERAGE = 3,
+ FACE_AREA_AVERAGE = 2,
+ ANGLE_AVERAGE = 3,
};
static EnumPropertyItem average_method_items[] = {
- { LOOP_AVERAGE, "Loop Average", 0, "Loop Average", "Take Average of Loop Normals" },
- { FACE_AVERAGE, "Face Average", 0, "Face Average", "Take Average of Face Normals"},
+ { LOOP_AVERAGE, "Loop", 0, "Loop", "Take Average of vert Normals" },
+ { FACE_AREA_AVERAGE, "Face Area", 0, "Face Area", "Set all vert normals by Face Area"},
+ { ANGLE_AVERAGE, "Corner Angle", 0, "Corner Angle", "Set all vert normals by Corner Angle" },
{ 0, NULL, 0, NULL, NULL }
};
static int edbm_average_loop_normals_exec(bContext *C, wmOperator *op)
{
- return OPERATOR_CANCELLED;
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMVert *v;
+ BMLoop *l;
+ BMIter viter, liter;
+ int index;
+
+ BM_lnorspace_update(bm);
+ LoopNormalData *ld = BM_loop_normal_init(bm);
+
+ const int average_type = RNA_enum_get(op->ptr, "average_type");
+ int cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, "__func__");
+
+ BM_ITER_MESH_INDEX(v, &viter, bm, BM_VERTS_OF_MESH, index) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+
+ float custom_normal[3];
+ int l_index = BM_elem_index_get(l);
+ short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], clnors_data, custom_normal);
+
+ if (average_type == FACE_AREA_AVERAGE) {
+ copy_v3_v3(custom_normal, l->f->no);
+ float face_area = BM_face_calc_area(l->f);
+ mul_v3_fl(custom_normal, face_area);
+ }
+ else if (average_type == ANGLE_AVERAGE)
+ copy_v3_v3(custom_normal, l->f->no); {
+ float face_angle = BM_loop_calc_face_angle(l);
+ mul_v3_fl(custom_normal, face_angle);
+ }
+ add_v3_v3(vnors[index], custom_normal);
+ }
+ }
+ }
+
+ for (int i = 0; i < bm->totvert; i++) {
+ if (!is_zero_v3(vnors[i]))
+ normalize_v3(vnors[i]);
+ }
+
+ BM_ITER_MESH_INDEX(v, &viter, bm, BM_VERTS_OF_MESH, index) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
+ int l_index = BM_elem_index_get(l);
+ short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset);
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[l_index], vnors[index], clnors_data);
+ }
+ }
+ }
+
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
}
void MESH_OT_average_loop_normals(struct wmOperatorType *ot)
{
- /* identifiers *
- ot->name = "Average Loop normals";
+ /* identifiers */
+ ot->name = "Average";
ot->description = "Average loop normals of selected vertices";
- ot->idname = "MESH_ot_average_loop_normals";
+ ot->idname = "MESH_OT_average_loop_normals";
- /* api callbacks *
+ /* api callbacks */
ot->exec = edbm_average_loop_normals_exec;
ot->poll = ED_operator_editmesh_auto_smooth;
- /* flags *
+ /* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- ot->prop = RNA_def_enum(ot->srna, "type", average_method_items, LOOP_AVERAGE, "Type", "Averaging method");
-}*/
+ ot->prop = RNA_def_enum(ot->srna, "average_type", average_method_items, LOOP_AVERAGE, "Type", "Averaging method");
+}
/********************** Copy/Paste Loop Normals **********************/
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index d9087d62019..0552cc3df81 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -234,6 +234,7 @@ 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);
+void MESH_OT_average_loop_normals(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 9817d1a7dfe..6143f952f97 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -197,6 +197,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_split_loop_normals);
WM_operatortype_append(MESH_OT_copy_normal);
WM_operatortype_append(MESH_OT_set_normals_from_faces);
+ WM_operatortype_append(MESH_OT_average_loop_normals);
#ifdef WITH_GAMEENGINE
WM_operatortype_append(MESH_OT_navmesh_make);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1cd9b304019..81121bc88b0 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4774,8 +4774,8 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_MOD_NORMALEDIT);
prop = RNA_def_property(srna, "weight", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 2, 15);
- RNA_def_property_ui_range(prop, 2, 15, 1, -1);
+ RNA_def_property_range(prop, 0, 20);
+ RNA_def_property_ui_range(prop, 0, 20, 1, -1);
RNA_def_property_ui_text(prop, "Weight", "Weights given to Face Normal for each mode");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
More information about the Bf-blender-cvs
mailing list