Blender V4.3
view3d_iterators.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "DNA_curve_types.h"
11#include "DNA_lattice_types.h"
12#include "DNA_meta_types.h"
13#include "DNA_object_types.h"
14#include "DNA_scene_types.h"
15
16#include "BLI_math_geom.h"
17#include "BLI_rect.h"
18#include "BLI_utildefines.h"
19
20#include "BKE_action.hh"
21#include "BKE_armature.hh"
22#include "BKE_attribute.hh"
23#include "BKE_curve.hh"
24#include "BKE_displist.h"
25#include "BKE_editmesh.hh"
26#include "BKE_mesh.hh"
27#include "BKE_mesh_iterators.hh"
28#include "BKE_mesh_runtime.hh"
29#include "BKE_mesh_wrapper.hh"
30#include "BKE_object.hh"
31#include "BKE_object_types.hh"
32
33#include "DEG_depsgraph.hh"
35
37
38#include "bmesh.hh"
39
40#include "ED_armature.hh"
41#include "ED_screen.hh"
42#include "ED_view3d.hh"
43
44/* -------------------------------------------------------------------- */
56static int content_planes_from_clip_flag(const ARegion *region,
57 const Object *ob,
58 const eV3DProjTest clip_flag,
59 float planes[6][4])
60{
62
63 float *clip_xmin = nullptr, *clip_xmax = nullptr;
64 float *clip_ymin = nullptr, *clip_ymax = nullptr;
65 float *clip_zmin = nullptr, *clip_zmax = nullptr;
66
67 int planes_len = 0;
68
69 /* The order of `planes` has been selected based on the likelihood of points being fully
70 * outside the plane to increase the chance of an early exit in #clip_segment_v3_plane_n.
71 * With "near" being most likely and "far" being unlikely.
72 *
73 * Otherwise the order of axes in `planes` isn't significant. */
74
75 if (clip_flag & V3D_PROJ_TEST_CLIP_NEAR) {
76 clip_zmin = planes[planes_len++];
77 }
78 if (clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
79 clip_xmin = planes[planes_len++];
80 clip_xmax = planes[planes_len++];
81 clip_ymin = planes[planes_len++];
82 clip_ymax = planes[planes_len++];
83 }
84 if (clip_flag & V3D_PROJ_TEST_CLIP_FAR) {
85 clip_zmax = planes[planes_len++];
86 }
87
88 BLI_assert(planes_len <= 6);
89 if (planes_len != 0) {
90 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
91 const blender::float4x4 projection = ED_view3d_ob_project_mat_get(rv3d, ob);
93 projection.ptr(), clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax);
94 }
95 return planes_len;
96}
97
107 const ARegion *region,
108 const float v_a[3],
109 const float v_b[3],
110 const eV3DProjTest clip_flag,
111 const rctf *win_rect,
112 const float content_planes[][4],
113 const int content_planes_len,
114 /* Output. */
115 float r_screen_co_a[2],
116 float r_screen_co_b[2])
117{
118 /* Clipping already handled, no need to check in projection. */
119 eV3DProjTest clip_flag_nowin = clip_flag & ~V3D_PROJ_TEST_CLIP_WIN;
120
122 region, v_a, r_screen_co_a, clip_flag_nowin);
124 region, v_b, r_screen_co_b, clip_flag_nowin);
125
126 if ((status_a == V3D_PROJ_RET_OK) && (status_b == V3D_PROJ_RET_OK)) {
127 if (clip_flag & V3D_PROJ_TEST_CLIP_WIN) {
128 if (!BLI_rctf_isect_segment(win_rect, r_screen_co_a, r_screen_co_b)) {
129 return false;
130 }
131 }
132 }
133 else {
134 if (content_planes_len == 0) {
135 return false;
136 }
137
138 /* Both too near, ignore. */
139 if ((status_a & V3D_PROJ_TEST_CLIP_NEAR) && (status_b & V3D_PROJ_TEST_CLIP_NEAR)) {
140 return false;
141 }
142
143 /* Both too far, ignore. */
144 if ((status_a & V3D_PROJ_TEST_CLIP_FAR) && (status_b & V3D_PROJ_TEST_CLIP_FAR)) {
145 return false;
146 }
147
148 /* Simple cases have been ruled out, clip by viewport planes, then re-project. */
149 float v_a_clip[3], v_b_clip[3];
150 if (!clip_segment_v3_plane_n(v_a, v_b, content_planes, content_planes_len, v_a_clip, v_b_clip))
151 {
152 return false;
153 }
154
155 if ((ED_view3d_project_float_object(region, v_a_clip, r_screen_co_a, clip_flag_nowin) !=
157 (ED_view3d_project_float_object(region, v_b_clip, r_screen_co_b, clip_flag_nowin) !=
159 {
160 return false;
161 }
162
163 /* No need for #V3D_PROJ_TEST_CLIP_WIN check here,
164 * clipping the segment by planes handle this. */
165 }
166
167 return true;
168}
169
174 const float v_a[3],
175 const float v_b[3],
176 const eV3DProjTest clip_flag,
177 /* Output. */
178 float r_screen_co_a[2],
179 float r_screen_co_b[2])
180{
181 int count = 0;
182
183 if (ED_view3d_project_float_object(region, v_a, r_screen_co_a, clip_flag) == V3D_PROJ_RET_OK) {
184 count++;
185 }
186 else {
187 r_screen_co_a[0] = IS_CLIPPED; /* weak */
188 /* screen_co_a[1]: intentionally don't set this so we get errors on misuse */
189 }
190
191 if (ED_view3d_project_float_object(region, v_b, r_screen_co_b, clip_flag) == V3D_PROJ_RET_OK) {
192 count++;
193 }
194 else {
195 r_screen_co_b[0] = IS_CLIPPED; /* weak */
196 /* screen_co_b[1]: intentionally don't set this so we get errors on misuse */
197 }
198
199 /* Caller may want to know this value, for now it's not needed. */
200 return count != 0;
201}
202
205/* -------------------------------------------------------------------- */
216
218 void (*func)(void *user_data, BMVert *eve, const float screen_co[2], int index);
222};
223
226 void (*func)(void *user_data,
227 BMEdge *eed,
228 const float screen_co_a[2],
229 const float screen_co_b[2],
230 int index);
234
235 rctf win_rect; /* copy of: vc.region->winx/winy, use for faster tests, minx/y will always be 0 */
236
241 float content_planes[6][4];
243};
244
246 void (*func)(void *user_data, BMFace *efa, const float screen_co_b[2], int index);
250};
251
261/* -------------------------------------------------------------------- */
265static void meshobject_foreachScreenVert__mapFunc(void *user_data,
266 int index,
267 const float co[3],
268 const float /*no*/[3])
269{
271 user_data);
272 if (!data->hide_vert.is_empty() && data->hide_vert[index]) {
273 return;
274 }
275
276 float screen_co[2];
277
278 if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
280 {
281 return;
282 }
283
284 data->func(data->user_data, screen_co, index);
285}
286
288 void (*func)(void *user_data,
289 const float screen_co[2],
290 int index),
291 void *user_data,
292 eV3DProjTest clip_flag)
293{
294 using namespace blender;
295 BLI_assert((clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) == 0);
297
298 const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
299 const Mesh *mesh = BKE_object_get_evaluated_mesh(ob_eval);
300 const bke::AttributeAccessor attributes = mesh->attributes();
301
303
304 data.vc = *vc;
305 data.func = func;
306 data.user_data = user_data;
307 data.clip_flag = clip_flag;
308 data.hide_vert = *attributes.lookup<bool>(".hide_vert", bke::AttrDomain::Point);
309
310 if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
311 ED_view3d_clipping_local(vc->rv3d, vc->obact->object_to_world().ptr());
312 }
313
316}
317
318static void mesh_foreachScreenVert__mapFunc(void *user_data,
319 int index,
320 const float co[3],
321 const float /*no*/[3])
322{
323 foreachScreenVert_userData *data = static_cast<foreachScreenVert_userData *>(user_data);
324 BMVert *eve = BM_vert_at_index(data->vc.em->bm, index);
326 return;
327 }
328
329 float screen_co[2];
330 if (ED_view3d_project_float_object(data->vc.region, co, screen_co, data->clip_flag) !=
332 {
333 return;
334 }
335
336 data->func(data->user_data, eve, screen_co, index);
337}
338
340 const ViewContext *vc,
341 void (*func)(void *user_data, BMVert *eve, const float screen_co[2], int index),
342 void *user_data,
343 eV3DProjTest clip_flag)
344{
346
348 vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
350
352
353 data.vc = *vc;
354 data.func = func;
355 data.user_data = user_data;
356 data.clip_flag = clip_flag;
357
358 if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
360 vc->obedit->object_to_world().ptr()); /* for local clipping lookups */
361 }
362
365}
366
369/* -------------------------------------------------------------------- */
373static void mesh_foreachScreenEdge__mapFunc(void *user_data,
374 int index,
375 const float v_a[3],
376 const float v_b[3])
377{
378 foreachScreenEdge_userData *data = static_cast<foreachScreenEdge_userData *>(user_data);
379 BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
381 return;
382 }
383
384 float screen_co_a[2], screen_co_b[2];
386 v_a,
387 v_b,
388 data->clip_flag,
389 &data->win_rect,
390 data->content_planes,
391 data->content_planes_len,
392 screen_co_a,
393 screen_co_b))
394 {
395 return;
396 }
397
398 data->func(data->user_data, eed, screen_co_a, screen_co_b, index);
399}
400
402 void (*func)(void *user_data,
403 BMEdge *eed,
404 const float screen_co_a[2],
405 const float screen_co_b[2],
406 int index),
407 void *user_data,
408 eV3DProjTest clip_flag)
409{
411
413 vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
415
417
418 data.vc = *vc;
419
420 data.win_rect.xmin = 0;
421 data.win_rect.ymin = 0;
422 data.win_rect.xmax = vc->region->winx;
423 data.win_rect.ymax = vc->region->winy;
424
425 data.func = func;
426 data.user_data = user_data;
427 data.clip_flag = clip_flag;
428
429 if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
431 vc->obedit->object_to_world().ptr()); /* for local clipping lookups */
432 }
433
434 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
435 data.content_planes_len = content_planes_from_clip_flag(
436 vc->region, vc->obedit, clip_flag, data.content_planes);
437 }
438 else {
439 data.content_planes_len = 0;
440 }
441
444}
445
448/* -------------------------------------------------------------------- */
457 int index,
458 const float v_a[3],
459 const float v_b[3])
460{
461 foreachScreenEdge_userData *data = static_cast<foreachScreenEdge_userData *>(user_data);
462 BMEdge *eed = BM_edge_at_index(data->vc.em->bm, index);
464 return;
465 }
466
467 BLI_assert(data->clip_flag & V3D_PROJ_TEST_CLIP_BB);
468
469 float v_a_clip[3], v_b_clip[3];
470 if (!clip_segment_v3_plane_n(v_a, v_b, data->vc.rv3d->clip_local, 4, v_a_clip, v_b_clip)) {
471 return;
472 }
473
474 float screen_co_a[2], screen_co_b[2];
476 v_a_clip,
477 v_b_clip,
478 data->clip_flag,
479 &data->win_rect,
480 data->content_planes,
481 data->content_planes_len,
482 screen_co_a,
483 screen_co_b))
484 {
485 return;
486 }
487
488 data->func(data->user_data, eed, screen_co_a, screen_co_b, index);
489}
490
492 void (*func)(void *user_data,
493 BMEdge *eed,
494 const float screen_co_a[2],
495 const float screen_co_b[2],
496 int index),
497 void *user_data,
498 eV3DProjTest clip_flag)
499{
501
503 vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
505
507
508 data.vc = *vc;
509
510 data.win_rect.xmin = 0;
511 data.win_rect.ymin = 0;
512 data.win_rect.xmax = vc->region->winx;
513 data.win_rect.ymax = vc->region->winy;
514
515 data.func = func;
516 data.user_data = user_data;
517 data.clip_flag = clip_flag;
518
519 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
520 data.content_planes_len = content_planes_from_clip_flag(
521 vc->region, vc->obedit, clip_flag, data.content_planes);
522 }
523 else {
524 data.content_planes_len = 0;
525 }
526
528
529 if ((clip_flag & V3D_PROJ_TEST_CLIP_BB) && (vc->rv3d->clipbb != nullptr)) {
531 vc->rv3d, vc->obedit->object_to_world().ptr()); /* for local clipping lookups. */
534 }
535 else {
537 mesh, vc->em->bm->totedge, mesh_foreachScreenEdge__mapFunc, &data);
538 }
539}
540
543/* -------------------------------------------------------------------- */
547static void mesh_foreachScreenFace__mapFunc(void *user_data,
548 int index,
549 const float cent[3],
550 const float /*no*/[3])
551{
552 foreachScreenFace_userData *data = static_cast<foreachScreenFace_userData *>(user_data);
553 BMFace *efa = BM_face_at_index(data->vc.em->bm, index);
555 return;
556 }
557
558 float screen_co[2];
559 if (ED_view3d_project_float_object(data->vc.region, cent, screen_co, data->clip_flag) !=
561 {
562 return;
563 }
564
565 data->func(data->user_data, efa, screen_co, index);
566}
567
569 const ViewContext *vc,
570 void (*func)(void *user_data, BMFace *efa, const float screen_co_b[2], int index),
571 void *user_data,
572 const eV3DProjTest clip_flag)
573{
574 BLI_assert((clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) == 0);
576
578 vc->depsgraph, vc->scene, vc->obedit, &CD_MASK_BAREMESH);
581
582 data.vc = *vc;
583 data.func = func;
584 data.user_data = user_data;
585 data.clip_flag = clip_flag;
586
588
589 const int face_dot_tags_num = mesh->runtime->subsurf_face_dot_tags.size();
590 if (face_dot_tags_num && (face_dot_tags_num != mesh->verts_num)) {
593 }
594 else {
597 }
598}
599
602/* -------------------------------------------------------------------- */
607 void (*func)(void *user_data,
608 Nurb *nu,
609 BPoint *bp,
610 BezTriple *bezt,
611 int beztindex,
612 bool handles_visible,
613 const float screen_co_b[2]),
614 void *user_data,
615 const eV3DProjTest clip_flag)
616{
617 Curve *cu = static_cast<Curve *>(vc->obedit->data);
618 int i;
620 /* If no point in the triple is selected, the handles are invisible. */
621 const bool only_selected = (vc->v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
622
624
625 if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
627 vc->obedit->object_to_world().ptr()); /* for local clipping lookups */
628 }
629
630 LISTBASE_FOREACH (Nurb *, nu, nurbs) {
631 if (nu->type == CU_BEZIER) {
632 for (i = 0; i < nu->pntsu; i++) {
633 BezTriple *bezt = &nu->bezt[i];
634
635 if (bezt->hide == 0) {
636 const bool handles_visible = (vc->v3d->overlay.handle_display != CURVE_HANDLE_NONE) &&
637 (!only_selected || BEZT_ISSEL_ANY(bezt));
638 float screen_co[2];
639
640 if (!handles_visible) {
642 vc->region,
643 bezt->vec[1],
644 screen_co,
646 {
647 func(user_data, nu, nullptr, bezt, 1, false, screen_co);
648 }
649 }
650 else {
652 vc->region,
653 bezt->vec[0],
654 screen_co,
656 {
657 func(user_data, nu, nullptr, bezt, 0, true, screen_co);
658 }
660 vc->region,
661 bezt->vec[1],
662 screen_co,
664 {
665 func(user_data, nu, nullptr, bezt, 1, true, screen_co);
666 }
668 vc->region,
669 bezt->vec[2],
670 screen_co,
672 {
673 func(user_data, nu, nullptr, bezt, 2, true, screen_co);
674 }
675 }
676 }
677 }
678 }
679 else {
680 for (i = 0; i < nu->pntsu * nu->pntsv; i++) {
681 BPoint *bp = &nu->bp[i];
682
683 if (bp->hide == 0) {
684 float screen_co[2];
686 vc->region,
687 bp->vec,
688 screen_co,
690 {
691 func(user_data, nu, bp, nullptr, -1, false, screen_co);
692 }
693 }
694 }
695 }
696 }
697}
698
701/* -------------------------------------------------------------------- */
706 void (*func)(void *user_data,
707 MetaElem *ml,
708 const float screen_co_b[2]),
709 void *user_data,
710 const eV3DProjTest clip_flag)
711{
712 MetaBall *mb = (MetaBall *)vc->obedit->data;
713
715
716 LISTBASE_FOREACH (MetaElem *, ml, mb->editelems) {
717 float screen_co[2];
718 if (ED_view3d_project_float_object(vc->region, &ml->x, screen_co, clip_flag) ==
720 {
721 func(user_data, ml, screen_co);
722 }
723 }
724}
725
728/* -------------------------------------------------------------------- */
733 void (*func)(void *user_data, BPoint *bp, const float screen_co[2]),
734 void *user_data,
735 const eV3DProjTest clip_flag)
736{
737 Object *obedit = vc->obedit;
738 Lattice *lt = static_cast<Lattice *>(obedit->data);
739 BPoint *bp = lt->editlatt->latt->def;
740 DispList *dl = obedit->runtime->curve_cache ?
741 BKE_displist_find(&obedit->runtime->curve_cache->disp, DL_VERTS) :
742 nullptr;
743 const float *co = dl ? dl->verts : nullptr;
744 int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
745
747
748 if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
750 obedit->object_to_world().ptr()); /* for local clipping lookups */
751 }
752
753 for (i = 0; i < N; i++, bp++, co += 3) {
754 if (bp->hide == 0) {
755 float screen_co[2];
756 if (ED_view3d_project_float_object(vc->region, dl ? co : bp->vec, screen_co, clip_flag) ==
758 {
759 func(user_data, bp, screen_co);
760 }
761 }
762 }
763}
764
767/* -------------------------------------------------------------------- */
772 void (*func)(void *user_data,
773 EditBone *ebone,
774 const float screen_co_a[2],
775 const float screen_co_b[2]),
776 void *user_data,
777 const eV3DProjTest clip_flag)
778{
779 bArmature *arm = static_cast<bArmature *>(vc->obedit->data);
780
782
783 float content_planes[6][4];
784 int content_planes_len;
785 rctf win_rect;
786
787 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
788 content_planes_len = content_planes_from_clip_flag(
789 vc->region, vc->obedit, clip_flag, content_planes);
790 win_rect.xmin = 0;
791 win_rect.ymin = 0;
792 win_rect.xmax = vc->region->winx;
793 win_rect.ymax = vc->region->winy;
794 }
795 else {
796 content_planes_len = 0;
797 }
798
799 LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) {
800 if (!EBONE_VISIBLE(arm, ebone)) {
801 continue;
802 }
803
804 float screen_co_a[2], screen_co_b[2];
805 const float *v_a = ebone->head, *v_b = ebone->tail;
806
807 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
809 v_a,
810 v_b,
811 clip_flag,
812 &win_rect,
813 content_planes,
814 content_planes_len,
815 screen_co_a,
816 screen_co_b))
817 {
818 continue;
819 }
820 }
821 else {
823 vc->region, v_a, v_b, clip_flag, screen_co_a, screen_co_b))
824 {
825 continue;
826 }
827 }
828
829 func(user_data, ebone, screen_co_a, screen_co_b);
830 }
831}
832
835/* -------------------------------------------------------------------- */
840 void (*func)(void *user_data,
841 bPoseChannel *pchan,
842 const float screen_co_a[2],
843 const float screen_co_b[2]),
844 void *user_data,
845 const eV3DProjTest clip_flag)
846{
847 /* Almost _exact_ copy of #armature_foreachScreenBone */
848
849 const Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, vc->obact);
850 const bArmature *arm_eval = static_cast<const bArmature *>(ob_eval->data);
851 bPose *pose = vc->obact->pose;
852
854
855 float content_planes[6][4];
856 int content_planes_len;
857 rctf win_rect;
858
859 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
860 content_planes_len = content_planes_from_clip_flag(
861 vc->region, ob_eval, clip_flag, content_planes);
862 win_rect.xmin = 0;
863 win_rect.ymin = 0;
864 win_rect.xmax = vc->region->winx;
865 win_rect.ymax = vc->region->winy;
866 }
867 else {
868 content_planes_len = 0;
869 }
870
871 LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
872 if (!PBONE_VISIBLE(arm_eval, pchan->bone)) {
873 continue;
874 }
875
876 bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
877 float screen_co_a[2], screen_co_b[2];
878 const float *v_a = pchan_eval->pose_head, *v_b = pchan_eval->pose_tail;
879
880 if (clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) {
882 v_a,
883 v_b,
884 clip_flag,
885 &win_rect,
886 content_planes,
887 content_planes_len,
888 screen_co_a,
889 screen_co_b))
890 {
891 continue;
892 }
893 }
894 else {
896 vc->region, v_a, v_b, clip_flag, screen_co_a, screen_co_b))
897 {
898 continue;
899 }
900 }
901
902 func(user_data, pchan, screen_co_a, screen_co_b);
903 }
904}
905
C++ functions to deal with Armature collections (i.e. the successor of bone layers).
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
#define PBONE_VISIBLE(arm, bone)
ListBase * BKE_curve_editNurbs_get(Curve *cu)
Definition curve.cc:398
const CustomData_MeshMasks CD_MASK_BAREMESH
display list (or rather multi purpose list) stuff.
DispList * BKE_displist_find(struct ListBase *lb, int type)
Definition displist.cc:71
@ DL_VERTS
@ MESH_FOREACH_NOP
void BKE_mesh_foreach_mapped_edge(Mesh *mesh, int tot_edges, void(*func)(void *user_data, int index, const float v0co[3], const float v1co[3]), void *user_data)
void BKE_mesh_foreach_mapped_face_center(Mesh *mesh, void(*func)(void *user_data, int index, const float cent[3], const float no[3]), void *user_data, MeshForeachFlag flag)
void BKE_mesh_foreach_mapped_subdiv_face_center(Mesh *mesh, void(*func)(void *user_data, int index, const float cent[3], const float no[3]), void *user_data, MeshForeachFlag flag)
void BKE_mesh_foreach_mapped_vert(const Mesh *mesh, void(*func)(void *user_data, int index, const float co[3], const float no[3]), void *user_data, MeshForeachFlag flag)
Mesh * BKE_mesh_wrapper_ensure_subdivision(Mesh *mesh)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
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])
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])
bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2])
#define UNLIKELY(x)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ CU_BEZIER
#define BEZT_ISSEL_ANY(bezt)
Object is a sort of wrapper for general info.
@ CURVE_HANDLE_NONE
@ CURVE_HANDLE_SELECTED
#define EBONE_VISIBLE(arm, ebone)
void ED_view3d_check_mats_rv3d(RegionView3D *rv3d)
eV3DProjTest
Definition ED_view3d.hh:265
@ V3D_PROJ_TEST_CLIP_FAR
Definition ED_view3d.hh:270
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:269
@ V3D_PROJ_TEST_CLIP_CONTENT
Definition ED_view3d.hh:292
@ V3D_PROJ_TEST_CLIP_WIN
Definition ED_view3d.hh:268
@ V3D_PROJ_TEST_CLIP_BB
Definition ED_view3d.hh:267
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
eV3DProjStatus
Definition ED_view3d.hh:242
@ V3D_PROJ_RET_CLIP_WIN
Definition ED_view3d.hh:258
@ V3D_PROJ_RET_CLIP_BB
Definition ED_view3d.hh:256
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
void ED_view3d_clipping_local(RegionView3D *rv3d, const float mat[4][4])
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
#define IS_CLIPPED
Definition ED_view3d.hh:239
@ BM_ELEM_HIDDEN
#define BM_elem_flag_test(ele, hflag)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
int count
#define N
Mesh * editbmesh_get_eval_cage_from_orig(Depsgraph *depsgraph, const Scene *scene, Object *obedit, const CustomData_MeshMasks *dataMask)
int totedge
float vec[4]
float vec[3][3]
float * verts
float tail[3]
float head[3]
struct Lattice * latt
struct EditLatt * editlatt
struct BPoint * def
ListBase * editelems
short type
BezTriple * bezt
BPoint * bp
struct bPose * pose
ObjectRuntimeHandle * runtime
struct BoundBox * clipbb
View3DOverlay overlay
RegionView3D * rv3d
Definition ED_view3d.hh:76
ARegion * region
Definition ED_view3d.hh:73
Scene * scene
Definition ED_view3d.hh:69
BMEditMesh * em
Definition ED_view3d.hh:77
View3D * v3d
Definition ED_view3d.hh:74
Object * obact
Definition ED_view3d.hh:71
Object * obedit
Definition ED_view3d.hh:72
Depsgraph * depsgraph
Definition ED_view3d.hh:68
ListBase * edbo
struct Bone * bone
ListBase chanbase
const c_style_mat & ptr() const
void(* func)(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
void(* func)(void *user_data, BMFace *efa, const float screen_co_b[2], int index)
blender::VArraySpan< bool > hide_vert
void(* func)(void *user_data, const float screen_co[2], int index)
void(* func)(void *user_data, BMVert *eve, const float screen_co[2], int index)
float xmax
float xmin
float ymax
float ymin
void pose_foreachScreenBone(const ViewContext *vc, void(*func)(void *user_data, bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), void *user_data, const eV3DProjTest clip_flag)
void mesh_foreachScreenVert(const ViewContext *vc, void(*func)(void *user_data, BMVert *eve, const float screen_co[2], int index), void *user_data, eV3DProjTest clip_flag)
static void mesh_foreachScreenVert__mapFunc(void *user_data, int index, const float co[3], const float[3])
static bool view3d_project_segment_to_screen_with_clip_tag(const ARegion *region, const float v_a[3], const float v_b[3], const eV3DProjTest clip_flag, float r_screen_co_a[2], float r_screen_co_b[2])
static void mesh_foreachScreenEdge__mapFunc(void *user_data, int index, const float v_a[3], const float v_b[3])
void mesh_foreachScreenFace(const ViewContext *vc, void(*func)(void *user_data, BMFace *efa, const float screen_co_b[2], int index), void *user_data, const eV3DProjTest clip_flag)
void mesh_foreachScreenEdge(const ViewContext *vc, void(*func)(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *user_data, eV3DProjTest clip_flag)
void armature_foreachScreenBone(const ViewContext *vc, void(*func)(void *user_data, EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), void *user_data, const eV3DProjTest clip_flag)
static void mesh_foreachScreenFace__mapFunc(void *user_data, int index, const float cent[3], const float[3])
static void meshobject_foreachScreenVert__mapFunc(void *user_data, int index, const float co[3], const float[3])
void mball_foreachScreenElem(const ViewContext *vc, void(*func)(void *user_data, MetaElem *ml, const float screen_co_b[2]), void *user_data, const eV3DProjTest clip_flag)
void nurbs_foreachScreenVert(const ViewContext *vc, void(*func)(void *user_data, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, bool handles_visible, const float screen_co_b[2]), void *user_data, const eV3DProjTest clip_flag)
static void mesh_foreachScreenEdge_clip_bb_segment__mapFunc(void *user_data, int index, const float v_a[3], const float v_b[3])
static int content_planes_from_clip_flag(const ARegion *region, const Object *ob, const eV3DProjTest clip_flag, float planes[6][4])
void mesh_foreachScreenEdge_clip_bb_segment(const ViewContext *vc, void(*func)(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *user_data, eV3DProjTest clip_flag)
void lattice_foreachScreenVert(const ViewContext *vc, void(*func)(void *user_data, BPoint *bp, const float screen_co[2]), void *user_data, const eV3DProjTest clip_flag)
void meshobject_foreachScreenVert(const ViewContext *vc, void(*func)(void *user_data, const float screen_co[2], int index), void *user_data, eV3DProjTest clip_flag)
static bool view3d_project_segment_to_screen_with_content_clip_planes(const ARegion *region, const float v_a[3], const float v_b[3], const eV3DProjTest clip_flag, const rctf *win_rect, const float content_planes[][4], const int content_planes_len, float r_screen_co_a[2], float r_screen_co_b[2])