[Bf-blender-cvs] [21595fc] temp_custom_loop_normals: SetSplitNormals modifier: add a new 'from split normals' mode.

Bastien Montagne noreply at git.blender.org
Fri Aug 22 12:48:06 CEST 2014


Commit: 21595fc2f571c1840ab6f037f1daa535efb4fb91
Author: Bastien Montagne
Date:   Fri Aug 22 12:22:07 2014 +0200
Branches: temp_custom_loop_normals
https://developer.blender.org/rB21595fc2f571c1840ab6f037f1daa535efb4fb91

SetSplitNormals modifier: add a new 'from split normals' mode.

This adds the ability to set our split normals from target's split normals.
We first find closest vert, then select 'best' lnor by matching polys' normals.

Note that if target has stray vertices, modified lnors closest to those non-loop
target vertices will just get auto-normals. Not sure we want to add further
loops to find closest 'loop-compatible' vert?

Also, fixed a nasty dummy crash when swithing target to Edit mode!

===================================================================

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenkernel/intern/mesh_evaluate.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_setsplitnormal.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 7a3daef..cda5eaa 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1228,6 +1228,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
     def SET_SPLIT_NORMAL(self, layout, ob, md):
         has_vgroup = bool(md.vertex_group)
         needs_object_bbox_center = (md.mode == 'ELLIPSOID') and not md.target
+        needs_use_current_clnors = (md.mode == 'SPLIT_NORMALS')
 
         row = layout.row()
         row.prop(md, "mode", expand=True)
@@ -1246,6 +1247,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         sub = row.row(align=True)
         sub.active = has_vgroup
         sub.prop(md, "use_invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
+        sub = col.row()
+        sub.active = needs_use_current_clnors
+        sub.prop(md, "use_current_custom_split_normals")
 
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 9771a5b..875127b 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -59,10 +59,10 @@
 
 #include "mikktspace.h"
 
-#define DEBUG_TIME
+//#define DEBUG_TIME
 
+#include "PIL_time.h"
 #ifdef DEBUG_TIME
-#  include "PIL_time.h"
 #  include "PIL_time_utildefines.h"
 #endif
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 1840e12..cc9600f 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1381,12 +1381,14 @@ typedef struct SetSplitNormalModifierData {
 enum {
 	MOD_SETSPLITNORMAL_MODE_ELLIPSOID    = 0,
 	MOD_SETSPLITNORMAL_MODE_GEOM_FACENOR = 1,
+	MOD_SETSPLITNORMAL_MODE_GEOM_LOOPNOR = 2,
 };
 
 /* SetSplitNormalModifierData.flags */
 enum {
 	MOD_SETSPLITNORMAL_INVERT_VGROUP = (1 << 0),
 	MOD_SETSPLITNORMAL_CENTER_BBOX   = (1 << 1),
+	MOD_SETSPLITNORMAL_USE_CURCLNORS = (1 << 2),
 };
 
 
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index c28c426..c14de99 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -3676,8 +3676,9 @@ static void rna_def_modifier_setsplitnormal(BlenderRNA *brna)
 
 	static EnumPropertyItem prop_mode_items[] = {
 		{MOD_SETSPLITNORMAL_MODE_ELLIPSOID, "ELLIPSOID", 0, "Ellipsoid",
-		        "From an ellipsoid (shape defined by the boundbox's dimensions - target is optional)"},
+		        "From an ellipsoid (shape defined by the boundbox's dimensions, target is optional)"},
 		{MOD_SETSPLITNORMAL_MODE_GEOM_FACENOR, "FACE_NORMALS", 0, "Face Normals", "From a mesh's face normals"},
+		{MOD_SETSPLITNORMAL_MODE_GEOM_LOOPNOR, "SPLIT_NORMALS", 0, "Split Normals", "From a mesh's split normals"},
 		{0, NULL, 0, NULL, NULL}
 	};
 
@@ -3711,7 +3712,15 @@ static void rna_def_modifier_setsplitnormal(BlenderRNA *brna)
 	prop = RNA_def_property(srna, "use_bbox_center", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SETSPLITNORMAL_CENTER_BBOX);
 	RNA_def_property_ui_text(prop, "BoundingBox Center",
-	                         "Center ellipsoid on bounding box center instead of own object center");
+	                         "Center ellipsoid on bounding box center instead of own object center "
+	                         "(Ellipsoid mode only)");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "use_current_custom_split_normals", PROP_BOOLEAN, PROP_NONE);
+	RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SETSPLITNORMAL_USE_CURCLNORS);
+	RNA_def_property_ui_text(prop, "Use Custom Split Normals",
+	                         "Use current custom split normals as basis, instead of auto-computed ones, if available "
+	                         "(Split Normals mode only)");
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
diff --git a/source/blender/modifiers/intern/MOD_setsplitnormal.c b/source/blender/modifiers/intern/MOD_setsplitnormal.c
index eef41e7..8b03131 100644
--- a/source/blender/modifiers/intern/MOD_setsplitnormal.c
+++ b/source/blender/modifiers/intern/MOD_setsplitnormal.c
@@ -35,6 +35,7 @@
 
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
+#include "BLI_linklist.h"
 #include "BLI_string.h"
 
 #include "BKE_cdderivedmesh.h"
