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:
-rw-r--r--source/blender/blenkernel/BKE_customdata.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h3
-rw-r--r--source/blender/blenkernel/intern/customdata.c29
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c51
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c14
-rw-r--r--source/blender/makesrna/intern/rna_mesh_api.c16
6 files changed, 114 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 0b248be9780..17ad51a7a16 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -260,6 +260,8 @@ void CustomData_bmesh_interp(
* faces an array of length 4 */
void CustomData_swap_corners(struct CustomData *data, int index, const int *corner_indices);
+void CustomData_swap(struct CustomData *data, const int index_a, const int index_b);
+
/* gets a pointer to the data element at index from the first layer of type
* returns NULL if there is no layer of type
*/
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index f35613f8bf7..b85c605f231 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -317,6 +317,9 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(
int *r_totloop, int *r_totpoly,
struct MLoop **r_mloop, struct MPoly **r_mpoly);
+void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
+void BKE_mesh_polygons_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly);
+
/* flush flags */
void BKE_mesh_flush_hidden_from_verts_ex(
const struct MVert *mvert,
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index c120509b769..1ed7c989075 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2356,6 +2356,35 @@ void CustomData_swap_corners(struct CustomData *data, int index, const int *corn
}
}
+/**
+ * Swap two items of given custom data, in all available layers.
+ */
+void CustomData_swap(struct CustomData *data, const int index_a, const int index_b)
+{
+ int i;
+ char buff_static[256];
+
+ if (index_a == index_b) {
+ return;
+ }
+
+ for (i = 0; i < data->totlayer; ++i) {
+ const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[i].type);
+ const size_t size = typeInfo->size;
+ const size_t offset_a = size * index_a;
+ const size_t offset_b = size * index_b;
+
+ void *buff = size <= sizeof(buff_static) ? buff_static : MEM_mallocN(size, __func__);
+ memcpy(buff, POINTER_OFFSET(data->layers[i].data, offset_a), size);
+ memcpy(POINTER_OFFSET(data->layers[i].data, offset_a), POINTER_OFFSET(data->layers[i].data, offset_b), size);
+ memcpy(POINTER_OFFSET(data->layers[i].data, offset_b), buff, size);
+
+ if (buff != buff_static) {
+ MEM_freeN(buff);
+ }
+ }
+}
+
void *CustomData_get(const CustomData *data, int index, int type)
{
int offset;
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index e3b9b21f341..9fdd541813a 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -3200,6 +3200,57 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData
}
/** \} */
+/**
+ * Flip (invert winding of) the given \a mpoly, i.e. reverse order of its loops
+ * (keeping the same vertex as 'start point').
+ *
+ * \param mpoly the polygon to flip.
+ * \param mloop the full loops array.
+ * \param ldata the loops custom data.
+ */
+void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
+{
+ int loopstart = mpoly->loopstart;
+ int loopend = loopstart + mpoly->totloop - 1;
+ const bool loops_in_ldata = (CustomData_get_layer(ldata, CD_MLOOP) == mloop);
+
+ /* Note that we keep same start vertex for flipped face. */
+
+ /* We also have to update loops' edge
+ * (they ell get ther original 'other edge', that is, the original edge of their original previous loop)... */
+ unsigned int prev_edge_index = mloop[loopstart].e;
+ mloop[loopstart].e = mloop[loopend].e;
+
+ for (loopstart++; loopend > loopstart; loopstart++, loopend--) {
+ mloop[loopend].e = mloop[loopend - 1].e;
+ SWAP(unsigned int, mloop[loopstart].e, prev_edge_index);
+
+ if (!loops_in_ldata) {
+ SWAP(MLoop, mloop[loopstart], mloop[loopend]);
+ }
+ CustomData_swap(ldata, loopstart, loopend);
+ }
+ /* Even if we did not swap the other 'pivot' loop, we need to set its swapped edge. */
+ if (loopstart == loopend) {
+ mloop[loopstart].e = prev_edge_index;
+ }
+}
+
+/**
+ * Flip (invert winding of) all polygons (used to inverse their normals).
+ *
+ * \note Invalidates tessalation, caller must handle that.
+ */
+void BKE_mesh_polygons_flip(
+ MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
+{
+ MPoly *mp;
+ int i;
+
+ for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
+ BKE_mesh_polygon_flip(mp, mloop, ldata);
+ }
+}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 686f8331ac4..1d734864833 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -418,6 +418,14 @@ static float rna_MeshPolygon_area_get(PointerRNA *ptr)
return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert);
}
+static void rna_MeshPolygon_flip(ID *id, MPoly *mp)
+{
+ Mesh *me = (Mesh *)id;
+
+ BKE_mesh_polygon_flip(mp, me->mloop, &me->ldata);
+ BKE_mesh_tessface_clear(me);
+}
+
static void rna_MeshTessFace_normal_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
@@ -2138,6 +2146,7 @@ static void rna_def_mpolygon(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "MeshPolygon", NULL);
RNA_def_struct_sdna(srna, "MPoly");
@@ -2216,6 +2225,11 @@ static void rna_def_mpolygon(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_MeshPolygon_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index of this polygon");
+
+ func = RNA_def_function(srna, "flip", "rna_MeshPolygon_flip");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+ RNA_def_function_ui_description(func, "Invert winding of this polygon (flip its normal)");
+
}
/* mesh.loop_uvs */
diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c
index 1459157112e..a3bc21b0170 100644
--- a/source/blender/makesrna/intern/rna_mesh_api.c
+++ b/source/blender/makesrna/intern/rna_mesh_api.c
@@ -200,6 +200,15 @@ static void rna_Mesh_transform(Mesh *mesh, float *mat, int shape_keys)
DAG_id_tag_update(&mesh->id, 0);
}
+static void rna_Mesh_flip_normals(Mesh *mesh)
+{
+ BKE_mesh_polygons_flip(mesh->mpoly, mesh->mloop, &mesh->ldata, mesh->totpoly);
+ BKE_mesh_tessface_clear(mesh);
+ BKE_mesh_calc_normals(mesh);
+
+ DAG_id_tag_update(&mesh->id, 0);
+}
+
#else
void RNA_api_mesh(StructRNA *srna)
@@ -209,11 +218,16 @@ void RNA_api_mesh(StructRNA *srna)
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");
+ RNA_def_function_ui_description(func, "Transform mesh vertices by a matrix "
+ "(Warning: inverts normals if matrix is negative)");
parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_boolean(func, "shape_keys", 0, "", "Transform Shape Keys");
+ func = RNA_def_function(srna, "flip_normals", "rna_Mesh_flip_normals");
+ RNA_def_function_ui_description(func, "Invert winding of all polygons "
+ "(clears tessellation, does not handle custom normals)");
+
func = RNA_def_function(srna, "calc_normals", "BKE_mesh_calc_normals");
RNA_def_function_ui_description(func, "Calculate vertex normals");