12# define _USE_MATH_DEFINES
15#include <fmt/format.h>
80#define USE_NET_ISLAND_CONNECT
82#define KMAXDIST (10 * UI_SCALE_FAC)
87#define KNIFE_FLT_EPS 0.00001f
88#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
89#define KNIFE_FLT_EPSBIG 0.0005f
91#define KNIFE_FLT_EPS_PX_VERT 0.5f
92#define KNIFE_FLT_EPS_PX_EDGE 0.05f
93#define KNIFE_FLT_EPS_PX_FACE 0.05f
95#define KNIFE_DEFAULT_ANGLE_SNAPPING_INCREMENT 30.0f
96#define KNIFE_MIN_ANGLE_SNAPPING_INCREMENT 0.0f
97#define KNIFE_MAX_ANGLE_SNAPPING_INCREMENT 180.0f
177 return this->ob_index == -1;
243#ifdef USE_NET_ISLAND_CONNECT
446 float numstr_size[2];
449 const float font_size = 14.0f;
450 const int distance_precision = 4;
457 SNPRINTF(numstr,
"%.*f", distance_precision, cut_len);
461 numstr,
sizeof(numstr), cut_len, distance_precision,
B_UNIT_LENGTH, unit,
false);
471 posit[0] -= numstr_size[0] / 2.0f;
472 posit[1] -= numstr_size[1] / 2.0f;
475 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
480 posit[0] - bg_margin,
481 posit[1] - bg_margin,
482 posit[0] + bg_margin + numstr_size[0],
483 posit[1] + bg_margin + numstr_size[1]);
501 const float start[3],
504 const float start_ss[2],
505 const float mid_ss[2],
506 const float end_ss[2],
510 const int arc_steps = 24;
514 const float font_size = 14.0f;
515 const int angle_precision = 3;
535 const float inverse_average_scale = 1 / (ob->object_to_world().
ptr()[0][0] +
536 ob->object_to_world().ptr()[1][1] +
537 ob->object_to_world().ptr()[2][2]);
539 const float px_scale =
540 3.0f * inverse_average_scale *
560 for (
int j = 0; j <= arc_steps; j++) {
583 float numstr_size[2];
600 posit[0] = mid_ss[0] + (cap_size * 2.0f);
601 posit[1] = mid_ss[1] - (numstr_size[1] / 2.0f);
604 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
609 posit[0] - bg_margin,
610 posit[1] - bg_margin,
611 posit[0] + bg_margin + numstr_size[0],
612 posit[1] + bg_margin + numstr_size[1]);
648 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
649 if (tempkfe->
v1 != kfv) {
650 tempkfv = tempkfe->
v1;
653 tempkfv = tempkfe->
v2;
656 if (
angle < min_angle) {
691 if (angle1 < angle2) {
718 if (kfe->
v1 != kfv) {
731 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
732 if (tempkfe->
v1 != kfv) {
733 tempkfv = tempkfe->
v1;
736 tempkfv = tempkfe->
v2;
739 if (
angle < min_angle) {
781 if (angle1 < angle2) {
987 if (total_hits > 0) {
993 int other_verts_count = 0;
994 int snapped_verts_count = 0;
1013 if (snapped_verts_count > 0) {
1022 if (other_verts_count > 0) {
1062 auto get_modal_key_str = [&](
int id) {
1086 const std::string
angle = fmt::format(
1087 "{}: {:.2f}({:.2f}) ({}{}{}{})",
1088 IFACE_(
"Angle Constraint"),
1115 int tri_index_buf[3])
1121 const std::array<BMLoop *, 3> <ri = obinfo->
em->
looptris[tri_index];
1122 for (
int i = 0;
i < 3;
i++) {
1125 return tri_index_buf;
1136 for (
int i = 0;
i < 3;
i++) {
1148 for (
int i = 0;
i < 3;
i++) {
1175 bool (*test_fn)(
BMFace *);
1184 const float epsilon = FLT_EPSILON * 2.0f;
1188 BMFace *f_test =
nullptr, *f_test_prev =
nullptr;
1189 bool test_fn_ret =
false;
1198 if (f_test != f_test_prev) {
1199 test_fn_ret = test_fn(f_test);
1200 f_test_prev = f_test;
1208 tottri += ob_tottri;
1213 f_test_prev =
nullptr;
1214 test_fn_ret =
false;
1229 f_test = looptris[
i][0]->f;
1230 if (f_test != f_test_prev) {
1231 test_fn_ret = test_fn(f_test);
1232 f_test_prev = f_test;
1239 float tri_cos[3][3];
1269 BMLoop *
const *ltri =
nullptr;
1279 for (; ob_index < kcd->
objects.
size(); ob_index++) {
1284 if (index < tottri) {
1297 float tri_cos[3][3];
1299 isect = (ray->
radius > 0.0f ?
1302#ifdef USE_KDOPBVH_WATERTIGHT
1309 if (isect && dist < hit->dist) {
1340 const float dist = r_dist ? *r_dist :
FLT_MAX;
1347 if (hit.
index != -1 && hit.
dist != dist) {
1375 bool (*filter_cb)(
BMFace *f,
void *userdata),
1376 void *filter_userdata)
1402 const float mval[2],
1417 float origin_ofs[3];
1418 float ray[3], ray_normal[3];
1430 bool v1_inside, v2_inside;
1431 bool v1_inface, v2_inface;
1434 if (!f || !v1 || !
v2) {
1447 v1_inface = (l1 !=
nullptr);
1448 v2_inface = (l2 !=
nullptr);
1453 if ((v1_inface && v2_inside) || (v2_inface && v1_inside) || (v1_inside && v2_inside)) {
1457 if (v1_inface && v2_inface) {
1491 if (r_kfe || ele_test ==
nullptr) {
1492 if (kfv->
v ==
nullptr) {
1494 kfe =
static_cast<KnifeEdge *
>(ref->data);
1506 if (ele_test ==
nullptr) {
1513 if (ele_test ==
nullptr) {
1528 if (ele_test ==
nullptr) {
1562 if (ref1->data == ref) {
1600 if (ref1->data == ref2->data) {
1601 return (
BMFace *)(ref1->data);
1637 const float *cageco;
1652 mul_v3_m4v3(cageco_ws, ob->object_to_world().ptr(), cageco);
1721 const float cageco[3],
1728 newkfe->
v1 = kfe->
v1;
1749 kfe->
v1 = newkfe->
v2;
1781 kfe->
v1 = newkfe->
v1;
1798 const float3 *curr_cage_constrain,
1830 if (lh1.
l < lh2.
l) {
1833 if (lh1.
l > lh2.
l) {
1836 if (lh1.
m < lh2.
m) {
1839 if (lh1.
m > lh2.
m) {
1842 if (lh1.
v < lh2.
v) {
1845 if (lh1.
v > lh2.
v) {
1858 bool is_double =
false;
1871 for (
int i = 0;
i < total_hits;
i++) {
1873 if (lhi->
v ==
nullptr) {
1877 for (
int j =
i - 1; j >= 0; j--) {
1885 if (lhi->
kfe == lhj->
kfe) {
1890 for (
int j =
i + 1; j < total_hits; j++) {
1895 if ((lhj->
kfe && (lhi->
kfe == lhj->
kfe)) || (lhi->
v == lhj->
v)) {
1906 while (j < total_hits) {
1909 if (lhj->
l == -1.0f) {
1914 if (lhi->
l == -1.0f) {
1955 if (lh->
v && lh->
v->
v) {
1963 else if (lh->
kfe && lh->
kfe->
e) {
1983 if ((lh1->
v && lh1->
v == lh2->
v) || (lh1->
kfe && lh1->
kfe == lh2->
kfe)) {
1988 if ((lh1->
v && lh2->
v) && (lh1->
v->
v && lh2->
v && lh2->
v->
v) &&
2000 if ((lh1->
v && !lh1->
kfe) && (lh2->
v && !lh2->
kfe)) {
2013 else if (lh1->
kfe) {
2029 else if (lh2->
kfe) {
2085 bool is_new_edge =
false;
2086 kfe =
static_cast<KnifeEdge *
>(ref->data);
2092 if (kfe->
e ==
nullptr) {
2093 if (kfe->
v1->
v && kfe->
v2->
v) {
2105 if (kfe->
v1->
v ==
nullptr) {
2108 if (kfe->
v2->
v ==
nullptr) {
2124 kfe_array[
i] = is_new_edge ? kfe :
nullptr;
2125 edge_array[
i] = kfe->
e;
2131 const int edge_array_len_orig =
i;
2134#ifdef USE_NET_ISLAND_CONNECT
2135 uint edge_array_holes_len;
2136 BMEdge **edge_array_holes;
2144 &edge_array_holes_len))
2147 for (
i = edge_array_len;
i < edge_array_holes_len;
i++) {
2152 edge_array_len = edge_array_holes_len;
2153 edge_array = edge_array_holes;
2162 for (
i = 0;
i < edge_array_len_orig;
i++) {
2163 if (kfe_array[
i] ==
nullptr) {
2168 kfe_array[
i]->
e =
nullptr;
2172#ifdef USE_NET_ISLAND_CONNECT
2184 const float *co =
static_cast<const float *
>(co_p);
2249 kfe =
static_cast<KnifeEdge *
>(ref->data);
2267 for (
auto [
e, list] : ehash.
items()) {
2271 kfv =
static_cast<KnifeVert *
>(ref->data);
2282 for (
auto [f, list] : fhash.
items()) {
2402 BLI_assert(index >= 0 && index < em->looptris.size());
2404 for (
i = index - 1;
i >= 0;
i--) {
2442 const float face_tol_sq,
2444 float hit_cageco[3])
2451 float tri_norm[3], tri_plane[4];
2452 float se1[2], se2[2];
2463 for (; tri_i < tottri; tri_i++) {
2464 float tri_cos[3][3];
2465 float ray_tri_uv[2];
2467 const std::array<BMLoop *, 3> <ri = em->
looptris[tri_i];
2468 if (ltri[0]->f != f) {
2492 kfe =
static_cast<KnifeEdge *
>(ref->data);
2499 if (d < face_tol_sq) {
2524 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2532 mul_m4_v3(ob->object_to_world().ptr(), ws);
2539 mul_m4_v3(ob->object_to_world().ptr(), ws);
2552 const float *co11, *co12, *co21, *co22;
2577 switch (((
BMElem *)user_data)->head.htype) {
2579 ans = (
BMFace *)user_data != f;
2630 float view[3], p_ofs[3];
2646 float view_clip[2][3];
2652 view_clip[0], view_clip[1], kcd->
vc.
rv3d->
clip_local, 6, view_clip[0], view_clip[1]))
2654 dist =
len_v3v3(p_ofs, view_clip[1]);
2710 memset(r_hit, 0,
sizeof(*r_hit));
2769 float s[2], se1[2], se2[2];
2771 float vert_tol, vert_tol_sq;
2772 float line_tol, line_tol_sq;
2773 float face_tol, face_tol_sq;
2830 BMLoop *
const *ltri =
nullptr;
2831 for (ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2849 if (
faces.contains(f)) {
2854 fobs.
add(f, ob_index);
2885 vert_tol = line_tol = face_tol = 0.5f;
2888 vert_tol_sq = vert_tol * vert_tol;
2889 line_tol_sq = line_tol * line_tol;
2890 face_tol_sq = face_tol * face_tol;
2899 bool kfv_is_in_cut =
false;
2906 kfv_is_in_cut =
true;
2911 if ((d <= vert_tol_sq) &&
2914 kfv_is_in_cut =
true;
2918 if (kfv_is_in_cut) {
2941 bool kfe_is_in_cut =
false;
2946 kfe_is_in_cut =
true;
2952 kfe_is_in_cut =
true;
2956 if (isect_kind == -1) {
2969 if (isect_kind == 1) {
2972 if (!(d1 <= line_tol || d2 <= line_tol ||
fabsf(d1 - d2) <= line_tol)) {
2976 float3 kfe_dir = kfe->v2->cageco - kfe->v1->cageco;
2978 p_cage = kfe->v1->cageco + kfe_dir * lambda;
2982 mid_v3_v3v3(p_cage, kfe->v1->cageco, kfe->v2->cageco);
2985 kfe_is_in_cut =
true;
2991 if (kfe_is_in_cut) {
2992 knife_linehit_set(kcd, s1, s2, p_cage_ss, p_cage, kfe->v1->ob_index,
nullptr, kfe, &hit);
2998 const bool use_hit_prev = (kcd->
prev.
vert ==
nullptr) && (kcd->
prev.
edge ==
nullptr);
2999 const bool use_hit_curr = (kcd->
curr.
vert ==
nullptr) && (kcd->
curr.
edge ==
nullptr) &&
3001 if (use_hit_prev || use_hit_curr) {
3026 int ob_index = fobs.
lookup(f);
3041 kcd->
linehits = std::move(linehits);
3055 kpd->
vert =
nullptr;
3056 kpd->
edge =
nullptr;
3093 vc.
mval[0] = int(mval[0]);
3094 vc.
mval[1] = int(mval[1]);
3104 cage = ray_orig + ray_dir;
3132 const float radius_sq = radius * radius;
3149 for (
i = 0;
i < 2;
i++) {
3160 if (dis_sq < radius_sq) {
3192 return density ?
min_ff(maxsize / (
float(density) * 0.5f), maxsize) : maxsize;
3202 const float3 &kfv1_cageco,
3203 const float3 &kfv2_cageco,
3208 if (!
isect_ray_line_v3(cut_origin, cut_dir, kfv1_cageco, kfv2_cageco, &lambda)) {
3225 const float2 &curr_cage_ss,
3226 const float3 *curr_cage_constrain,
3244 const float maxdist_sq = maxdist * maxdist;
3245 float cur_dist_sq = maxdist_sq;
3246 bool has_hit =
false;
3250 (curr_cage_constrain ? *curr_cage_constrain : kcd->
curr.
cage) - kcd->
prev.
cage);
3256 float test_cagep[3];
3281 if (dis_sq >= cur_dist_sq) {
3292 cur_dist_sq = dis_sq;
3301 r_kpd->
mval = closest_ss;
3328 const float maxdist_sq = maxdist * maxdist;
3330 float cur_kfv_sco[2];
3331 float dis_sq, curdis_sq =
FLT_MAX;
3333 for (
int i = 0;
i < 2;
i++) {
3350 if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
3367 r_kpd->
mval = cur_kfv_sco;
3382 const float angle_delta = (roundf(
angle / angle_snap) * angle_snap) -
angle;
3384 return angle + angle_delta;
3395 float3 curr_cage_projected;
3397 curr_cage_projected, ray_orig, ray_orig + ray_dir, kcd->
prev.
cage, axis))
3419 r_cage = kcd->
prev.
cage + dvec_snap;
3506 float3 prev_ray_orig, prev_ray_dir;
3517 kcd, prev_ray_orig, prev_ray_dir, 0.0f,
nullptr,
nullptr, &fprev_ob_index);
3520 if (!fprev || fprev != fcurr) {
3594 const short orientation_type = scene_orientation ? scene_orientation :
3599 scene, view_layer, kcd->
vc.
v3d, rv3d, obedit, obedit, orientation_type, pivot_point, mat);
3609 float3 cage_dir = constrain_dir * lambda;
3614 r_cage = kcd->
prev.
cage + cage_dir;
3626 const float3 *curr_cage_constrain,
3638 curr_cage_constrain,
3644 kcd->
curr = kpos_tmp;
3691 float2 mval_constrain = mval;
3700 bool is_constrained =
false;
3718 is_constrained =
true;
3722 is_constrained =
true;
3727 float3 curr_cage_constrain;
3728 if (is_constrained) {
3742 curr_cage_constrain = kcd->
curr.
cage;
3750 is_constrained ? &curr_cage_constrain :
nullptr,
3751 is_constrained ? &fallback :
nullptr);
3771 for (
int i = 0;
i < undo->
splits;
i++) {
3777 for (
int i = 0;
i < undo->
cuts;
i++) {
3801 kfe =
static_cast<KnifeEdge *
>(ref->data);
3810 if (!
v2->is_invalid && !
v2->is_splitting) {
3811 v2->is_invalid =
true;
3814 kfe =
static_cast<KnifeEdge *
>(ref->data);
3816 v2->is_invalid =
false;
3844 bool use_tri_indices)
3848 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(ob->
data);
3849 const Mesh &mesh_eval = *
static_cast<const Mesh *
>(obedit_eval->
data);
3855 obinfo->
em = &em_eval;
3857 kcd->
vc.
depsgraph, &em_eval, scene_eval, obedit_eval);
3860 obinfo->
em = mesh_orig.
runtime->edit_mesh.get();
3866 if (use_tri_indices) {
3869 const std::array<BMLoop *, 3> <ri = obinfo->
em->
looptris[
i];
3908 const bool only_select,
3909 const bool cut_through,
3911 const int visible_measurements,
3912 const int angle_snapping,
3913 const float angle_snapping_increment,
3914 const bool is_interactive)
3918 bool use_tri_indices = !is_interactive;
3928 kcd->
objects = std::move(objects);
3933 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
3955#ifdef USE_NET_ISLAND_CONNECT
3982 if (is_interactive) {
4030#ifdef USE_NET_ISLAND_CONNECT
4098 params.calc_looptris =
true;
4099 params.calc_normals =
true;
4100 params.is_destructive =
true;
4148 "CYCLE_ANGLE_SNAP_EDGE",
4150 "Cycle Angle Snapping Relative Edge",
4154 "SHOW_DISTANCE_ANGLE_TOGGLE",
4156 "Toggle Distance and Angle Measurements",
4166 {0,
nullptr, 0,
nullptr,
nullptr},
4202 bool do_refresh =
false;
4219 bool handled =
false;
4220 float snapping_increment_temp;
4221 const float2 mval = {float(event->
mval[0]), float(event->
mval[1])};
4249 switch (event->
val) {
4259 const bool changed = (kcd->
totkvert != 0);
4452 switch (event->
type) {
4563 const int visible_measurements =
RNA_enum_get(op->
ptr,
"visible_measurements");
4566 const float angle_snapping_increment =
RAD2DEGF(
4581 visible_measurements,
4583 angle_snapping_increment,
4587 bool faces_selected =
false;
4591 faces_selected =
true;
4595 if (!faces_selected) {
4608 if (wait_for_input ==
false) {
4631 ot->name =
"Knife Topology Tool";
4632 ot->idname =
"MESH_OT_knife_tool";
4633 ot->description =
"Cut new topology";
4651 {0,
nullptr, 0,
nullptr,
nullptr},
4661 "Angle snapping relative to the previous cut edge"},
4662 {0,
nullptr, 0,
nullptr,
nullptr},
4666 "use_occlude_geometry",
4669 "Only cut the front most geometry");
4670 RNA_def_boolean(
ot->srna,
"only_selected",
false,
"Only Selected",
"Only cut selected geometry");
4671 RNA_def_boolean(
ot->srna,
"xray",
true,
"X-Ray",
"Show cuts hidden by geometry");
4674 "visible_measurements",
4675 visible_measurements_items,
4678 "Visible distance and angle measurements");
4681 angle_snapping_items,
4684 "Angle snapping mode");
4688 "angle_snapping_increment",
4692 "Angle Snap Increment",
4693 "The angle snap increment used when in constrained angle mode",
4716 const float(*mval_fl)[2] =
static_cast<const float(*)[2]
>(p->
link);
4735 const bool only_select =
false;
4736 const bool is_interactive =
false;
4737 const bool xray =
false;
4742 kcd = MEM_new<KnifeTool_OpData>(__func__);
4750 visible_measurements,
4752 angle_snapping_increment,
4766 const float(*mval_fl)[2] =
static_cast<const float(*)[2]
>(p->
link);
4773 for (
i = 1;
i < mval_tot;
i++) {
4809#define F_ISECT_IS_UNKNOWN(f) BM_elem_flag_test(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4810#define F_ISECT_SET_UNKNOWN(f) BM_elem_flag_enable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4811#define F_ISECT_SET_OUTSIDE(f) BM_elem_flag_disable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4830 float cent[3], cent_ss[2];
4832 mul_m4_v3(ob->object_to_world().ptr(), cent);
4843 keep_search =
false;
4852 BMLoop *l_iter = l_first;
4859 if (l_radial_iter != l_iter) {
4864 }
while ((l_radial_iter = l_radial_iter->
radial_next) != l_iter &&
4868 }
while ((l_iter = l_iter->
next) != l_first && (found ==
false));
4871 float cent[3], cent_ss[2];
4873 mul_m4_v3(ob->object_to_world().ptr(), cent);
4887 }
while (keep_search);
4889#undef F_ISECT_IS_UNKNOWN
4890#undef F_ISECT_SET_UNKNOWN
4891#undef F_ISECT_SET_OUTSIDE
wmWindow * CTX_wm_window(const bContext *C)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
blender::Array< blender::float3 > BKE_editmesh_vert_coords_alloc(Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, Object *ob)
bool BKE_editmesh_eval_orig_map_available(const Mesh &mesh_eval, const Mesh *mesh_orig)
bool BKE_object_is_visible_in_viewport(const View3D *v3d, const Object *ob)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
void BKE_report(ReportList *reports, eReportType type, const char *message)
int BKE_scene_orientation_get_index(Scene *scene, int slot_index)
size_t BKE_unit_value_as_string(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings &settings, bool pad)
size_t BKE_unit_value_as_string_scaled(char *str, int str_maxncpy, double value, int prec, int type, const UnitSettings &settings, bool pad)
void BLF_size(int fontid, float size)
void BLF_color3ubv(int fontid, const unsigned char rgb[3])
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
void BLF_disable(int fontid, int option)
void BLF_rotation(int fontid, float angle)
void BLF_draw(int fontid, const char *str, size_t str_len, ResultBLF *r_info=nullptr) ATTR_NONNULL(2)
void BLF_enable(int fontid, int option)
void BLF_position(int fontid, float x, float y, float z)
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_unreachable()
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
GSet * BLI_gset_ptr_new(const char *info)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
unsigned int BLI_gset_len(const GSet *gs) ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
bool BLI_gset_add(GSet *gs, void *key)
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
int * BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num)
void BLI_bvhtree_balance(BVHTree *tree)
void BLI_bvhtree_free(BVHTree *tree)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count_at_most(const ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void BLI_listbase_sort_r(ListBase *listbase, int(*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
MINLINE float min_ff(float a, float b)
MINLINE float min_fff(float a, float b, float c)
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
int isect_seg_seg_v2_point_ex(const float v0[2], const float v1[2], const float v2[2], const float v3[2], float endpoint_bias, float r_vi[2])
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
bool clip_segment_v3_plane_n(const float p1[3], const float p2[3], const float plane_array[][4], int plane_num, float r_p1[3], float r_p2[3])
bool isect_ray_ray_v3(const float ray_origin_a[3], const float ray_direction_a[3], const float ray_origin_b[3], const float ray_direction_b[3], float *r_lambda_a, float *r_lambda_b)
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, bool clip)
float dist_squared_to_plane_v3(const float p[3], const float plane[4])
bool isect_ray_line_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], float *r_lambda)
void transform_point_by_seg_v3(float p_dst[3], const float p_src[3], const float l_dst_p1[3], const float l_dst_p2[3], const float l_src_p1[3], const float l_src_p2[3])
bool isect_ray_tri_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
bool isect_point_poly_v2(const float pt[2], const float verts[][2], unsigned int nr)
float closest_ray_to_segment_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], float r_close[3])
bool isect_ray_tri_watertight_v3(const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc, const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2])
float closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
bool isect_ray_tri_epsilon_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], float epsilon)
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void mul_qt_v3(const float q[4], float r[3])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], float angle)
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v2(float r[2])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3v3_uv(float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2])
MINLINE float normalize_v3(float n[3])
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) ATTR_NONNULL()
void * BLI_mempool_iterstep(BLI_mempool_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1)
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
void BLI_stack_pop(BLI_Stack *stack, void *dst) ATTR_NONNULL()
void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL()
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
void * BLI_stack_peek(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_discard(BLI_Stack *stack) ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
#define SNPRINTF(dst, format,...)
#define BLI_STR_UTF8_DEGREE_SIGN
#define UNUSED_FUNCTION(x)
#define INIT_MINMAX(min, max)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define POINTER_AS_INT(i)
#define BLT_I18NCONTEXT_ID_MESH
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
Object is a sort of wrapper for general info.
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ OP_IS_MODAL_CURSOR_REGION
#define OPERATOR_RETVAL_CHECK(ret)
void EDBM_flag_disable_all(BMEditMesh *em, char hflag)
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
BMFace * EDBM_face_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
ViewContext em_setup_viewcontext(bContext *C)
void EDBM_selectmode_flush(BMEditMesh *em)
bool ED_operator_editmesh_view3d(bContext *C)
void ED_workspace_status_text(bContext *C, const char *str)
void ED_region_tag_redraw(ARegion *region)
void * ED_region_draw_cb_activate(ARegionType *art, void(*draw)(const bContext *, ARegion *, void *), void *customdata, int type)
#define REGION_DRAW_POST_VIEW
bool ED_region_draw_cb_exit(ARegionType *art, void *handle)
bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_normal[3], bool do_clip_planes)
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
bool ED_view3d_unproject_v3(const ARegion *region, float regionx, float regiony, float regionz, float world[3])
bool ED_view3d_win_to_segment_clipped(const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
bool ED_view3d_clip_range_get(const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, bool use_ortho_factor, float *r_clip_start, float *r_clip_end)
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], bool is_local)
eV3DProjStatus ED_view3d_project_float_global(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
#define GPU_batch_uniform_1f(batch, name, x)
void GPU_batch_discard(blender::gpu::Batch *batch)
void GPU_batch_program_set_builtin(blender::gpu::Batch *batch, eGPUBuiltinShader shader_id)
void GPU_batch_draw(blender::gpu::Batch *batch)
#define GPU_batch_uniform_4fv(batch, name, val)
void GPU_batch_draw_range(blender::gpu::Batch *batch, int vertex_first, int vertex_count)
void GPU_matrix_identity_set()
void GPU_matrix_push_projection()
void GPU_matrix_pop_projection()
void GPU_polygon_offset(float viewdist, float dist)
@ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_program_point_size(bool enable)
void GPU_blend(eGPUBlend blend)
void GPU_line_width(float width)
void GPU_depth_test(eGPUDepthTest test)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
void UI_GetThemeColorType3ubv(int colorid, int spacetype, unsigned char col[3])
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
#define BM_FACE_FIRST_LOOP(p)
void BM_edge_kill(BMesh *bm, BMEdge *e)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
BMesh const char void * data
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
Select Edge.
Array< float3 > BM_mesh_vert_coords_alloc(BMesh *bm)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
bool BM_face_point_inside_test(const BMFace *f, const float co[3])
bool BM_face_split_edgenet_connect_islands(BMesh *bm, BMFace *f, BMEdge **edge_net_init, const uint edge_net_init_len, bool use_partial_connect, MemArena *mem_arena, BMEdge ***r_edge_net_new, uint *r_edge_net_new_len)
bool BM_face_split_edgenet(BMesh *bm, BMFace *f, BMEdge **edge_net, const int edge_net_len, blender::Vector< BMFace * > *r_face_arr)
float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3])
bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
bool BM_vert_in_face(BMVert *v, BMFace *f)
BMLoop * BM_face_edge_share_loop(BMFace *f, BMEdge *e)
Return the Loop Shared by Face and Edge.
BMLoop * BM_face_vert_share_loop(BMFace *f, BMVert *v)
Return the Loop Shared by Face and Vertex.
float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3])
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
bool closest(btVector3 &v)
void reinitialize(const int64_t new_size)
const T & last(const int64_t n=0) const
IndexRange index_range() const
void resize(const int64_t new_size)
int64_t first_index_of_try(const T &value) const
void item(std::string text, int icon1, int icon2=0)
void opmodal(std::string text, const wmOperatorType *ot, int propvalue, bool inverted=false)
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
Value lookup_default(const Key &key, const Value &default_value) const
ItemIterator items() const &
bool contains(const Key &key) const
bool remove(const Key &key)
constexpr bool is_empty() const
void append(const T &value)
static bool knife_find_closest_face(KnifeTool_OpData *kcd, const float2 &mval, const float3 &ray_orig, const float3 &ray_dir, KnifePosData *r_kpd)
static void knife_bvh_init(KnifeTool_OpData *kcd)
static void knifetool_disable_angle_snapping(KnifeTool_OpData *kcd)
static void knife_edge_append_face(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMFace *f)
static void knife_find_line_hits(KnifeTool_OpData *kcd)
static KnifeVert * get_bm_knife_vert(KnifeTool_OpData *kcd, BMVert *v, int ob_index)
static bool knife_find_closest_vert_of_edge(KnifeTool_OpData *kcd, const KnifeEdge *kfe, const float2 &cage_ss, KnifePosData *r_kpd)
static void knifetool_draw_angle(const KnifeTool_OpData *kcd, const float start[3], const float mid[3], const float end[3], const float start_ss[2], const float mid_ss[2], const float end_ss[2], const float angle)
static BMFace * knife_bvh_raycast(KnifeTool_OpData *kcd, const float co[3], const float dir[3], const float radius, float *r_dist, float r_cagehit[3], int *r_ob_index)
static ListBase * knife_get_face_kedges(KnifeTool_OpData *kcd, int ob_index, BMFace *f)
static bool knife_ray_intersect_face(KnifeTool_OpData *kcd, const float s[2], const float v1[3], const float v2[3], int ob_index, BMFace *f, const float face_tol_sq, float hit_co[3], float hit_cageco[3])
#define KNIFE_FLT_EPS_PX_VERT
@ KNF_CONSTRAIN_AXIS_MODE_LOCAL
@ KNF_CONSTRAIN_AXIS_MODE_GLOBAL
@ KNF_CONSTRAIN_AXIS_MODE_NONE
static void knife_input_ray_segment(const KnifeTool_OpData *kcd, const float mval[2], float r_origin[3], float r_end[3])
static bool knife_closest_constrain_to_edge(const float3 &cut_origin, const float3 &cut_dir, const float3 &kfv1_cageco, const float3 &kfv2_cageco, float r_close[3])
static void knife_bvh_free(KnifeTool_OpData *kcd)
static void calc_ortho_extent(KnifeTool_OpData *kcd)
static BMFace * knife_find_common_face(ListBase *faces1, ListBase *faces2)
static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd)
static ListBase * knife_empty_list(KnifeTool_OpData *kcd)
static void knife_draw_line(const KnifeTool_OpData *kcd, const uchar color[3])
static int knife_calculate_snap_ref_edges(KnifeTool_OpData *kcd, const float3 &ray_orig, const float3 &ray_dir)
static void knifetool_draw_orientation_locking(const KnifeTool_OpData *kcd)
static void knife_project_v2(const KnifeTool_OpData *kcd, const float co[3], float sco[2])
static void knife_make_cuts(KnifeTool_OpData *kcd, int ob_index)
static void UNUSED_FUNCTION knifetool_recast_cageco(KnifeTool_OpData *kcd, float mval[3], float r_cage[3])
static void knifetool_init(ViewContext *vc, KnifeTool_OpData *kcd, Vector< Object * > objects, const bool only_select, const bool cut_through, const bool xray, const int visible_measurements, const int angle_snapping, const float angle_snapping_increment, const bool is_interactive)
static void knifetool_draw_dist_angle(const KnifeTool_OpData *kcd)
static void linehit_to_knifepos(KnifePosData *kpos, KnifeLineHit *lh)
static bool knife_verts_edge_in_face(KnifeVert *v1, KnifeVert *v2, BMFace *f)
static void knifetool_undo(KnifeTool_OpData *kcd)
#define KNIFE_FLT_EPS_PX_EDGE
@ KNF_MODAL_DEPTH_TEST_TOGGLE
@ KNF_MODAL_CYCLE_ANGLE_SNAP_EDGE
@ KNF_MODAL_SHOW_DISTANCE_ANGLE_TOGGLE
@ KNF_MODAL_ANGLE_SNAP_TOGGLE
@ KNF_MODAL_IGNORE_SNAP_OFF
@ KNF_MODAL_ADD_CUT_CLOSED
@ KNF_MODAL_IGNORE_SNAP_ON
@ KNF_MODAL_CUT_THROUGH_TOGGLE
static void knifetool_finish_ex(KnifeTool_OpData *kcd)
static void knife_append_list(KnifeTool_OpData *kcd, ListBase *lst, void *elem)
static void knifetool_cancel(bContext *, wmOperator *op)
static void prepare_linehits_for_cut(KnifeTool_OpData *kcd)
static BMElem * bm_elem_from_knife_edge(KnifeEdge *kfe)
#define F_ISECT_SET_UNKNOWN(f)
static LinkData * find_ref(ListBase *lb, void *ref)
static void knifetool_finish_single_post(KnifeTool_OpData *, Object *ob)
static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMesh *bm, BMFace *f, ListBase *kfedges)
static bool knife_bm_face_is_not_hidden(BMFace *f)
static void knifetool_update_mval(KnifeTool_OpData *kcd, const float2 &mval)
static void knifetool_exit(wmOperator *op)
static bool knife_snap_angle_impl(const KnifeTool_OpData *kcd, const float3 &vec_x, const float3 &axis, const float3 &ray_orig, const float3 &ray_dir, float3 &r_cage, float &r_angle)
wmKeyMap * knifetool_modal_keymap(wmKeyConfig *keyconf)
static void knife_finish_cut(KnifeTool_OpData *kcd)
@ KNF_CONSTRAIN_ANGLE_MODE_NONE
@ KNF_CONSTRAIN_ANGLE_MODE_SCREEN
@ KNF_CONSTRAIN_ANGLE_MODE_RELATIVE
static void knife_bm_tri_cagecos_get_worldspace(const KnifeTool_OpData *kcd, int ob_index, int tri_index, float cos[3][3])
#define F_ISECT_SET_OUTSIDE(f)
static void knife_add_to_vert_edges(KnifeTool_OpData *kcd, KnifeEdge *kfe)
void MESH_OT_knife_tool(wmOperatorType *ot)
static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3], const float d)
static void knife_bvh_raycast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
static void knife_recalc_ortho(KnifeTool_OpData *kcd)
static bool knife_linehit_face_test(KnifeTool_OpData *kcd, float s1[2], float s2[2], float sco[2], float ray_start[3], float ray_end[3], int ob_index, BMFace *f, float face_tol_sq, KnifeLineHit *r_hit)
static wmOperatorStatus knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
#define KNIFE_MAX_ANGLE_SNAPPING_INCREMENT
static void knife_join_edge(KnifeEdge *newkfe, KnifeEdge *kfe)
static void add_hit_to_facehits(KnifeTool_OpData *kcd, GHash *facehits, BMFace *f, KnifeLineHit *hit)
static int get_lowest_face_tri(KnifeTool_OpData *kcd, BMFace *f)
#define KNIFE_DEFAULT_ANGLE_SNAPPING_INCREMENT
static void knife_pos_data_clear(KnifePosData *kpd)
static void knife_constrain_axis(const KnifeTool_OpData *kcd, const float3 &ray_orig, const float3 &ray_dir, float3 &r_cage)
static void knifetool_draw_visible_angles(const KnifeTool_OpData *kcd)
static bool knife_add_single_cut__is_linehit_outside_face(BMFace *f, const KnifeLineHit *lh, const float co[3])
static int knife_update_active(KnifeTool_OpData *kcd, const float2 &mval)
static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
void EDBM_mesh_knife(ViewContext *vc, const Span< Object * > objects, LinkNode *polys, bool use_tag, bool cut_through)
static BMFace * knife_bvh_raycast_filter(KnifeTool_OpData *kcd, const float co[3], const float dir[3], const float radius, float *r_dist, float r_cagehit[3], int *r_ob_index, bool(*filter_cb)(BMFace *f, void *userdata), void *filter_userdata)
static void knife_reset_snap_angle_input(KnifeTool_OpData *kcd)
static KnifeVert * new_knife_vert(KnifeTool_OpData *kcd, const float co[3], const float cageco[3])
static void knifetool_finish_single_pre(KnifeTool_OpData *kcd, int ob_index)
@ KNF_MEASUREMENT_DISTANCE
static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits)
static void knifetool_draw(const bContext *, ARegion *, void *arg)
static void knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float2 &mval)
static const int * knife_bm_tri_index_get(const KnifeTool_OpData *kcd, int ob_index, int tri_index, int tri_index_buf[3])
static bool bm_ray_cast_cb_elem_not_in_face_check(BMFace *f, void *user_data)
static KnifeEdge * new_knife_edge(KnifeTool_OpData *kcd)
static bool knife_find_closest_edge_of_face(KnifeTool_OpData *kcd, int ob_index, BMFace *f, const float2 &curr_cage_ss, const float3 *curr_cage_constrain, const float3 &ray_orig, const float3 &ray_dir, KnifePosData *r_kpd)
static void knife_linehit_set(KnifeTool_OpData *kcd, float s1[2], float s2[2], float sco[2], float cage[3], int ob_index, KnifeVert *v, KnifeEdge *kfe, KnifeLineHit *r_hit)
static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, KnifeLineHit *lh2, BMFace *f)
static bool knife_snap_angle_screen(const KnifeTool_OpData *kcd, const float3 &ray_orig, const float3 &ray_dir, float3 &r_cage, float &r_angle)
#define KNIFE_FLT_EPS_PX_FACE
static void knife_bm_tri_cagecos_get(const KnifeTool_OpData *kcd, int ob_index, int tri_index, float cos[3][3])
static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
#define KNIFE_MIN_ANGLE_SNAPPING_INCREMENT
static bool knife_snap_angle_relative(KnifeTool_OpData *kcd, const float3 &ray_orig, const float3 &ray_dir, float3 &r_cage, float &r_angle)
static bool point_is_visible(KnifeTool_OpData *kcd, const float p[3], const float s[2], BMElem *ele_test)
static void knife_add_cut(KnifeTool_OpData *kcd)
static void knifetool_init_obinfo(KnifeTool_OpData *kcd, Object *ob, int ob_index, bool use_tri_indices)
static void knife_snap_curr(KnifeTool_OpData *kcd, const float2 &mval, const float3 &ray_orig, const float3 &ray_dir, const float3 *curr_cage_constrain, const float3 *fallback)
static void knifetool_finish(wmOperator *op)
@ KNF_CONSTRAIN_AXIS_NONE
static void knife_update_header(bContext *C, wmOperator *op, KnifeTool_OpData *kcd)
static void knife_append_list_no_dup(KnifeTool_OpData *kcd, ListBase *lst, void *elem)
static float knife_snap_v3_angle(float3 &r, const float3 &dvec, const float3 &vecx, const float3 &axis, float angle_snap)
#define KNIFE_FLT_EPS_SQUARED
static BMElem * bm_elem_from_knife_vert(KnifeVert *kfv, KnifeEdge **r_kfe)
static int sort_verts_by_dist_cb(void *co_p, const void *cur_a_p, const void *cur_b_p)
static KnifeEdge * get_bm_knife_edge(KnifeTool_OpData *kcd, BMEdge *e, int ob_index)
static void knifetool_disable_orientation_locking(KnifeTool_OpData *kcd)
static int knife_sample_screen_density_from_closest_face(KnifeTool_OpData *kcd, const float radius, int ob_index, BMFace *f, const float cageco[3])
static int linehit_compare(const KnifeLineHit &lh1, const KnifeLineHit &lh2)
static void knife_add_edge_faces_to_vert(KnifeTool_OpData *kcd, KnifeVert *kfv, BMEdge *e)
static void knife_start_cut(KnifeTool_OpData *kcd, const float2 &mval)
static bool coinciding_edges(BMEdge *e1, BMEdge *e2)
static bool knife_bm_face_is_select(BMFace *f)
static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
static wmOperatorStatus knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void knife_init_colors(KnifeColors *colors)
static void knifetool_exit_ex(KnifeTool_OpData *kcd)
static void set_lowest_face_tri(KnifeTool_OpData *kcd, BMEditMesh *em, BMFace *f, int index)
static KnifeVert * knife_split_edge(KnifeTool_OpData *kcd, KnifeEdge *kfe, const float co[3], const float cageco[3], KnifeEdge **r_kfe)
#define F_ISECT_IS_UNKNOWN(f)
struct @242053044010324116347033273112253060004051364061::@051143074301336237271216303350234260141112266062 batch
#define MEM_SIZE_OPTIMAL(size)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< float, 4 > float4
VecBase< float, 2 > float2
VecBase< float, 3 > float3
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
ARegionRuntimeHandle * runtime
blender::Array< std::array< BMLoop *, 3 > > looptris
struct BMLoop * radial_next
struct IsectRayPrecalc * isect_precalc
bool(* filter_cb)(BMFace *f, void *userdata)
blender::Span< std::array< BMLoop *, 3 > > looptris
Array< float3 > positions_cage
Array< int3 > tri_indices
MeshRuntimeHandle * runtime
struct ToolSettings * toolsettings
struct ReportList * reports
struct wmOperatorType * type
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_modal_restore(wmWindow *win)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
std::optional< std::string > WM_modalkeymap_operator_items_to_string(wmOperatorType *ot, const int propvalue, const bool compact)
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
void wmOrtho2_region_pixelspace(const ARegion *region)