12# define _USE_MATH_DEFINES
15#include <fmt/format.h>
75#define USE_NET_ISLAND_CONNECT
77#define KMAXDIST (10 * UI_SCALE_FAC)
82#define KNIFE_FLT_EPS 0.00001f
83#define KNIFE_FLT_EPS_SQUARED (KNIFE_FLT_EPS * KNIFE_FLT_EPS)
84#define KNIFE_FLT_EPSBIG 0.0005f
86#define KNIFE_FLT_EPS_PX_VERT 0.5f
87#define KNIFE_FLT_EPS_PX_EDGE 0.05f
88#define KNIFE_FLT_EPS_PX_FACE 0.05f
90#define KNIFE_DEFAULT_ANGLE_SNAPPING_INCREMENT 30.0f
91#define KNIFE_MIN_ANGLE_SNAPPING_INCREMENT 0.0f
92#define KNIFE_MAX_ANGLE_SNAPPING_INCREMENT 180.0f
172 return this->ob_index == -1;
239#ifdef USE_NET_ISLAND_CONNECT
384 kcd->
vc.
rv3d->
persmat, planes[2], planes[0], planes[1], planes[3],
nullptr,
nullptr);
393 float curr_cage_adjust[3];
402 for (i = 0; i < 4; i++) {
410 if (lambda_test < 0.0f) {
411 if (lambda_test > lambda_best[0]) {
413 lambda_best[0] = lambda_test;
417 if (lambda_test < lambda_best[1]) {
419 lambda_best[1] = lambda_test;
502 float numstr_size[2];
505 const float font_size = 14.0f;
506 const int distance_precision = 4;
513 SNPRINTF(numstr,
"%.*f", distance_precision, cut_len);
518 double(cut_len * unit->scale_length),
532 posit[0] -= numstr_size[0] / 2.0f;
533 posit[1] -= numstr_size[1] / 2.0f;
536 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
541 posit[0] - bg_margin,
542 posit[1] - bg_margin,
543 posit[0] + bg_margin + numstr_size[0],
544 posit[1] + bg_margin + numstr_size[1]);
562 const float start[3],
565 const float start_ss[2],
566 const float mid_ss[2],
567 const float end_ss[2],
571 const int arc_steps = 24;
575 const float font_size = 14.0f;
576 const int angle_precision = 3;
596 const float inverse_average_scale = 1 / (ob->object_to_world().ptr()[0][0] +
597 ob->object_to_world().ptr()[1][1] +
598 ob->object_to_world().ptr()[2][2]);
600 const float px_scale =
601 3.0f * inverse_average_scale *
621 for (
int j = 0; j <= arc_steps; j++) {
644 float numstr_size[2];
653 numstr,
sizeof(numstr),
double(angle), angle_precision,
B_UNIT_ROTATION, unit,
false);
661 posit[0] = mid_ss[0] + (cap_size * 2.0f);
662 posit[1] = mid_ss[1] - (numstr_size[1] / 2.0f);
665 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
670 posit[0] - bg_margin,
671 posit[1] - bg_margin,
672 posit[0] + bg_margin + numstr_size[0],
673 posit[1] + bg_margin + numstr_size[1]);
709 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
710 if (tempkfe->
v1 != kfv) {
711 tempkfv = tempkfe->
v1;
714 tempkfv = tempkfe->
v2;
717 if (angle < min_angle) {
752 if (angle1 < angle2) {
779 if (kfe->
v1 != kfv) {
792 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
793 if (tempkfe->
v1 != kfv) {
794 tempkfv = tempkfe->
v1;
797 tempkfv = tempkfe->
v2;
800 if (angle < min_angle) {
842 if (angle1 < angle2) {
1029 if (total_hits > 0) {
1035 int other_verts_count = 0;
1036 int snapped_verts_count = 0;
1054 if (snapped_verts_count > 0) {
1062 if (other_verts_count > 0) {
1102 auto get_modal_key_str = [&](
int id) {
1126 const std::string angle = fmt::format(
1127 "{}: {:.2f}({:.2f}) ({}{}{}{})",
1128 IFACE_(
"Angle Constraint"),
1155 int tri_index_buf[3])
1161 const std::array<BMLoop *, 3> <ri = obinfo->
em->
looptris[tri_index];
1162 for (
int i = 0; i < 3; i++) {
1165 return tri_index_buf;
1176 for (
int i = 0; i < 3; i++) {
1188 for (
int i = 0; i < 3; i++) {
1215 bool (*test_fn)(
BMFace *);
1224 const float epsilon = FLT_EPSILON * 2.0f;
1228 BMFace *f_test =
nullptr, *f_test_prev =
nullptr;
1229 bool test_fn_ret =
false;
1238 if (f_test != f_test_prev) {
1239 test_fn_ret = test_fn(f_test);
1240 f_test_prev = f_test;
1248 tottri += ob_tottri;
1253 f_test_prev =
nullptr;
1254 test_fn_ret =
false;
1269 f_test = looptris[i][0]->f;
1270 if (f_test != f_test_prev) {
1271 test_fn_ret = test_fn(f_test);
1272 f_test_prev = f_test;
1279 float tri_cos[3][3];
1309 BMLoop *
const *ltri =
nullptr;
1319 for (; ob_index < kcd->
objects.
size(); ob_index++) {
1324 if (index < tottri) {
1337 float tri_cos[3][3];
1339 isect = (ray->radius > 0.0f ?
1341 ray->origin, ray->direction,
UNPACK3(tri_cos), &dist,
nullptr, ray->radius) :
1342#ifdef USE_KDOPBVH_WATERTIGHT
1344 ray->origin, ray->isect_precalc,
UNPACK3(tri_cos), &dist,
nullptr));
1349 if (isect && dist < hit->dist) {
1380 const float dist = r_dist ? *r_dist :
FLT_MAX;
1387 if (hit.index != -1 && hit.dist != dist) {
1415 bool (*filter_cb)(
BMFace *f,
void *userdata),
1416 void *filter_userdata)
1442 const float mval[2],
1457 float origin_ofs[3];
1458 float ray[3], ray_normal[3];
1470 bool v1_inside, v2_inside;
1471 bool v1_inface, v2_inface;
1474 if (!f || !v1 || !
v2) {
1487 v1_inface = (l1 !=
nullptr);
1488 v2_inface = (l2 !=
nullptr);
1493 if ((v1_inface && v2_inside) || (v2_inface && v1_inside) || (v1_inside && v2_inside)) {
1497 if (v1_inface && v2_inface) {
1531 if (r_kfe || ele_test ==
nullptr) {
1532 if (kfv->
v ==
nullptr) {
1534 kfe =
static_cast<KnifeEdge *
>(ref->data);
1546 if (ele_test ==
nullptr) {
1553 if (ele_test ==
nullptr) {
1568 if (ele_test ==
nullptr) {
1602 if (ref1->data == ref) {
1640 if (ref1->data == ref2->data) {
1641 return (
BMFace *)(ref1->data);
1677 const float *cageco;
1692 mul_v3_m4v3(cageco_ws, ob->object_to_world().ptr(), cageco);
1761 const float cageco[3],
1768 newkfe->
v1 = kfe->
v1;
1789 kfe->
v1 = newkfe->
v2;
1821 kfe->
v1 = newkfe->
v1;
1860 if (lh1.
l < lh2.
l) {
1863 if (lh1.
l > lh2.
l) {
1866 if (lh1.
m < lh2.
m) {
1869 if (lh1.
m > lh2.
m) {
1872 if (lh1.
v < lh2.
v) {
1875 if (lh1.
v > lh2.
v) {
1888 bool is_double =
false;
1901 for (
int i = 0; i < total_hits; i++) {
1903 if (lhi->
v ==
nullptr) {
1907 for (
int j = i - 1; j >= 0; j--) {
1915 if (lhi->
kfe == lhj->
kfe) {
1920 for (
int j = i + 1; j < total_hits; j++) {
1925 if ((lhj->
kfe && (lhi->
kfe == lhj->
kfe)) || (lhi->
v == lhj->
v)) {
1936 while (j < total_hits) {
1939 if (lhj->
l == -1.0f) {
1944 if (lhi->
l == -1.0f) {
1985 if (lh->
v && lh->
v->
v) {
1993 else if (lh->
kfe && lh->
kfe->
e) {
2013 if ((lh1->
v && lh1->
v == lh2->
v) || (lh1->
kfe && lh1->
kfe == lh2->
kfe)) {
2018 if ((lh1->
v && lh2->
v) && (lh1->
v->
v && lh2->
v && lh2->
v->
v) &&
2030 if ((lh1->
v && !lh1->
kfe) && (lh2->
v && !lh2->
kfe)) {
2043 else if (lh1->
kfe) {
2059 else if (lh2->
kfe) {
2115 bool is_new_edge =
false;
2116 kfe =
static_cast<KnifeEdge *
>(ref->data);
2122 if (kfe->
e ==
nullptr) {
2123 if (kfe->
v1->
v && kfe->
v2->
v) {
2135 if (kfe->
v1->
v ==
nullptr) {
2138 if (kfe->
v2->
v ==
nullptr) {
2154 kfe_array[i] = is_new_edge ? kfe :
nullptr;
2155 edge_array[i] = kfe->
e;
2161 const int edge_array_len_orig = i;
2164#ifdef USE_NET_ISLAND_CONNECT
2165 uint edge_array_holes_len;
2166 BMEdge **edge_array_holes;
2174 &edge_array_holes_len))
2177 for (i = edge_array_len; i < edge_array_holes_len; i++) {
2182 edge_array_len = edge_array_holes_len;
2183 edge_array = edge_array_holes;
2192 for (i = 0; i < edge_array_len_orig; i++) {
2193 if (kfe_array[i] ==
nullptr) {
2198 kfe_array[i]->
e =
nullptr;
2202#ifdef USE_NET_ISLAND_CONNECT
2214 const float *co =
static_cast<const float *
>(co_p);
2279 kfe =
static_cast<KnifeEdge *
>(ref->data);
2297 for (
auto [
e, list] : ehash.
items()) {
2301 kfv =
static_cast<KnifeVert *
>(ref->data);
2312 for (
auto [f, list] : fhash.
items()) {
2432 BLI_assert(index >= 0 && index < em->looptris.size());
2434 for (i = index - 1; i >= 0; i--) {
2472 const float face_tol_sq,
2474 float hit_cageco[3])
2481 float tri_norm[3], tri_plane[4];
2482 float se1[2], se2[2];
2493 for (; tri_i < tottri; tri_i++) {
2494 float tri_cos[3][3];
2495 float ray_tri_uv[2];
2497 const std::array<BMLoop *, 3> <ri = em->
looptris[tri_i];
2498 if (ltri[0]->f != f) {
2522 kfe =
static_cast<KnifeEdge *
>(ref->data);
2529 if (d < face_tol_sq) {
2550 float min[3], max[3];
2554 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2560 for (
int i = 0; i < em->
bm->
totvert; i++) {
2562 mul_m4_v3(ob->object_to_world().ptr(), ws);
2569 mul_m4_v3(ob->object_to_world().ptr(), ws);
2582 const float *co11, *co12, *co21, *co22;
2607 switch (((
BMElem *)user_data)->head.htype) {
2609 ans = (
BMFace *)user_data != f;
2660 float view[3], p_ofs[3];
2676 float view_clip[2][3];
2682 view_clip[0], view_clip[1], kcd->
vc.
rv3d->
clip_local, 6, view_clip[0], view_clip[1]))
2684 dist =
len_v3v3(p_ofs, view_clip[1]);
2716 float closest[3], dir[3];
2740 memset(r_hit, 0,
sizeof(*r_hit));
2794 float v1[3],
v2[3], v3[3], v4[3], s1[2], s2[2];
2798 float s[2], se1[2], se2[2];
2800 float vert_tol, vert_tol_sq;
2801 float line_tol, line_tol_sq;
2802 float face_tol, face_tol_sq;
2847 float v1_v2[3], v1_v3[3];
2871 for (i = 0, result = results; i < tot; i++, result++) {
2873 BMLoop *
const *ltri =
nullptr;
2874 for (ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2892 if (faces.contains(f)) {
2897 fobs.
add(f, ob_index);
2928 vert_tol = line_tol = face_tol = 0.5f;
2931 vert_tol_sq = vert_tol * vert_tol;
2932 line_tol_sq = line_tol * line_tol;
2933 face_tol_sq = face_tol * face_tol;
2942 bool kfv_is_in_cut =
false;
2949 kfv_is_in_cut =
true;
2954 if ((d <= vert_tol_sq) &&
2957 kfv_is_in_cut =
true;
2961 if (kfv_is_in_cut) {
2984 bool kfe_is_in_cut =
false;
2989 kfe_is_in_cut =
true;
2995 kfe_is_in_cut =
true;
2999 if (isect_kind == -1) {
3012 if (isect_kind == 1) {
3015 if (!(d1 <= line_tol || d2 <= line_tol ||
fabsf(d1 - d2) <= line_tol)) {
3024 kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_dummy);
3025 if (isect_kind >= 1 &&
3030 mid_v3_v3v3(p_cage, kfe->v1->cageco, kfe->v2->cageco);
3033 kfe_is_in_cut =
true;
3038 if (kfe_is_in_cut) {
3039 knife_linehit_set(kcd, s1, s2, p_cage_ss, p_cage, kfe->v1->ob_index,
nullptr, kfe, &hit);
3045 const bool use_hit_prev = (kcd->
prev.
vert ==
nullptr) && (kcd->
prev.
edge ==
nullptr);
3046 const bool use_hit_curr = (kcd->
curr.
vert ==
nullptr) && (kcd->
curr.
edge ==
nullptr) &&
3048 if (use_hit_prev || use_hit_curr) {
3050 int ob_index = fobs.
lookup(f);
3065 kcd->
linehits = std::move(linehits);
3079 kpd->
vert =
nullptr;
3080 kpd->
edge =
nullptr;
3093 const float3 &ray_origin,
3094 const float3 &ray_normal,
3103 f =
knife_bvh_raycast(kcd, ray_origin, ray_normal, 0.0f,
nullptr, cage, &ob_index);
3128 cage = ray_origin + ray_normal;
3156 const float radius_sq = radius * radius;
3173 for (i = 0; i < 2; i++) {
3184 if (dis_sq < radius_sq) {
3216 return density ?
min_ff(maxsize / (
float(density) * 0.5f), maxsize) : maxsize;
3225 const float3 &kfv1_cageco,
3226 const float3 &kfv2_cageco,
3249 const float3 &ray_origin,
3250 const float3 &ray_normal,
3251 const float2 &curr_cage_ss,
3267 const float maxdist_sq = maxdist * maxdist;
3268 float cur_dist_sq = maxdist_sq;
3269 bool has_hit =
false;
3275 float test_cagep[3];
3299 if (dis_sq >= cur_dist_sq) {
3310 cur_dist_sq = dis_sq;
3319 r_kpd->
mval = closest_ss;
3346 const float maxdist_sq = maxdist * maxdist;
3348 float cur_kfv_sco[2];
3349 float dis_sq, curdis_sq =
FLT_MAX;
3351 for (
int i = 0; i < 2; i++) {
3368 if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
3384 r_kpd->
mval = cur_kfv_sco;
3395static float snap_v2_angle(
float r[2],
const float v[2],
const float v_ref[2],
float angle_snap)
3399 float angle, angle_delta;
3405 angle_delta = (roundf(angle / angle_snap) * angle_snap) - angle;
3409 return angle + angle_delta;
3415 const float dvec_ref[2] = {1.0f, 0.0f};
3416 float dvec[2], dvec_snap[2];
3447 float r[3],
const float v[3],
const float v_ref[3],
const float plane_no[3],
float snap_step)
3450 float angle, angle_delta;
3453 angle_delta = (roundf(angle / snap_step) * snap_step) - angle;
3457 return angle + angle_delta;
3469 float curr_origin[3];
3470 float curr_origin_ofs[3];
3471 float curr_ray[3], curr_ray_normal[3];
3478 sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
3482 kcd, curr_origin, curr_ray_normal, 0.0f,
nullptr, curr_cage,
nullptr);
3527 f = ((
BMFace *)(ref->data));
3535 f = ((
BMFace *)(ref->data));
3543 float prev_origin[3];
3544 float prev_origin_ofs[3];
3545 float prev_ray[3], prev_ray_normal[3];
3550 sub_v3_v3v3(prev_ray, prev_origin_ofs, prev_origin);
3555 kcd, prev_origin, prev_ray_normal, 0.0f,
nullptr, prev_cage, &fprev_ob_index);
3558 if (!fprev || fprev != fcurr) {
3586 float rotated_vec[3];
3605 float curr_origin[3];
3606 float curr_origin_ofs[3];
3607 float curr_ray[3], curr_ray_normal[3];
3611 sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
3615 kcd, curr_origin, curr_ray_normal, 0.0f,
nullptr, curr_cage,
nullptr);
3660 float curr_cage_adjusted[3];
3671 const short orientation_type = scene_orientation ? scene_orientation :
3673 const int pivot_point = scene->toolsettings->transform_pivot_point;
3676 scene, view_layer, kcd->
vc.
v3d, rv3d, obedit, obedit, orientation_type, pivot_point, mat);
3684 for (
int i = 0; i <= 2; i++) {
3687 co[2][i] = co[0][i];
3696 float curr_screenspace[2];
3697 float prev_screenspace[2];
3700 float intersection[2];
3723 kcd, kpos_tmp.
ob_index, kpos_tmp.
bmface, ray_origin, ray_normal, mval, &kpos_tmp))
3726 kcd->
curr = kpos_tmp;
3745 float origin_ofs[3];
3817 for (
int i = 0; i < undo->
splits; i++) {
3823 for (
int i = 0; i < undo->
cuts; i++) {
3847 kfe =
static_cast<KnifeEdge *
>(ref->data);
3856 if (!
v2->is_invalid && !
v2->is_splitting) {
3857 v2->is_invalid =
true;
3860 kfe =
static_cast<KnifeEdge *
>(ref->data);
3862 v2->is_invalid =
false;
3890 bool use_tri_indices)
3900 obinfo->
em = em_eval;
3902 kcd->
vc.
depsgraph, em_eval, scene_eval, obedit_eval);
3904 if (use_tri_indices) {
3907 const std::array<BMLoop *, 3> <ri = em_eval->
looptris[i];
3931 colors->curpoint_a[3] = 102;
3934 colors->point_a[3] = 102;
3946 const bool only_select,
3947 const bool cut_through,
3949 const int visible_measurements,
3950 const int angle_snapping,
3951 const float angle_snapping_increment,
3952 const bool is_interactive)
3956 bool use_tri_indices = !is_interactive;
3966 kcd->
objects = std::move(objects);
3971 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
3993#ifdef USE_NET_ISLAND_CONNECT
4020 if (is_interactive) {
4068#ifdef USE_NET_ISLAND_CONNECT
4119 const float mval[2] = {
float(mval_i[0]),
float(mval_i[1])};
4143 params.calc_looptris =
true;
4144 params.calc_normals =
true;
4145 params.is_destructive =
true;
4193 "CYCLE_ANGLE_SNAP_EDGE",
4195 "Cycle Angle Snapping Relative Edge",
4199 "SHOW_DISTANCE_ANGLE_TOGGLE",
4201 "Toggle Distance and Angle Measurements",
4211 {0,
nullptr, 0,
nullptr,
nullptr},
4247 bool do_refresh =
false;
4264 bool handled =
false;
4265 float snapping_increment_temp;
4293 switch (event->
val) {
4303 const bool changed = (kcd->
totkvert != 0);
4508 switch (event->
type) {
4594 op->
flag &= ~OP_IS_MODAL_CURSOR_REGION;
4616 const int visible_measurements =
RNA_enum_get(op->
ptr,
"visible_measurements");
4619 const float angle_snapping_increment =
RAD2DEGF(
4634 visible_measurements,
4636 angle_snapping_increment,
4640 bool faces_selected =
false;
4644 faces_selected =
true;
4648 if (!faces_selected) {
4661 if (wait_for_input ==
false) {
4683 ot->
name =
"Knife Topology Tool";
4703 {0,
nullptr, 0,
nullptr,
nullptr},
4713 "Angle snapping relative to the previous cut edge"},
4714 {0,
nullptr, 0,
nullptr,
nullptr},
4718 "use_occlude_geometry",
4721 "Only cut the front most geometry");
4726 "visible_measurements",
4727 visible_measurements_items,
4730 "Visible distance and angle measurements");
4733 angle_snapping_items,
4736 "Angle snapping mode");
4740 "angle_snapping_increment",
4744 "Angle Snap Increment",
4745 "The angle snap increment used when in constrained angle mode",
4768 const float(*mval_fl)[2] =
static_cast<const float(*)[2]
>(p->
link);
4787 const bool only_select =
false;
4788 const bool is_interactive =
false;
4789 const bool xray =
false;
4794 kcd = MEM_new<KnifeTool_OpData>(__func__);
4802 visible_measurements,
4804 angle_snapping_increment,
4818 const float(*mval_fl)[2] =
static_cast<const float(*)[2]
>(p->
link);
4825 for (i = 1; i < mval_tot; i++) {
4861#define F_ISECT_IS_UNKNOWN(f) BM_elem_flag_test(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4862#define F_ISECT_SET_UNKNOWN(f) BM_elem_flag_enable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4863#define F_ISECT_SET_OUTSIDE(f) BM_elem_flag_disable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4882 float cent[3], cent_ss[2];
4884 mul_m4_v3(ob->object_to_world().ptr(), cent);
4895 keep_search =
false;
4904 BMLoop *l_iter = l_first;
4911 if (l_radial_iter != l_iter) {
4916 }
while ((l_radial_iter = l_radial_iter->
radial_next) != l_iter &&
4920 }
while ((l_iter = l_iter->
next) != l_first && (found ==
false));
4923 float cent[3], cent_ss[2];
4925 mul_m4_v3(ob->object_to_world().ptr(), cent);
4939 }
while (keep_search);
4941#undef F_ISECT_IS_UNKNOWN
4942#undef F_ISECT_SET_UNKNOWN
4943#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_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)
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)
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(struct ListBase *lb)
int BLI_listbase_count_at_most(const struct ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void BLI_listbase_sort_r(ListBase *listbase, int(*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_ASSERT_UNIT_V2(v)
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_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, bool clip)
int isect_line_line_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float r_i1[3], float r_i2[3])
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)
bool isect_ray_plane_v3_factor(const float ray_origin[3], const float ray_direction[3], const float plane_co[3], const float plane_no[3], float *r_lambda)
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])
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
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)
void planes_from_projmat(const float mat[4][4], float left[4], float right[4], float bottom[4], float top[4], float near[4], float far[4])
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
void mul_m3_m3_pre(float R[3][3], const float A[3][3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
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])
bool invert_m3(float mat[3][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])
void angle_to_mat2(float R[2][2], float angle)
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], float angle)
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)
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
float angle_signed_v2v2(const float v1[2], const float v2[2]) 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 add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
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])
MINLINE float normalize_v2_v2(float r[2], const float a[2])
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])
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void 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
ID * DEG_get_evaluated_id(const Depsgraph *depsgraph, ID *id)
Object is a sort of wrapper for general info.
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
@ OP_IS_MODAL_CURSOR_REGION
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_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[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)
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_UNIFORM_COLOR
void GPU_blend(eGPUBlend blend)
void GPU_line_width(float width)
void GPU_point_size(float size)
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.
#define MEM_SIZE_OPTIMAL(size)
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)
ATTR_WARN_UNUSED_RESULT BMesh * bm
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.
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
void item(std::string text, int icon1, int icon2=0)
void opmodal(std::string text, const wmOperatorType *ot, int propvalue, bool inverted=false)
void reinitialize(const int64_t new_size)
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)
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
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 int knife_calculate_snap_ref_edges(KnifeTool_OpData *kcd)
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 void knife_snap_curr(KnifeTool_OpData *kcd, const float2 &mval)
static bool knife_snap_angle_screen(KnifeTool_OpData *kcd)
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
static void knife_constrain_axis(KnifeTool_OpData *kcd)
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 bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
static float snap_v3_angle_plane(float r[3], const float v[3], const float v_ref[3], const float plane_no[3], float snap_step)
static void knifetool_draw_visible_distances(const KnifeTool_OpData *kcd)
static ListBase * knife_empty_list(KnifeTool_OpData *kcd)
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)
static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
@ 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 bool knife_find_closest_edge_of_face(KnifeTool_OpData *kcd, int ob_index, BMFace *f, const float3 &ray_origin, const float3 &ray_normal, const float2 &curr_cage_ss, KnifePosData *r_kpd)
#define KNIFE_FLT_EPS_PX_EDGE
static bool knife_closest_constrain_to_edge(KnifeTool_OpData *kcd, const float3 &kfv1_cageco, const float3 &kfv2_cageco, float r_close[3])
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 int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
static bool knife_bm_face_is_not_hidden(BMFace *f)
static void knifetool_exit(wmOperator *op)
wmKeyMap * knifetool_modal_keymap(wmKeyConfig *keyconf)
static void knife_finish_cut(KnifeTool_OpData *kcd)
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)
#define KNIFE_MAX_ANGLE_SNAPPING_INCREMENT
static void knife_join_edge(KnifeEdge *newkfe, KnifeEdge *kfe)
@ KNF_MEASUREMENT_DISTANCE
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 knifetool_raycast_planes(const KnifeTool_OpData *kcd, float r_v1[3], float r_v2[3])
static void knife_pos_data_clear(KnifePosData *kpd)
static void knifetool_draw_visible_angles(const KnifeTool_OpData *kcd)
static void knife_snap_update_from_mval(KnifeTool_OpData *kcd, const float mval[2])
static bool knife_add_single_cut__is_linehit_outside_face(BMFace *f, const KnifeLineHit *lh, const float co[3])
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 float snap_v2_angle(float r[2], const float v[2], const float v_ref[2], float angle_snap)
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)
static void knife_cut_face(KnifeTool_OpData *kcd, BMFace *f, ListBase *hits)
static void knifetool_draw(const bContext *, ARegion *, void *arg)
static const int * knife_bm_tri_index_get(const KnifeTool_OpData *kcd, int ob_index, int tri_index, int tri_index_buf[3])
static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2], float r_origin[3], float r_end[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 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)
@ KNF_CONSTRAIN_ANGLE_MODE_NONE
@ KNF_CONSTRAIN_ANGLE_MODE_SCREEN
@ KNF_CONSTRAIN_ANGLE_MODE_RELATIVE
static void knife_add_single_cut(KnifeTool_OpData *kcd, KnifeLineHit *lh1, KnifeLineHit *lh2, BMFace *f)
static int knife_update_active(KnifeTool_OpData *kcd)
#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 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 knifetool_finish(wmOperator *op)
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)
#define KNIFE_FLT_EPS_SQUARED
static bool knife_find_closest_face(KnifeTool_OpData *kcd, const float3 &ray_origin, const float3 &ray_normal, const float2 &mval, KnifePosData *r_kpd)
static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
static BMElem * bm_elem_from_knife_vert(KnifeVert *kfv, KnifeEdge **r_kfe)
@ KNF_CONSTRAIN_AXIS_MODE_LOCAL
@ KNF_CONSTRAIN_AXIS_MODE_GLOBAL
@ KNF_CONSTRAIN_AXIS_MODE_NONE
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])
@ KNF_CONSTRAIN_AXIS_NONE
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)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float3 cos(float3 v)
VecBase< float, 2 > float2
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)
struct ARegionType * type
blender::Array< std::array< BMLoop *, 3 > > looptris
struct BMLoop * radial_next
bool(* filter_cb)(BMFace *f, void *userdata)
blender::Span< std::array< BMLoop *, 3 > > looptris
Array< float3 > positions_cage
Array< int3 > tri_indices
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
void(* cancel)(bContext *C, wmOperator *op)
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)