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--release/scripts/startup/bl_ui/properties_data_modifier.py71
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h22
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c30
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c100
4 files changed, 196 insertions, 27 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 172fe07eab3..1dd3c545b79 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -569,7 +569,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.operator("object.meshdeform_bind", text="Bind")
def MIRROR(self, layout, ob, md):
- split = layout.split(factor=0.25)
+ split = layout.split(factor=0.33)
col = split.column()
col.label(text="Axis:")
@@ -578,15 +578,66 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "use_z")
col = split.column()
- col.label(text="Options:")
- col.prop(md, "use_mirror_merge", text="Merge")
- col.prop(md, "use_clip", text="Clipping")
- col.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
+ col.label(text="Bisect:")
+
+ col_x = col.column()
+ col_x.prop(md, "use_bisect_x")
+ col_x.active = md.use_x
+
+ col_y = col.column()
+ col_y.prop(md, "use_bisect_y")
+ col_y.active = md.use_y
+
+ col_z = col.column()
+ col_z.prop(md, "use_bisect_z")
+ col_z.active = md.use_z
col = split.column()
+ col.label(text="Flip:")
+
+ col_fx = col.column()
+ col_fx.prop(md, "flip_x")
+ col_fx.active = md.use_bisect_x and md.use_x
+
+ col_fy = col.column()
+ col_fy.prop(md, "flip_y")
+ col_fy.active = md.use_bisect_y and md.use_y
+
+ col_fz = col.column()
+ col_fz.prop(md, "flip_z")
+ col_fz.active = md.use_bisect_z and md.use_z
+
+ layout.separator()
+
+ col = layout.column()
+ col.label(text="Mirror Object:")
+ col.prop(md, "mirror_object", text="")
+
+ layout.separator()
+
+ col = layout.column()
+ col.label(text="Options:")
+
+ row = layout.row()
+ row.prop(md, "use_mirror_vertex_groups", text="Vertex Groups")
+ row.prop(md, "use_clip", text="Clipping")
+ row = layout.row()
+ row.prop(md, "use_mirror_merge", text="Merge")
+
+ col = layout.column()
+ if md.use_mirror_merge is True:
+ col.prop(md, "merge_threshold")
+
+ layout.separator()
+ col = layout.column()
+
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
col.label(text="Textures:")
- col.prop(md, "use_mirror_u", text="Flip U")
- col.prop(md, "use_mirror_v", text="Flip V")
+ row = layout.row()
+ row.prop(md, "use_mirror_u", text="Flip U")
+ row.prop(md, "use_mirror_v", text="Flip V")
col = layout.column(align=True)
@@ -600,12 +651,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "offset_u")
col.prop(md, "offset_v")
- col = layout.column()
-
- if md.use_mirror_merge is True:
- col.prop(md, "merge_threshold")
- col.label(text="Mirror Object:")
- col.prop(md, "mirror_object", text="")
def MULTIRES(self, layout, ob, md):
layout.row().prop(md, "subdivision_type", expand=True)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 4eb9f890be0..e2f963b7a1b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -313,14 +313,20 @@ typedef struct MirrorModifierData {
/* MirrorModifierData->flag */
enum {
- MOD_MIR_CLIPPING = (1 << 0),
- MOD_MIR_MIRROR_U = (1 << 1),
- MOD_MIR_MIRROR_V = (1 << 2),
- MOD_MIR_AXIS_X = (1 << 3),
- MOD_MIR_AXIS_Y = (1 << 4),
- MOD_MIR_AXIS_Z = (1 << 5),
- MOD_MIR_VGROUP = (1 << 6),
- MOD_MIR_NO_MERGE = (1 << 7),
+ MOD_MIR_CLIPPING = (1 << 0),
+ MOD_MIR_MIRROR_U = (1 << 1),
+ MOD_MIR_MIRROR_V = (1 << 2),
+ MOD_MIR_AXIS_X = (1 << 3),
+ MOD_MIR_AXIS_Y = (1 << 4),
+ MOD_MIR_AXIS_Z = (1 << 5),
+ MOD_MIR_VGROUP = (1 << 6),
+ MOD_MIR_NO_MERGE = (1 << 7),
+ MOD_MIR_BISECT_AXIS_X = (1 << 8),
+ MOD_MIR_BISECT_AXIS_Y = (1 << 9),
+ MOD_MIR_BISECT_AXIS_Z = (1 << 10),
+ MOD_MIR_FLIP_AXIS_X = (1 << 11),
+ MOD_MIR_FLIP_AXIS_Y = (1 << 12),
+ MOD_MIR_FLIP_AXIS_Z = (1 << 13),
};
typedef struct EdgeSplitModifierData {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index b633dd907ae..c2fa89891b0 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1561,6 +1561,36 @@ static void rna_def_modifier_mirror(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip", "Prevent vertices from going through the mirror during transform");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "use_bisect_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_BISECT_AXIS_X);
+ RNA_def_property_ui_text(prop, "X", "Cuts the mesh across the mirrorplane");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "use_bisect_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_BISECT_AXIS_Y);
+ RNA_def_property_ui_text(prop, "Y", "Cuts the mesh across the mirrorplane");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "use_bisect_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_BISECT_AXIS_Z);
+ RNA_def_property_ui_text(prop, "Z", "Cuts the mesh across the mirrorplane");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "flip_x", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_FLIP_AXIS_X);
+ RNA_def_property_ui_text(prop, "X", "Flips the direction of the slice");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "flip_y", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_FLIP_AXIS_Y);
+ RNA_def_property_ui_text(prop, "Y", "Flips the direction of the slice");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "flip_z", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_FLIP_AXIS_Z);
+ RNA_def_property_ui_text(prop, "Z", "Flips the direction of the slice");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "use_mirror_vertex_groups", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MIR_VGROUP);
RNA_def_property_ui_text(prop, "Mirror Vertex Groups", "Mirror vertex groups (e.g. .R->.L)");
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index d4e02a437d7..df08122aebf 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -45,6 +45,9 @@
#include "BKE_modifier.h"
#include "BKE_deform.h"
+#include "bmesh.h"
+#include "bmesh_tools.h"
+
#include "MEM_guardedalloc.h"
#include "DEG_depsgraph_build.h"
@@ -78,21 +81,90 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Mirror Modifier");
}
-static Mesh *doMirrorOnAxis(
+static Mesh *doBiscetOnMirrorPlane(
MirrorModifierData *mmd,
Object *ob,
const Mesh *mesh,
- int axis)
+ int axis,
+ float mirrormat[4][4])
+{
+ bool do_flip_axis = (
+ (axis == 0 && mmd->flag & MOD_MIR_FLIP_AXIS_X) ||
+ (axis == 1 && mmd->flag & MOD_MIR_FLIP_AXIS_Y) ||
+ (axis == 2 && mmd->flag & MOD_MIR_FLIP_AXIS_Z));
+
+ const float bisect_distance = 0.001;
+
+ Mesh *result;
+ BMesh *bm;
+ BMIter viter;
+ BMVert *v, *v_next;
+
+ bm = BKE_mesh_to_bmesh_ex(
+ mesh,
+ &(struct BMeshCreateParams){0},
+ &(struct BMeshFromMeshParams){
+ .calc_face_normal = true,
+ .cd_mask_extra = CD_MASK_ORIGINDEX,
+ });
+
+ /* prepare data for bisecting */
+ float plane[4];
+ float plane_co[3] = {0, 0, 0};
+ float plane_no[3];
+ copy_v3_v3(plane_no, mirrormat[axis]);
+
+ if (mmd->mirror_ob) {
+ float tmp[4][4];
+ invert_m4_m4(tmp, ob->obmat);
+ mul_m4_m4m4(tmp, tmp, mmd->mirror_ob->obmat);
+
+ copy_v3_v3(plane_no, tmp[axis]);
+ copy_v3_v3(plane_co, tmp[3]);
+ }
+
+ plane_from_point_normal_v3(plane, plane_co, plane_no);
+
+ BM_mesh_bisect_plane(bm, plane, false, false, 0, 0, bisect_distance);
+
+ /* Plane definitions for vert killing. */
+ float plane_offset[4];
+ copy_v3_v3(plane_offset, plane);
+ plane_offset[3] = plane[3] - bisect_distance;
+
+ if (do_flip_axis) {
+ negate_v3(plane_offset);
+ }
+
+ /* Delete verts across the mirror plane. */
+ BM_ITER_MESH_MUTABLE(v, v_next, &viter, bm, BM_VERTS_OF_MESH) {
+ if (plane_point_side_v3(plane_offset, v->co) > 0.0f) {
+ BM_vert_kill(bm, v);
+ }
+ }
+
+ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, 0);
+ BM_mesh_free(bm);
+
+ return result;
+}
+
+static Mesh *doMirrorOnAxis(
+ MirrorModifierData *mmd,
+ Object *ob,
+ const Mesh *mesh,
+ int axis)
{
const float tolerance_sq = mmd->tolerance * mmd->tolerance;
const bool do_vtargetmap = (mmd->flag & MOD_MIR_NO_MERGE) == 0;
int tot_vtargetmap = 0; /* total merge vertices */
+ const bool do_bisect = (
+ (axis == 0 && mmd->flag & MOD_MIR_BISECT_AXIS_X) ||
+ (axis == 1 && mmd->flag & MOD_MIR_BISECT_AXIS_Y) ||
+ (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z));
+
Mesh *result;
- const int maxVerts = mesh->totvert;
- const int maxEdges = mesh->totedge;
- const int maxLoops = mesh->totloop;
- const int maxPolys = mesh->totpoly;
MVert *mv, *mv_prev;
MEdge *me;
MLoop *ml;
@@ -125,6 +197,18 @@ static Mesh *doMirrorOnAxis(
mul_m4_m4m4(mtx, itmp, mtx);
}
+
+ Mesh *mesh_bisect = NULL;
+ if (do_bisect) {
+ mesh_bisect = doBiscetOnMirrorPlane(mmd, ob, mesh, axis, mtx);
+ mesh = mesh_bisect;
+ }
+
+ const int maxVerts = mesh->totvert;
+ const int maxEdges = mesh->totedge;
+ const int maxLoops = mesh->totloop;
+ const int maxPolys = mesh->totpoly;
+
result = BKE_mesh_new_nomain_from_template(
mesh, maxVerts * 2, maxEdges * 2, 0, maxLoops * 2, maxPolys * 2);
@@ -290,6 +374,10 @@ static Mesh *doMirrorOnAxis(
MEM_freeN(vtargetmap);
}
+ if (mesh_bisect != NULL) {
+ BKE_id_free(NULL, mesh_bisect);
+ }
+
return result;
}