@@ -55,7 +56,7 @@ static bool is_valid_target(SetSplitNormalModifierData *smd)
 	if (smd->mode == MOD_SETSPLITNORMAL_MODE_ELLIPSOID) {
 		return true;
 	}
-	else if (smd->mode == MOD_SETSPLITNORMAL_MODE_GEOM_FACENOR &&
+	else if (ELEM(smd->mode, MOD_SETSPLITNORMAL_MODE_GEOM_FACENOR, MOD_SETSPLITNORMAL_MODE_GEOM_LOOPNOR) &&
 	         smd->target && smd->target->type == OB_MESH)
 	{
 		return true;
@@ -125,6 +126,44 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UN
 	}
 }
 
+static bool ensure_target_dm(Object *target_ob, DerivedMesh **r_target_dm)
+{
+	*r_target_dm = target_ob->derivedFinal;
+	if (!*r_target_dm) {
+#if 0
+		if (ELEM(target_ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+			*r_target_dm = CDDM_from_curve(target_ob);
+			return true;
+		}
+		else if (target_ob->type == OB_MESH) {
+#else
+		if (target_ob->type == OB_MESH) {
+#endif
+			Mesh *me = (Mesh *)target_ob->data;
+			if (me->edit_btmesh) {
+				*r_target_dm = CDDM_from_editbmesh(me->edit_btmesh, false, false);
+				return true;
+			}
+			else {
+				*r_target_dm = CDDM_from_mesh(me);
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+static float get_weight(MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, const int vidx)
+{
+	if (!dvert || defgrp_index == -1) {
+		return 1.0f;
+	}
+	else {
+		const float weight = defvert_find_weight(&dvert[vidx], defgrp_index);
+		return use_invert_vgroup ? 1.0f - weight : weight;
+	}
+}
+
 static void generate_vert_coordinates(DerivedMesh *dm, Object *ob, Object *ob_center, const bool use_bbox_center,
                                       const int num_verts, float (*r_cos)[3], float r_size[3])
 {
@@ -206,10 +245,6 @@ static void generate_vert_coordinates(DerivedMesh *dm, Object *ob, Object *ob_ce
 	}
 }
 
-static float vertex_weight(MDeformVert *dvert, const int index, const int defgrp_index) {
-	return (!dvert || defgrp_index == -1) ? 1.0f :  defvert_find_weight(&dvert[index], defgrp_index);
-}
-
 static void setSplitNormalModifier_do_ellipsoid(
         SetSplitNormalModifierData *smd, Object *ob, DerivedMesh *dm,
         short (*clnors)[2], float (*polynors)[3],
@@ -257,9 +292,8 @@ static void setSplitNormalModifier_do_ellipsoid(
 		/* We reuse cos to now store the ellipsoid-normal of the verts! */
 		while (i--) {
 			float *co = cos[i];
-			const float weight = vertex_weight(dvert, i, defgrp_index);
-			facs[i] = use_invert_vgroup ? 1.0f - weight : weight;
 
+			facs[i] = get_weight(dvert, defgrp_index, use_invert_vgroup, i);
 			if (facs[i]) {
 				const float x2 = co[0] * co[0];
 				const float y2 = co[1] * co[1];
@@ -293,7 +327,8 @@ static void setSplitNormalModifier_do_facenormal(
         MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
 {
 	Object *target_ob = smd->target;
-	DerivedMesh *target_dm = target_ob->derivedFinal;
+	DerivedMesh *target_dm;
+	const bool free_target_dm = ensure_target_dm(target_ob, &target_dm);
 	BVHTreeFromMesh treeData = {0};
 
 	float (*cos)[3] = MEM_mallocN(sizeof(*cos) * num_verts, __func__);
@@ -330,7 +365,7 @@ static void setSplitNormalModifier_do_facenormal(
 		nearest.index = -1;
 		dm->getVertCos(dm, cos);
 
-		/* Find the nearest vert/edge/face. */
+		/* Find the nearest face. */
 #ifndef __APPLE__
 #pragma omp parallel for default(none) private(i) firstprivate(nearest) \
                          shared(treeData, cos, facs, target_polynors, loc2trgt, dvert) \
@@ -338,8 +373,8 @@ static void setSplitNormalModifier_do_facenormal(
 #endif
 		for (i = 0; i < num_verts; i++) {
 			float tmp_co[3];
-			const float weight = vertex_weight(dvert, i, defgrp_index);
-			facs[i] = use_invert_vgroup ? 1.0f - weight : weight;
+
+			facs[i] = get_weight(dvert, defgrp_index, use_invert_vgroup, i);
 
 			/* Convert the vertex to tree coordinates. */
 			copy_v3_v3(tmp_co, cos[i]);
@@ -377,6 +412,191 @@ static void setSplitNormalModifier_do_facenormal(
 
 	MEM_freeN(cos);
 	MEM_freeN(facs);
+	if (target_dm && free_target_dm) {
+		target_dm->release(target_dm);
+	}
+}
+
+static void setSplitNormalModifier_do_loopnormal(
+        SetSplitNormalModifierData *smd, Object *ob, DerivedMesh *dm,
+        short (*clnors)[2], float (*polynors)[3],
+        MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup,
+        MVert *mvert, const int num_verts, MEdge *medge, const int num_edges,
+        MLoop *mloop, const int num_loops, MPoly *mpoly, const int num_polys)
+{
+	Object *target_ob = smd->target;
+	DerivedMesh *target_dm;
+	const bool free_target_dm = ensure_target_dm(target_ob, &target_dm);
+	BVHTreeFromMesh treeData = {0};
+
+	const bool use_current_clnors = ((smd->flags & MOD_SETSPLITNORMAL_USE_CURCLNORS) != 0);
+
+	float (*cos)[3] = MEM_mallocN(sizeof(*cos) * num_verts, __func__);
+	float (*nos)[3] = MEM_callocN(sizeof(*nos) * num_loops, __func__);
+	float *facs = MEM_mallocN(sizeof(*facs) * num_loops, __func__);
+	float *vfacs = MEM_mallocN(sizeof(*facs) * num_verts, __func__);
+
+	/* Create a bvh-tree of the given target's vertices. */
+	bvhtree_from_mesh_verts(&treeData, target_dm, 0.0, 2, 6);
+	if (treeData.tree != NULL) {
+		BVHTreeNearest nearest = {0};
+		int *loop_to_poly = MEM_mallocN(sizeof(int) * (size_t)num_loops, __func__);
+
+		const int target_num_verts = target_dm->getNumVerts(target_dm);
+		const int target_num_edges = target_dm->getNumEdges(target_dm);
+		const int target_num_polys = target_dm->getNumPolys(target_dm);
+		const int target_num_loops = target_dm->getNumLoops(target_dm);
+		MVert *target_mvert = target_dm->getVertArray(target_dm);
+		MEdge *target_medge = 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list