[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60015] trunk/blender/source/blender/ makesrna/intern: Split normals API, to get per-vertex per-face normals, useful to export sharp edges in a compatible way.

Bastien Montagne montagne29 at wanadoo.fr
Tue Sep 10 17:26:13 CEST 2013


Revision: 60015
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60015
Author:   mont29
Date:     2013-09-10 15:26:12 +0000 (Tue, 10 Sep 2013)
Log Message:
-----------
Split normals API, to get per-vertex per-face normals, useful to export sharp edges in a compatible way.

Many thanks to Campbell and Brecht for reviews.

Modified Paths:
--------------
    trunk/blender/source/blender/makesrna/intern/rna_mesh.c
    trunk/blender/source/blender/makesrna/intern/rna_mesh_api.c

Modified: trunk/blender/source/blender/makesrna/intern/rna_mesh.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_mesh.c	2013-09-10 15:24:31 UTC (rev 60014)
+++ trunk/blender/source/blender/makesrna/intern/rna_mesh.c	2013-09-10 15:26:12 UTC (rev 60015)
@@ -320,6 +320,20 @@
 	medge->crease = (char)(CLAMPIS(value * 255.0f, 0, 255));
 }
 
+static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values)
+{
+	Mesh *me = rna_mesh(ptr);
+	MLoop *ml = (MLoop *)ptr->data;
+	const float (*vec)[3] = CustomData_get(&me->ldata, (int)(ml - me->mloop), CD_NORMAL);
+
+	if (!vec) {
+		zero_v3(values);
+	}
+	else {
+		copy_v3_v3(values, (const float *)vec);
+	}
+}
+
 static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values)
 {
 	Mesh *me = rna_mesh(ptr);
@@ -1838,6 +1852,16 @@
 	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 	RNA_def_property_int_funcs(prop, "rna_MeshLoop_index_get", NULL, NULL);
 	RNA_def_property_ui_text(prop, "Index", "Index of this loop");
+
+	prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION);
+	RNA_def_property_array(prop, 3);
+	RNA_def_property_range(prop, -1.0f, 1.0f);
+	RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+	RNA_def_property_float_funcs(prop, "rna_MeshLoop_normal_get", NULL, NULL);
+	RNA_def_property_ui_text(prop, "Loop Normal",
+	                         "Local space unit length split normal vector of this vertex for this polygon "
+	                         "(only computed on demand!)");
+
 }
 
 static void rna_def_mpolygon(BlenderRNA *brna)

Modified: trunk/blender/source/blender/makesrna/intern/rna_mesh_api.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_mesh_api.c	2013-09-10 15:24:31 UTC (rev 60014)
+++ trunk/blender/source/blender/makesrna/intern/rna_mesh_api.c	2013-09-10 15:26:12 UTC (rev 60015)
@@ -37,6 +37,7 @@
 #include "BLI_sys_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_math.h"
 
 #include "BKE_mesh.h"
 #include "ED_mesh.h"
@@ -57,9 +58,49 @@
 	return ret;
 }
 
-void rna_Mesh_calc_smooth_groups(struct Mesh *mesh, int use_bitflags, int *r_poly_group_len,
-                                 int **r_poly_group, int *r_group_total)
+static void rna_Mesh_calc_split_normals(Mesh *mesh, float min_angle)
 {
+	float (*r_loopnors)[3];
+	float (*polynors)[3];
+	bool free_polynors;
+
+	if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
+		r_loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
+		memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop);
+	}
+	else {
+		r_loopnors = CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop);
+		CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+	}
+
+	if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
+		/* This assume that layer is always up to date, not sure this is the case (esp. in Edit mode?)... */
+		polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+	}
+	else {
+		polynors = MEM_mallocN(sizeof(float [3]) * mesh->totpoly, AT);
+		BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
+		                           polynors, false);
+		free_polynors = true;
+	}
+
+	BKE_mesh_normals_loop_split(mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
+	                            mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, polynors, mesh->totpoly,
+	                            min_angle);
+
+	if (free_polynors) {
+		MEM_freeN(polynors);
+	}
+}
+
+static void rna_Mesh_free_split_normals(Mesh *mesh)
+{
+	CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop);
+}
+
+static void rna_Mesh_calc_smooth_groups(Mesh *mesh, int use_bitflags, int *r_poly_group_len,
+                                        int **r_poly_group, int *r_group_total)
+{
 	*r_poly_group_len = mesh->totpoly;
 	*r_poly_group = BKE_mesh_calc_smoothgroups(
 	                    mesh->medge, mesh->totedge,
@@ -83,6 +124,16 @@
 	func = RNA_def_function(srna, "calc_normals", "BKE_mesh_calc_normals");
 	RNA_def_function_ui_description(func, "Calculate vertex normals");
 
+	func = RNA_def_function(srna, "calc_split_normals", "rna_Mesh_calc_split_normals");
+	RNA_def_function_ui_description(func, "Calculate split vertex normals, which preserve sharp edges");
+	parm = RNA_def_float(func, "split_angle", M_PI, 0.0f, M_PI, "",
+	                     "Angle between polys' normals above which an edge is always sharp (180° to disable)",
+	                     0.0f, M_PI);
+	RNA_def_property_subtype(parm, PROP_UNIT_ROTATION);
+
+	func = RNA_def_function(srna, "free_split_normals", "rna_Mesh_free_split_normals");
+	RNA_def_function_ui_description(func, "Free split vertex normals");
+
 	func = RNA_def_function(srna, "calc_tessface", "ED_mesh_calc_tessface");
 	RNA_def_function_ui_description(func, "Calculate face tessellation (supports editmode too)");
 




More information about the Bf-blender-cvs mailing list