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:
Diffstat (limited to 'source/blender/makesrna/intern/rna_mesh_api.c')
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c127
1 files changed, 117 insertions, 10 deletions
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index cc1f57d8a14..53704e24bff 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -61,10 +61,19 @@ static const char *rna_Mesh_unit_test_compare(struct Mesh *mesh, struct Mesh *me
return ret;
}
-static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
+static void rna_Mesh_create_normals_split(Mesh *mesh)
+{
+ if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
+ CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop);
+ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
+ }
+}
+
+static void rna_Mesh_calc_normals_split(Mesh *mesh)
{
float (*r_loopnors)[3];
float (*polynors)[3];
+ short (*clnors)[2] = NULL;
bool free_polynors = false;
if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
@@ -76,6 +85,9 @@ static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
}
+ /* may be NULL */
+ clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+
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);
@@ -88,9 +100,10 @@ static void rna_Mesh_calc_normals_split(Mesh *mesh, float min_angle)
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);
+ BKE_mesh_normals_loop_split(
+ mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
+ mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly,
+ (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, NULL, clnors, NULL);
if (free_polynors) {
MEM_freeN(polynors);
@@ -117,7 +130,7 @@ static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *
/* Compute loop normals if needed. */
if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
- rna_Mesh_calc_normals_split(mesh, (float)M_PI);
+ rna_Mesh_calc_normals_split(mesh);
}
BKE_mesh_loop_tangents(mesh, uvmap, r_looptangents, reports);
@@ -139,6 +152,78 @@ static void rna_Mesh_calc_smooth_groups(Mesh *mesh, int use_bitflags, int *r_pol
r_group_total, use_bitflags);
}
+static void rna_Mesh_normals_split_custom_do(Mesh *mesh, float (*custom_loopnors)[3], const bool use_vertices)
+{
+ float (*polynors)[3];
+ short (*clnors)[2];
+ const int numloops = mesh->totloop;
+ bool free_polynors = false;
+
+ clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
+ if (clnors) {
+ memset(clnors, 0, sizeof(*clnors) * numloops);
+ }
+ else {
+ clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_DEFAULT, NULL, numloops);
+ }
+
+ if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
+ polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+ }
+ else {
+ polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, __func__);
+ BKE_mesh_calc_normals_poly(mesh->mvert, mesh->totvert, mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
+ polynors, false);
+ free_polynors = true;
+ }
+
+ if (use_vertices) {
+ BKE_mesh_normals_loop_custom_from_vertices_set(
+ mesh->mvert, custom_loopnors, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, mesh->totloop,
+ mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors);
+ }
+ else {
+ BKE_mesh_normals_loop_custom_set(
+ mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, custom_loopnors, mesh->totloop,
+ mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors);
+ }
+
+ if (free_polynors) {
+ MEM_freeN(polynors);
+ }
+}
+
+static void rna_Mesh_normals_split_custom_set(Mesh *mesh, ReportList *reports, int normals_len, float *normals)
+{
+ float (*loopnors)[3] = (float (*)[3])normals;
+ const int numloops = mesh->totloop;
+
+ if (normals_len != numloops * 3) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Number of custom normals is not number of loops (%f / %d)",
+ (float)normals_len / 3.0f, numloops);
+ return;
+ }
+
+ rna_Mesh_normals_split_custom_do(mesh, loopnors, false);
+}
+
+static void rna_Mesh_normals_split_custom_set_from_vertices(
+ Mesh *mesh, ReportList *reports, int normals_len, float *normals)
+{
+ float (*vertnors)[3] = (float (*)[3])normals;
+ const int numverts = mesh->totvert;
+
+ if (normals_len != numverts * 3) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Number of custom normals is not number of vertices (%f / %d)",
+ (float)normals_len / 3.0f, numverts);
+ return;
+ }
+
+ rna_Mesh_normals_split_custom_do(mesh, vertnors, true);
+}
+
static void rna_Mesh_transform(Mesh *mesh, float *mat, int shape_keys)
{
BKE_mesh_transform(mesh, (float (*)[4])mat, shape_keys);
@@ -152,6 +237,7 @@ void RNA_api_mesh(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
+ const int normals_array_dim[] = {1, 3};
func = RNA_def_function(srna, "transform", "rna_Mesh_transform");
RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix");
@@ -162,12 +248,11 @@ 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, "create_normals_split", "rna_Mesh_create_normals_split");
+ RNA_def_function_ui_description(func, "Empty split vertex normals");
+
func = RNA_def_function(srna, "calc_normals_split", "rna_Mesh_calc_normals_split");
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, (PropertySubType)PROP_UNIT_ROTATION);
func = RNA_def_function(srna, "free_normals_split", "rna_Mesh_free_normals_split");
RNA_def_function_ui_description(func, "Free split vertex normals");
@@ -196,6 +281,26 @@ void RNA_api_mesh(StructRNA *srna)
parm = RNA_def_int(func, "groups", 0, 0, INT_MAX, "groups", "Total number of groups", 0, INT_MAX);
RNA_def_property_flag(parm, PROP_OUTPUT);
+ func = RNA_def_function(srna, "normals_split_custom_set", "rna_Mesh_normals_split_custom_set");
+ RNA_def_function_ui_description(func,
+ "Define custom split normals of this mesh "
+ "(use zero-vectors to keep auto ones)");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
+ RNA_def_property_multi_array(parm, 2, normals_array_dim);
+ RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_REQUIRED);
+
+ func = RNA_def_function(srna, "normals_split_custom_set_from_vertices",
+ "rna_Mesh_normals_split_custom_set_from_vertices");
+ RNA_def_function_ui_description(func,
+ "Define custom split normals of this mesh, from vertices' normals "
+ "(use zero-vectors to keep auto ones)");
+ RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ /* TODO, see how array size of 0 works, this shouldnt be used */
+ parm = RNA_def_float_array(func, "normals", 1, NULL, -1.0f, 1.0f, "", "Normals", 0.0f, 0.0f);
+ RNA_def_property_multi_array(parm, 2, normals_array_dim);
+ RNA_def_property_flag(parm, PROP_DYNAMIC | PROP_REQUIRED);
func = RNA_def_function(srna, "update", "ED_mesh_update");
RNA_def_boolean(func, "calc_edges", 0, "Calculate Edges", "Force recalculation of edges");
@@ -211,7 +316,9 @@ void RNA_api_mesh(StructRNA *srna)
func = RNA_def_function(srna, "validate", "BKE_mesh_validate");
RNA_def_function_ui_description(func, "Validate geometry, return True when the mesh has had "
"invalid geometry corrected/removed");
- RNA_def_boolean(func, "verbose", 0, "Verbose", "Output information about the errors found");
+ RNA_def_boolean(func, "verbose", false, "Verbose", "Output information about the errors found");
+ RNA_def_boolean(func, "cleanup_cddata", true, "Cleanup CDData",
+ "Remove temp/cached cdlayers, like e.g. normals...");
parm = RNA_def_boolean(func, "result", 0, "Result", "");
RNA_def_function_return(func, parm);