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:
authorCampbell Barton <ideasman42@gmail.com>2018-11-21 02:01:04 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-11-21 02:01:04 +0300
commit19875439b5fb2b7c569bc95f384b5be548a5e45f (patch)
tree0133b5545724d2445a1497317d3a4f7aa78060b5 /source/blender/modifiers
parent6aa7cea3c28d5c79867ba64e4bcef8c5c6ef871e (diff)
Modifier: Mirror learns to bisect on plane
D3966 by @kioku w/ edits. This adds bisect and flip options to mirror modifier.
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c100
1 files changed, 94 insertions, 6 deletions
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;
}