Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2013-09-10 19:26:12 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2013-09-10 19:26:12 +0400
commit135f6a72d42d704468dd29c470390df52b905d1b (patch)
tree99c70d8191e1f22beeb87d3df3a7291af50a138b /source/blender/makesrna
parent44c7a87ada3ae260f14bbd25a26bd89341f1543f (diff)
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.
Diffstat (limited to 'source/blender/makesrna')
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c24
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c55
2 files changed, 77 insertions, 2 deletions
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index ead702a56a6..2820a7a3aa9 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -320,6 +320,20 @@ static void rna_MEdge_crease_set(PointerRNA *ptr, float value)
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 @@ static void rna_def_mloop(BlenderRNA *brna)
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)
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 7fec4a1ff9c..e1a0a2b428b 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -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,8 +58,48 @@ static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, bContext *C, st
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(
@@ -83,6 +124,16 @@ void RNA_api_mesh(StructRNA *srna)
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)");