[Bf-blender-cvs] [448c61b8610] soc-2017-normal-tools: Added Split/Merge normals.
Rohan Rathi
noreply at git.blender.org
Sat Jul 1 08:36:28 CEST 2017
Commit: 448c61b8610b7ae4d9056411762cc21afafe1667
Author: Rohan Rathi
Date: Sat Jul 1 12:03:08 2017 +0530
Branches: soc-2017-normal-tools
https://developer.blender.org/rB448c61b8610b7ae4d9056411762cc21afafe1667
Added Split/Merge normals.
Doesn't work on the basis of any weighting mode. Will have to implement that first. I'll add more methods as I progress in other areas.
===================================================================
M release/scripts/startup/bl_ui/space_view3d_toolbar.py
M source/blender/bmesh/intern/bmesh_mesh.c
M source/blender/bmesh/intern/bmesh_opdefines.c
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/editors/transform/transform.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 86be68de043..177c558f5c5 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -447,6 +447,12 @@ class VIEW3D_PT_tools_normal(View3DPanel, Panel):
col.operator("transform.rotate_normal", text = "Rotate Normal")
col.operator("mesh.point_normals")
+ col = layout.column(align=True)
+ col.label(text="Split/Merge: ")
+
+ col.operator_menu_enum("mesh.merge_loop_normals", "merge_type")
+ col.operator_menu_enum("mesh.split_loop_normals", "split_type")
+
class VIEW3D_PT_tools_uvs(View3DPanel, Panel):
bl_category = "Shading / UVs"
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 47105ffb601..e2d584a517f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -814,7 +814,12 @@ static void bm_mesh_loops_calc_normals(
if (r_lnors_spacearr) {
/* Assign current lnor space to current 'vertex' loop. */
- BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true);
+
+ /* weak fix, need to look out if breaks something. Without this 'if', wrongly builds the lnor spaces
+ if loops are merged. */
+ if (!rebuild || !BM_elem_flag_test(lfan_pivot->v, BM_ELEM_TAG) || (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL)) {
+ BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, true);
+ }
if (e_next != e_org) {
/* We store here all edges-normalized vectors processed. */
BLI_stack_push(edge_vectors, vec_next);
@@ -853,7 +858,10 @@ static void bm_mesh_loops_calc_normals(
clnors_avg[0] /= clnors_nbr;
clnors_avg[1] /= clnors_nbr;
/* Fix/update all clnors of this fan with computed average value. */
- printf("Invalid clnors in this fan!\n");
+
+ /* Prints continuously when merge custom normals, so commenting -Rohan
+ printf("Invalid clnors in this fan!\n");*/
+
while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
//print_v2("org clnor", clnor);
clnor[0] = (short)clnors_avg[0];
@@ -1073,6 +1081,7 @@ void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
}
}
}
+
BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, r_lnors, bm->lnor_spacearr, NULL, cd_loop_clnors_offset, true);
MEM_freeN(r_lnors);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index c4e0511bf26..1b8879e27ee 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -208,8 +208,7 @@ static BMOpDefine bmo_region_extend_def = {
},
bmo_region_extend_exec,
(BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE |
- BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL),
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 9f439b3f598..de9085effdf 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -42,6 +42,8 @@
#include "DNA_scene_types.h"
#include "BLI_listbase.h"
+#include "BLI_linklist.h"
+#include "BLI_linklist_stack.h"
#include "BLI_noise.h"
#include "BLI_math.h"
#include "BLI_rand.h"
@@ -6442,4 +6444,204 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
prop = RNA_def_property(ot->srna, "selected", PROP_INT, PROP_NONE);
RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+
+/********************** Split/Merge Loop Normals **********************/
+
+enum {
+ MERGE_LOOP_AVERAGE = 1,
+ SPLIT_LOOP_TO_FACE = 2,
+ SPLIT_LOOP_KEEP = 3
+};
+
+static EnumPropertyItem merge_loop_method_items[] = {
+ { MERGE_LOOP_AVERAGE, "Average", 0, "Average", "Take Average of Loop Normals" },
+ { 0, NULL, 0, NULL, NULL }
+};
+
+static EnumPropertyItem split_loop_method_items[] = {
+ { SPLIT_LOOP_TO_FACE, "Set to face", 0, "Set to face", "Set loop normal to respective faces" },
+ { SPLIT_LOOP_KEEP, "Keep Normal", 0, "Keep Normal", "Keep normal value after splitting" },
+ { 0, NULL, 0, NULL, NULL }
+};
+
+static bool merge_loop_average(bContext *C, wmOperator *op, LoopNormalData *ld)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ TransDataLoopNormal *tld = ld->normal;
+
+ for (int i = 0; i < ld->totloop; i++, tld++) {
+ MLoopNorSpace *lnor_space = bm->lnor_spacearr->lspacearr[tld->loop_index];
+
+ if (lnor_space->loops) {
+
+ LinkNode *loops = lnor_space->loops;
+ float avg_normal[3] = { 0, 0, 0 };
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+ short *clnors_data;
+
+ while (loops) {
+ const int loop_index = GET_INT_FROM_POINTER(loops->link);
+
+ 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);
+ BLI_SMALLSTACK_PUSH(clnors, tld->clnors_data);
+ }
+ }
+ loops = loops->next;
+ }
+ if (len_squared_v3(avg_normal) < 1e-4f) { /* if avg normal is nearly 0, set clnor to default value */
+ while ((clnors_data = BLI_SMALLSTACK_POP(clnors))) {
+ copy_v2_v2_short(clnors_data, (short[2]) { 0, 0 });
+ }
+ }
+ else {
+ normalize_v3(avg_normal); /* else set all clnors to this avg */
+ while ((clnors_data = BLI_SMALLSTACK_POP(clnors))) {
+ BKE_lnor_space_custom_normal_to_data(lnor_space, avg_normal, clnors_data);
+ printf("hi");
+ }
+ }
+ }
+ }
+ return true;
+}
+
+static bool split_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;
+
+ TransDataLoopNormal *tld = ld->normal;
+
+ const int type = RNA_enum_get(op->ptr, "split_type");
+
+ for (int i = 0; i < ld->totloop; i++, tld++) {
+ if (type == SPLIT_LOOP_TO_FACE) { /* set loop to face normal if split to faces */
+ BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (tld->loop_index == BM_elem_index_get(l)) {
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[tld->loop_index], f->no, tld->clnors_data);
+ }
+ }
+ }
+ }
+ }
+ else if (type == SPLIT_LOOP_KEEP) { /* else set to transdata normal computed */
+ BKE_lnor_space_custom_normal_to_data(bm->lnor_spacearr->lspacearr[tld->loop_index], tld->nloc, tld->clnors_data);
+ printf("hi");
+ }
+ }
+ return true;
+}
+
+static int edbm_split_merge_loop_normals_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMEdge *e;
+ BMIter eiter;
+
+ if ((((Mesh *)(obedit->data))->flag & ME_AUTOSMOOTH) == 0) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BM_lnorspace_update(bm);
+ LoopNormalData *ld = BM_loop_normal_init(bm);
+
+ const bool merge = RNA_struct_find_property(op->ptr, "merge_type") != NULL;
+ const int type = merge ? RNA_enum_get(op->ptr, "merge_type") : RNA_enum_get(op->ptr, "split_type");
+
+ mesh_set_smooth_faces(em, merge);
+
+ BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_set(e, BM_ELEM_SMOOTH, merge);
+ }
+ }
+
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ BM_lnorspace_update(bm);
+
+ bool handled = false;
+
+ if (merge) {
+ switch (type) {
+ case MERGE_LOOP_AVERAGE:
+ handled = merge_loop_average(C, op, ld);
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+ }
+ else {
+ switch (type) {
+ case SPLIT_LOOP_TO_FACE:
+ handled = split_loop(C, op, ld);
+ break;
+
+ case SPLIT_LOOP_KEEP:
+ handled = split_loop(C, op, ld);
+ break;
+
+ default:
+ BLI_assert(0);
+ break;
+ }
+ }
+ if (!handled) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BKE_reportf(op->reports, RPT_INFO, "Finished");
+ EDBM_update_generic(em, true, false);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_merge_loop_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Merge Loop";
+ ot->description = "Merge loop normals of selected vertices";
+ ot->idname = "MESH_OT_merge_loop_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_split_merge_loop_normals_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "merge_type", merge_loop_method_items, MERGE_LOOP_AVERAGE, "Type", "Merge method");
+}
+
+void MESH_OT_split_loop_normals(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Split Loop";
+ ot->description = "Split loop normals of selected vertices";
+ ot->idname = "MESH_OT_split_loop_normals";
+
+ /* api callbacks */
+ ot->exec = edbm_split_merge_loop_normals_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "split_type", split_loop_method_items, SPLIT_LOOP_TO_FACE, "Type", "Split method");
}
\ 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 5a141f29607..fbad0a5d5f1 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -230,6 +230,8 @@ void MESH_OT_merge(struct wmOperatorType *ot);
void MESH_OT_remove_doubles(struct wmOperatorType *ot);
void MESH_OT_poke(struct wmOperatorType *ot);
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);
#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 6ed2453c86e..66a39b30594 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/sourc
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list