Blender V4.3
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
11#include "MEM_guardedalloc.h"
12
13#include "BLI_math_geom.h"
14#include "BLI_math_vector.h"
15#include "BLI_utildefines.h"
17
18#include "bmesh.hh"
19#include "bmesh_tools.hh"
20
21#include "intern/bmesh_operators_private.hh" /* own include */
22
23#define ELE_NEW 1
24#define ELE_CUT 2
25#define ELE_INPUT 4
26
28{
29 const float dist = BMO_slot_float_get(op->slots_in, "dist");
30 const bool use_snap_center = BMO_slot_bool_get(op->slots_in, "use_snap_center");
31 const bool clear_outer = BMO_slot_bool_get(op->slots_in, "clear_outer");
32 const bool clear_inner = BMO_slot_bool_get(op->slots_in, "clear_inner");
33
34 float plane_co[3];
35 float plane_no[3];
36 float plane[4];
37
38 BMO_slot_vec_get(op->slots_in, "plane_co", plane_co);
39 BMO_slot_vec_get(op->slots_in, "plane_no", plane_no);
40
41 if (is_zero_v3(plane_no)) {
42 BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "Zero normal given");
43 return;
44 }
45
46 plane_from_point_normal_v3(plane, plane_co, plane_no);
47
48 /* tag geometry to bisect */
51
53
54 BM_mesh_bisect_plane(bm, plane, use_snap_center, true, ELE_CUT, ELE_NEW, dist);
55
56 if (clear_outer || clear_inner) {
57 /* Use an array of vertices because 'geom' contains both verts and edges that may use them.
58 * Removing a vert may remove and edge which is later checked by #BMO_ITER.
59 * over-allocate the total possible vert count. */
60 const int vert_arr_max = min_ii(bm->totvert, BMO_slot_buffer_len(op->slots_in, "geom"));
61 BMVert **vert_arr = static_cast<BMVert **>(
62 MEM_mallocN(sizeof(*vert_arr) * size_t(vert_arr_max), __func__));
63 BMOIter siter;
64 BMVert *v;
65 float plane_inner[4];
66 float plane_outer[4];
67
68 STACK_DECLARE(vert_arr);
69
70 copy_v3_v3(plane_outer, plane);
71 copy_v3_v3(plane_inner, plane);
72 plane_outer[3] = plane[3] - dist;
73 plane_inner[3] = plane[3] + dist;
74
75 STACK_INIT(vert_arr, vert_arr_max);
76
77 BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
78 if ((clear_outer && plane_point_side_v3(plane_outer, v->co) > 0.0f) ||
79 (clear_inner && plane_point_side_v3(plane_inner, v->co) < 0.0f))
80 {
81 STACK_PUSH(vert_arr, v);
82 }
83 }
84
85 while ((v = STACK_POP(vert_arr))) {
87 }
88
89 MEM_freeN(vert_arr);
90 }
91
93 bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW | ELE_INPUT);
95 bm, op, op->slots_out, "geom_cut.out", BM_VERT | BM_EDGE, ELE_CUT);
96}
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:215
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
ATTR_WARN_UNUSED_RESULT 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:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
int totvert