Blender V5.0
bmo_bisect_plane.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_math_geom.h"
14#include "BLI_math_vector.h"
16
17#include "bmesh.hh"
18#include "bmesh_tools.hh"
19
20#include "intern/bmesh_operators_private.hh" /* own include */
21
22#define ELE_NEW 1
23#define ELE_CUT 2
24#define ELE_INPUT 4
25
27{
28 const float dist = BMO_slot_float_get(op->slots_in, "dist");
29 const bool use_snap_center = BMO_slot_bool_get(op->slots_in, "use_snap_center");
30 const bool clear_outer = BMO_slot_bool_get(op->slots_in, "clear_outer");
31 const bool clear_inner = BMO_slot_bool_get(op->slots_in, "clear_inner");
32
33 float plane_co[3];
34 float plane_no[3];
35 float plane[4];
36
37 BMO_slot_vec_get(op->slots_in, "plane_co", plane_co);
38 BMO_slot_vec_get(op->slots_in, "plane_no", plane_no);
39
40 if (is_zero_v3(plane_no)) {
41 BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "Zero normal given");
42 return;
43 }
44
45 plane_from_point_normal_v3(plane, plane_co, plane_no);
46
47 /* tag geometry to bisect */
50
52
53 BM_mesh_bisect_plane(bm, plane, use_snap_center, true, ELE_CUT, ELE_NEW, dist);
54
55 if (clear_outer || clear_inner) {
56 /* Use an array of vertices because 'geom' contains both verts and edges that may use them.
57 * Removing a vert may remove and edge which is later checked by #BMO_ITER.
58 * over-allocate the total possible vert count. */
59 const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_len(op->slots_in, "geom"));
60 BMVert **vert_arr = static_cast<BMVert **>(
61 MEM_mallocN(sizeof(*vert_arr) * size_t(vert_arr_max), __func__));
62 BMOIter siter;
63 BMVert *v;
64 float plane_inner[4];
65 float plane_outer[4];
66
67 STACK_DECLARE(vert_arr);
68
69 copy_v3_v3(plane_outer, plane);
70 copy_v3_v3(plane_inner, plane);
71 plane_outer[3] = plane[3] - dist;
72 plane_inner[3] = plane[3] + dist;
73
74 STACK_INIT(vert_arr, vert_arr_max);
75
76 BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
77 if ((clear_outer && plane_point_side_v3(plane_outer, v->co) > 0.0f) ||
78 (clear_inner && plane_point_side_v3(plane_inner, v->co) < 0.0f))
79 {
80 STACK_PUSH(vert_arr, v);
81 }
82 }
83
84 while ((v = STACK_POP(vert_arr))) {
86 }
87
88 MEM_freeN(vert_arr);
89 }
90
92 bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW | ELE_INPUT);
94 bm, op, op->slots_out, "geom_cut.out", BM_VERT | BM_EDGE, ELE_CUT);
95}
MINLINE int min_ii(int a, int b)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:217
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
#define STACK_POP(stack)
#define STACK_PUSH(stack, val)
#define STACK_DECLARE(stack)
#define STACK_INIT(stack, stack_num)
Read Guarded memory(de)allocation.
void BM_mesh_bisect_plane(BMesh *bm, const float plane[4], const bool use_snap_center, const bool use_tag, const short oflag_center, const short oflag_new, const float eps)
#define BM_ALL_NOLOOP
@ BM_ELEM_TAG
void BM_vert_kill(BMesh *bm, BMVert *v)
@ BMO_ERROR_CANCEL
void BMO_error_raise(BMesh *bm, BMOperator *owner, eBMOpErrorLevel level, const char *msg) ATTR_NONNULL(1
BMesh * bm
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
BMO_FLAG_BUFFER.
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3])
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define ELE_NEW
#define ELE_CUT
#define ELE_INPUT
void bmo_bisect_plane_exec(BMesh *bm, BMOperator *op)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]