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
394 immVertexFormat(),
"pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
448 float numstr_size[2];
451 const float font_size = 14.0f;
452 const int distance_precision = 4;
463 numstr,
sizeof(numstr), cut_len, distance_precision,
B_UNIT_LENGTH, unit,
false);
473 posit[0] -= numstr_size[0] / 2.0f;
474 posit[1] -= numstr_size[1] / 2.0f;
477 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
482 posit[0] - bg_margin,
483 posit[1] - bg_margin,
484 posit[0] + bg_margin + numstr_size[0],
485 posit[1] + bg_margin + numstr_size[1]);
503 const float start[3],
506 const float start_ss[2],
507 const float mid_ss[2],
508 const float end_ss[2],
512 const int arc_steps = 24;
516 const float font_size = 14.0f;
517 const int angle_precision = 3;
523 immVertexFormat(),
"pos", blender::gpu::VertAttrType::SFLOAT_32_32_32);
537 const float inverse_average_scale = 1 / (ob->object_to_world().
ptr()[0][0] +
538 ob->object_to_world().ptr()[1][1] +
539 ob->object_to_world().ptr()[2][2]);
541 const float px_scale =
542 3.0f * inverse_average_scale *
562 for (
int j = 0; j <= arc_steps; j++) {
585 float numstr_size[2];
602 posit[0] = mid_ss[0] + (cap_size * 2.0f);
603 posit[1] = mid_ss[1] - (numstr_size[1] / 2.0f);
606 float color_back[4] = {0.0f, 0.0f, 0.0f, 0.5f};
611 posit[0] - bg_margin,
612 posit[1] - bg_margin,
613 posit[0] + bg_margin + numstr_size[0],
614 posit[1] + bg_margin + numstr_size[1]);
650 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
651 if (tempkfe->
v1 != kfv) {
652 tempkfv = tempkfe->
v1;
655 tempkfv = tempkfe->
v2;
658 if (
angle < min_angle) {
693 if (angle1 < angle2) {
720 if (kfe->
v1 != kfv) {
733 tempkfe =
static_cast<KnifeEdge *
>(ref->data);
734 if (tempkfe->
v1 != kfv) {
735 tempkfv = tempkfe->
v1;
738 tempkfv = tempkfe->
v2;
741 if (
angle < min_angle) {
783 if (angle1 < angle2) {
989 if (total_hits > 0) {
995 int other_verts_count = 0;
996 int snapped_verts_count = 0;
1015 if (snapped_verts_count > 0) {
1024 if (other_verts_count > 0) {
1064 auto get_modal_key_str = [&](
int id) {
1088 const std::string
angle = fmt::format(
1089 "{}: {:.2f}({:.2f}) ({}{}{}{})",
1090 IFACE_(
"Angle Constraint"),
1117 int tri_index_buf[3])
1123 const std::array<BMLoop *, 3> <ri = obinfo->
em->
looptris[tri_index];
1124 for (
int i = 0;
i < 3;
i++) {
1127 return tri_index_buf;
1138 for (
int i = 0;
i < 3;
i++) {
1150 for (
int i = 0;
i < 3;
i++) {
1177 bool (*test_fn)(
BMFace *);
1186 const float epsilon = FLT_EPSILON * 2.0f;
1190 BMFace *f_test =
nullptr, *f_test_prev =
nullptr;
1191 bool test_fn_ret =
false;
1200 if (f_test != f_test_prev) {
1201 test_fn_ret = test_fn(f_test);
1202 f_test_prev = f_test;
1210 tottri += ob_tottri;
1215 f_test_prev =
nullptr;
1216 test_fn_ret =
false;
1231 f_test = looptris[
i][0]->f;
1232 if (f_test != f_test_prev) {
1233 test_fn_ret = test_fn(f_test);
1234 f_test_prev = f_test;
1241 float tri_cos[3][3];
1271 BMLoop *
const *ltri =
nullptr;
1281 for (; ob_index < kcd->
objects.
size(); ob_index++) {
1286 if (index < tottri) {
1299 float tri_cos[3][3];
1301 isect = (ray->
radius > 0.0f ?
1304#ifdef USE_KDOPBVH_WATERTIGHT
1311 if (isect && dist < hit->dist) {
1342 const float dist = r_dist ? *r_dist :
FLT_MAX;
1349 if (hit.
index != -1 && hit.
dist != dist) {
1377 bool (*filter_cb)(
BMFace *f,
void *userdata),
1378 void *filter_userdata)
1404 const float mval[2],
1419 float origin_ofs[3];
1420 float ray[3], ray_normal[3];
1432 bool v1_inside, v2_inside;
1433 bool v1_inface, v2_inface;
1436 if (!f || !v1 || !
v2) {
1449 v1_inface = (l1 !=
nullptr);
1450 v2_inface = (l2 !=
nullptr);
1455 if ((v1_inface && v2_inside) || (v2_inface && v1_inside) || (v1_inside && v2_inside)) {
1459 if (v1_inface && v2_inface) {
1493 if (r_kfe || ele_test ==
nullptr) {
1494 if (kfv->
v ==
nullptr) {
1496 kfe =
static_cast<KnifeEdge *
>(ref->data);
1508 if (ele_test ==
nullptr) {
1515 if (ele_test ==
nullptr) {
1530 if (ele_test ==
nullptr) {
1564 if (ref1->data == ref) {
1602 if (ref1->data == ref2->data) {
1603 return (
BMFace *)(ref1->data);
1639 const float *cageco;
1654 mul_v3_m4v3(cageco_ws, ob->object_to_world().ptr(), cageco);
1723 const float cageco[3],
1730 newkfe->
v1 = kfe->
v1;
1751 kfe->
v1 = newkfe->
v2;
1783 kfe->
v1 = newkfe->
v1;
1800 const float3 *curr_cage_constrain,
1832 if (lh1.
l < lh2.
l) {
1835 if (lh1.
l > lh2.
l) {
1838 if (lh1.
m < lh2.
m) {
1841 if (lh1.
m > lh2.
m) {
1844 if (lh1.
v < lh2.
v) {
1847 if (lh1.
v > lh2.
v) {
1860 bool is_double =
false;
1873 for (
int i = 0;
i < total_hits;
i++) {
1875 if (lhi->
v ==
nullptr) {
1879 for (
int j =
i - 1; j >= 0; j--) {
1887 if (lhi->
kfe == lhj->
kfe) {
1892 for (
int j =
i + 1; j < total_hits; j++) {
1897 if ((lhj->
kfe && (lhi->
kfe == lhj->
kfe)) || (lhi->
v == lhj->
v)) {
1908 while (j < total_hits) {
1911 if (lhj->
l == -1.0f) {
1916 if (lhi->
l == -1.0f) {
1957 if (lh->
v && lh->
v->
v) {
1965 else if (lh->
kfe && lh->
kfe->
e) {
1985 if ((lh1->
v && lh1->
v == lh2->
v) || (lh1->
kfe && lh1->
kfe == lh2->
kfe)) {
1990 if ((lh1->
v && lh2->
v) && (lh1->
v->
v && lh2->
v && lh2->
v->
v) &&
2002 if ((lh1->
v && !lh1->
kfe) && (lh2->
v && !lh2->
kfe)) {
2015 else if (lh1->
kfe) {
2031 else if (lh2->
kfe) {
2087 bool is_new_edge =
false;
2088 kfe =
static_cast<KnifeEdge *
>(ref->data);
2094 if (kfe->
e ==
nullptr) {
2095 if (kfe->
v1->
v && kfe->
v2->
v) {
2107 if (kfe->
v1->
v ==
nullptr) {
2110 if (kfe->
v2->
v ==
nullptr) {
2126 kfe_array[
i] = is_new_edge ? kfe :
nullptr;
2127 edge_array[
i] = kfe->
e;
2133 const int edge_array_len_orig =
i;
2136#ifdef USE_NET_ISLAND_CONNECT
2137 uint edge_array_holes_len;
2138 BMEdge **edge_array_holes;
2146 &edge_array_holes_len))
2149 for (
i = edge_array_len;
i < edge_array_holes_len;
i++) {
2154 edge_array_len = edge_array_holes_len;
2155 edge_array = edge_array_holes;
2164 for (
i = 0;
i < edge_array_len_orig;
i++) {
2165 if (kfe_array[
i] ==
nullptr) {
2170 kfe_array[
i]->
e =
nullptr;
2174#ifdef USE_NET_ISLAND_CONNECT
2186 const float *co =
static_cast<const float *
>(co_p);
2251 kfe =
static_cast<KnifeEdge *
>(ref->data);
2269 for (
auto [
e, list] : ehash.
items()) {
2273 kfv =
static_cast<KnifeVert *
>(ref->data);
2284 for (
auto [f, list] : fhash.
items()) {
2404 BLI_assert(index >= 0 && index < em->looptris.size());
2406 for (
i = index - 1;
i >= 0;
i--) {
2444 const float face_tol_sq,
2446 float hit_cageco[3])
2453 float tri_norm[3], tri_plane[4];
2454 float se1[2], se2[2];
2465 for (; tri_i < tottri; tri_i++) {
2466 float tri_cos[3][3];
2467 float ray_tri_uv[2];
2469 const std::array<BMLoop *, 3> <ri = em->
looptris[tri_i];
2470 if (ltri[0]->f != f) {
2494 kfe =
static_cast<KnifeEdge *
>(ref->data);
2501 if (d < face_tol_sq) {
2526 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2534 mul_m4_v3(ob->object_to_world().ptr(), ws);
2541 mul_m4_v3(ob->object_to_world().ptr(), ws);
2554 const float *co11, *co12, *co21, *co22;
2579 switch (((
BMElem *)user_data)->head.htype) {
2581 ans = (
BMFace *)user_data != f;
2632 float view[3], p_ofs[3];
2648 float view_clip[2][3];
2654 view_clip[0], view_clip[1], kcd->
vc.
rv3d->
clip_local, 6, view_clip[0], view_clip[1]))
2656 dist =
len_v3v3(p_ofs, view_clip[1]);
2712 memset(r_hit, 0,
sizeof(*r_hit));
2771 float s[2], se1[2], se2[2];
2773 float vert_tol, vert_tol_sq;
2774 float line_tol, line_tol_sq;
2775 float face_tol, face_tol_sq;
2832 BMLoop *
const *ltri =
nullptr;
2833 for (ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
2851 if (
faces.contains(f)) {
2856 fobs.
add(f, ob_index);
2887 vert_tol = line_tol = face_tol = 0.5f;
2890 vert_tol_sq = vert_tol * vert_tol;
2891 line_tol_sq = line_tol * line_tol;
2892 face_tol_sq = face_tol * face_tol;
2901 bool kfv_is_in_cut =
false;
2908 kfv_is_in_cut =
true;
2913 if ((d <= vert_tol_sq) &&
2916 kfv_is_in_cut =
true;
2920 if (kfv_is_in_cut) {
2943 bool kfe_is_in_cut =
false;
2948 kfe_is_in_cut =
true;
2954 kfe_is_in_cut =
true;
2958 if (isect_kind == -1) {
2971 if (isect_kind == 1) {
2974 if (!(d1 <= line_tol || d2 <= line_tol ||
fabsf(d1 - d2) <= line_tol)) {
2978 float3 kfe_dir = kfe->v2->cageco - kfe->v1->cageco;
2980 p_cage = kfe->v1->cageco + kfe_dir * lambda;
2984 mid_v3_v3v3(p_cage, kfe->v1->cageco, kfe->v2->cageco);
2987 kfe_is_in_cut =
true;
2993 if (kfe_is_in_cut) {
2994 knife_linehit_set(kcd, s1, s2, p_cage_ss, p_cage, kfe->v1->ob_index,
nullptr, kfe, &hit);
3000 const bool use_hit_prev = (kcd->
prev.
vert ==
nullptr) && (kcd->
prev.
edge ==
nullptr);
3001 const bool use_hit_curr = (kcd->
curr.
vert ==
nullptr) && (kcd->
curr.
edge ==
nullptr) &&
3003 if (use_hit_prev || use_hit_curr) {
3028 int ob_index = fobs.
lookup(f);
3043 kcd->
linehits = std::move(linehits);
3057 kpd->
vert =
nullptr;
3058 kpd->
edge =
nullptr;
3095 vc.
mval[0] = int(mval[0]);
3096 vc.
mval[1] = int(mval[1]);
3106 cage = ray_orig + ray_dir;
3134 const float radius_sq = radius * radius;
3151 for (
i = 0;
i < 2;
i++) {
3162 if (dis_sq < radius_sq) {
3194 return density ?
min_ff(maxsize / (
float(density) * 0.5f), maxsize) : maxsize;
3204 const float3 &kfv1_cageco,
3205 const float3 &kfv2_cageco,
3210 if (!
isect_ray_line_v3(cut_origin, cut_dir, kfv1_cageco, kfv2_cageco, &lambda)) {
3227 const float2 &curr_cage_ss,
3228 const float3 *curr_cage_constrain,
3246 const float maxdist_sq = maxdist * maxdist;
3247 float cur_dist_sq = maxdist_sq;
3248 bool has_hit =
false;
3252 (curr_cage_constrain ? *curr_cage_constrain : kcd->
curr.
cage) - kcd->
prev.
cage);
3258 float test_cagep[3];
3283 if (dis_sq >= cur_dist_sq) {
3294 cur_dist_sq = dis_sq;
3303 r_kpd->
mval = closest_ss;
3330 const float maxdist_sq = maxdist * maxdist;
3332 float cur_kfv_sco[2];
3333 float dis_sq, curdis_sq =
FLT_MAX;
3335 for (
int i = 0;
i < 2;
i++) {
3352 if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
3369 r_kpd->
mval = cur_kfv_sco;
3384 const float angle_delta = (
roundf(
angle / angle_snap) * angle_snap) -
angle;
3386 return angle + angle_delta;
3397 float3 curr_cage_projected;
3399 curr_cage_projected, ray_orig, ray_orig + ray_dir, kcd->
prev.
cage, axis))
3421 r_cage = kcd->
prev.
cage + dvec_snap;
3508 float3 prev_ray_orig, prev_ray_dir;
3519 kcd, prev_ray_orig, prev_ray_dir, 0.0f,
nullptr,
nullptr, &fprev_ob_index);
3522 if (!fprev || fprev != fcurr) {
3596 const short orientation_type = scene_orientation ? scene_orientation :
3601 scene, view_layer, kcd->
vc.
v3d, rv3d, obedit, obedit, orientation_type, pivot_point, mat);
3611 float3 cage_dir = constrain_dir * lambda;
3616 r_cage = kcd->
prev.
cage + cage_dir;
3628 const float3 *curr_cage_constrain,
3640 curr_cage_constrain,
3646 kcd->
curr = kpos_tmp;
3693 float2 mval_constrain = mval;
3702 bool is_constrained =
false;
3720 is_constrained =
true;
3724 is_constrained =
true;
3729 float3 curr_cage_constrain;
3730 if (is_constrained) {
3744 curr_cage_constrain = kcd->
curr.
cage;
3752 is_constrained ? &curr_cage_constrain :
nullptr,
3753 is_constrained ? &fallback :
nullptr);
3773 for (
int i = 0;
i < undo->
splits;
i++) {
3779 for (
int i = 0;
i < undo->
cuts;
i++) {
3803 kfe =
static_cast<KnifeEdge *
>(ref->data);
3812 if (!
v2->is_invalid && !
v2->is_splitting) {
3813 v2->is_invalid =
true;
3816 kfe =
static_cast<KnifeEdge *
>(ref->data);
3818 v2->is_invalid =
false;
3846 bool use_tri_indices)
3850 const Mesh &mesh_orig = *
static_cast<const Mesh *
>(ob->
data);
3851 const Mesh &mesh_eval = *
static_cast<const Mesh *
>(obedit_eval->
data);
3857 obinfo->
em = &em_eval;
3859 kcd->
vc.
depsgraph, &em_eval, scene_eval, obedit_eval);
3862 obinfo->
em = mesh_orig.
runtime->edit_mesh.get();
3868 if (use_tri_indices) {
3871 const std::array<BMLoop *, 3> <ri = obinfo->
em->
looptris[
i];
3910 const bool only_select,
3911 const bool cut_through,
3913 const int visible_measurements,
3914 const int angle_snapping,
3915 const float angle_snapping_increment,
3916 const bool is_interactive)
3920 bool use_tri_indices = !is_interactive;
3930 kcd->
objects = std::move(objects);
3935 for (
int ob_index = 0; ob_index < kcd->
objects.
size(); ob_index++) {
3957#ifdef USE_NET_ISLAND_CONNECT
3984 if (is_interactive) {
4032#ifdef USE_NET_ISLAND_CONNECT
4102 params.calc_looptris =
true;
4103 params.calc_normals =
true;
4104 params.is_destructive =
true;
4152 "CYCLE_ANGLE_SNAP_EDGE",
4154 "Cycle Angle Snapping Relative Edge",
4158 "SHOW_DISTANCE_ANGLE_TOGGLE",
4160 "Toggle Distance and Angle Measurements",
4170 {0,
nullptr, 0,
nullptr,
nullptr},
4206 bool do_refresh =
false;
4223 bool handled =
false;
4224 float snapping_increment_temp;
4253 switch (event->
val) {
4263 const bool changed = (kcd->
totkvert != 0);
4456 switch (event->
type) {
4567 const int visible_measurements =
RNA_enum_get(op->
ptr,
"visible_measurements");
4570 const float angle_snapping_increment =
RAD2DEGF(
4585 visible_measurements,
4587 angle_snapping_increment,
4591 bool faces_selected =
false;
4595 faces_selected =
true;
4599 if (!faces_selected) {
4612 if (wait_for_input ==
false) {
4635 ot->name =
"Knife Topology Tool";
4636 ot->idname =
"MESH_OT_knife_tool";
4637 ot->description =
"Cut new topology";
4655 {0,
nullptr, 0,
nullptr,
nullptr},
4665 "Angle snapping relative to the previous cut edge"},
4666 {0,
nullptr, 0,
nullptr,
nullptr},
4670 "use_occlude_geometry",
4673 "Only cut the front most geometry");
4674 RNA_def_boolean(
ot->srna,
"only_selected",
false,
"Only Selected",
"Only cut selected geometry");
4675 RNA_def_boolean(
ot->srna,
"xray",
true,
"X-Ray",
"Show cuts hidden by geometry");
4678 "visible_measurements",
4679 visible_measurements_items,
4682 "Visible distance and angle measurements");
4685 angle_snapping_items,
4688 "Angle snapping mode");
4692 "angle_snapping_increment",
4696 "Angle Snap Increment",
4697 "The angle snap increment used when in constrained angle mode",
4720 const float (*mval_fl)[2] =
static_cast<const float (*)[2]
>(p->
link);
4739 const bool only_select =
false;
4740 const bool is_interactive =
false;
4741 const bool xray =
false;
4746 kcd = MEM_new<KnifeTool_OpData>(__func__);
4754 visible_measurements,
4756 angle_snapping_increment,
4770 const float (*mval_fl)[2] =
static_cast<const float (*)[2]
>(p->
link);
4777 for (
i = 1;
i < mval_tot;
i++) {
4813#define F_ISECT_IS_UNKNOWN(f) BM_elem_flag_test(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4814#define F_ISECT_SET_UNKNOWN(f) BM_elem_flag_enable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4815#define F_ISECT_SET_OUTSIDE(f) BM_elem_flag_disable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
4834 float cent[3], cent_ss[2];
4836 mul_m4_v3(ob->object_to_world().ptr(), cent);
4847 keep_search =
false;
4856 BMLoop *l_iter = l_first;
4863 if (l_radial_iter != l_iter) {
4868 }
while ((l_radial_iter = l_radial_iter->
radial_next) != l_iter &&
4872 }
while ((l_iter = l_iter->
next) != l_first && (found ==
false));
4875 float cent[3], cent_ss[2];
4877 mul_m4_v3(ob->object_to_world().ptr(), cent);
4891 }
while (keep_search);
4893#undef F_ISECT_IS_UNKNOWN
4894#undef F_ISECT_SET_UNKNOWN
4895#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_enable(int fontid, FontFlags flag)
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_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_disable(int fontid, FontFlags flag)
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)
MINLINE 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_UTF8(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)
bool EDBM_uvselect_clear(BMEditMesh *em)
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)
#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, GPUBuiltinShader shader_id)
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, GPUBatchFlag owns_flag)
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_line_width(float width)
void GPU_blend(GPUBlend blend)
void GPU_depth_test(GPUDepthTest test)
static blender::gpu::VertBuf * GPU_vertbuf_create_with_format(const GPUVertFormat &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)
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
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)
@ KNF_CONSTRAIN_ANGLE_MODE_NONE
@ KNF_CONSTRAIN_ANGLE_MODE_SCREEN
@ KNF_CONSTRAIN_ANGLE_MODE_RELATIVE
static bool knife_find_closest_face(KnifeTool_OpData *kcd, const float2 &mval, const float3 &ray_orig, const float3 &ray_dir, KnifePosData *r_kpd)
@ 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 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
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
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_AXIS_NONE
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)
@ KNF_MEASUREMENT_DISTANCE
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)
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)
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)
@ 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])
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 @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
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, 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)