Blender  V2.93
editcurve_query.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_object_types.h"
25 #include "DNA_scene_types.h"
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_listbase.h"
30 #include "BLI_math.h"
31 
32 #include "BKE_curve.h"
33 #include "BKE_fcurve.h"
34 #include "BKE_layer.h"
35 
36 #include "DEG_depsgraph.h"
37 #include "DEG_depsgraph_build.h"
38 
39 #include "ED_curve.h"
40 #include "ED_view3d.h"
41 
42 #include "curve_intern.h"
43 
44 /* -------------------------------------------------------------------- */
48 static void ED_curve_pick_vert__do_closest(void *userData,
49  Nurb *nu,
50  BPoint *bp,
51  BezTriple *bezt,
52  int beztindex,
53  bool handles_visible,
54  const float screen_co[2])
55 {
56  struct {
57  BPoint *bp;
58  BezTriple *bezt;
59  Nurb *nurb;
60  float dist;
61  int hpoint, select;
62  float mval_fl[2];
63  bool is_changed;
64  } *data = userData;
65 
66  uint8_t flag;
67  float dist_test;
68 
69  if (bp) {
70  flag = bp->f1;
71  }
72  else {
73  BLI_assert(handles_visible || beztindex == 1);
74 
75  if (beztindex == 0) {
76  flag = bezt->f1;
77  }
78  else if (beztindex == 1) {
79  flag = bezt->f2;
80  }
81  else {
82  flag = bezt->f3;
83  }
84  }
85 
86  dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
87  if ((flag & SELECT) == data->select) {
88  dist_test += 5.0f;
89  }
90  if (bezt && beztindex == 1) {
91  dist_test += 3.0f; /* middle points get a small disadvantage */
92  }
93 
94  if (dist_test < data->dist) {
95  data->dist = dist_test;
96 
97  data->bp = bp;
98  data->bezt = bezt;
99  data->nurb = nu;
100  data->hpoint = bezt ? beztindex : 0;
101  data->is_changed = true;
102  }
103 
104  UNUSED_VARS_NDEBUG(handles_visible);
105 }
106 
108  short sel,
109  Nurb **r_nurb,
110  BezTriple **r_bezt,
111  BPoint **r_bp,
112  short *r_handle,
113  Base **r_base)
114 {
115  /* (sel == 1): selected gets a disadvantage */
116  /* in nurb and bezt or bp the nearest is written */
117  /* return 0 1 2: handlepunt */
118  struct {
119  BPoint *bp;
120  BezTriple *bezt;
121  Nurb *nurb;
122  float dist;
123  int hpoint, select;
124  float mval_fl[2];
125  bool is_changed;
126  } data = {NULL};
127 
129  data.hpoint = 0;
130  data.select = sel;
131  data.mval_fl[0] = vc->mval[0];
132  data.mval_fl[1] = vc->mval[1];
133 
134  uint bases_len;
136  vc->view_layer, vc->v3d, &bases_len);
137  for (uint base_index = 0; base_index < bases_len; base_index++) {
138  Base *base = bases[base_index];
139  data.is_changed = false;
140 
144 
145  if (r_base && data.is_changed) {
146  *r_base = base;
147  }
148  }
149  MEM_freeN(bases);
150 
151  *r_nurb = data.nurb;
152  *r_bezt = data.bezt;
153  *r_bp = data.bp;
154 
155  if (r_handle) {
156  *r_handle = data.hpoint;
157  }
158 
159  return (data.bezt || data.bp);
160 }
161 
164 /* -------------------------------------------------------------------- */
169  Curve *cu, View3D *v3d, Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp)
170 {
171  /* in nu and (bezt or bp) selected are written if there's 1 sel. */
172  /* if more points selected in 1 spline: return only nu, bezt and bp are 0 */
173  ListBase *editnurb = &cu->editnurb->nurbs;
174  BezTriple *bezt1;
175  BPoint *bp1;
176  int a;
177 
178  *r_nu = NULL;
179  *r_bezt = NULL;
180  *r_bp = NULL;
181 
182  LISTBASE_FOREACH (Nurb *, nu1, editnurb) {
183  if (nu1->type == CU_BEZIER) {
184  bezt1 = nu1->bezt;
185  a = nu1->pntsu;
186  while (a--) {
187  if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1)) {
188  if (!ELEM(*r_nu, NULL, nu1)) {
189  *r_nu = NULL;
190  *r_bp = NULL;
191  *r_bezt = NULL;
192  return;
193  }
194 
195  if (*r_bezt || *r_bp) {
196  *r_bp = NULL;
197  *r_bezt = NULL;
198  }
199  else {
200  *r_bezt = bezt1;
201  *r_nu = nu1;
202  }
203  }
204  bezt1++;
205  }
206  }
207  else {
208  bp1 = nu1->bp;
209  a = nu1->pntsu * nu1->pntsv;
210  while (a--) {
211  if (bp1->f1 & SELECT) {
212  if (!ELEM(*r_nu, NULL, nu1)) {
213  *r_bp = NULL;
214  *r_bezt = NULL;
215  *r_nu = NULL;
216  return;
217  }
218 
219  if (*r_bezt || *r_bp) {
220  *r_bp = NULL;
221  *r_bezt = NULL;
222  }
223  else {
224  *r_bp = bp1;
225  *r_nu = nu1;
226  }
227  }
228  bp1++;
229  }
230  }
231  }
232 }
233 
235 {
236  Nurb *nu = NULL;
237  void *vert = NULL;
238 
239  if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) {
240  return false;
241  }
242 
243  if (nu->type == CU_BEZIER) {
244  BezTriple *bezt = (BezTriple *)vert;
245  copy_v3_v3(center, bezt->vec[1]);
246  }
247  else {
248  BPoint *bp = (BPoint *)vert;
249  copy_v3_v3(center, bp->vec);
250  }
251 
252  return true;
253 }
254 
bool BKE_curve_nurb_vert_active_get(struct Curve *cu, struct Nurb **r_nu, void **r_vert)
Definition: curve.c:5146
#define BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, v3d, r_len)
Definition: BKE_layer.h:430
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
@ CU_BEZIER
#define BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)
Object is a sort of wrapper for general info.
void nurbs_foreachScreenVert(struct ViewContext *vc, void(*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, bool handle_visible, const float screen_co[2]), void *userData, const eV3DProjTest clip_flag)
void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
Definition: space_view3d.c:190
void ED_view3d_viewcontext_init_object(struct ViewContext *vc, struct Object *obact)
#define V3D_PROJ_TEST_CLIP_DEFAULT
Definition: ED_view3d.h:201
float ED_view3d_select_dist_px(void)
NSNotificationCenter * center
Read Guarded memory(de)allocation.
#define SELECT
void ED_curve_nurb_vert_selected_find(Curve *cu, View3D *v3d, Nurb **r_nu, BezTriple **r_bezt, BPoint **r_bp)
bool ED_curve_pick_vert(ViewContext *vc, short sel, Nurb **r_nurb, BezTriple **r_bezt, BPoint **r_bp, short *r_handle, Base **r_base)
bool ED_curve_active_center(Curve *cu, float center[3])
static void ED_curve_pick_vert__do_closest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, bool handles_visible, const float screen_co[2])
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static unsigned a[3]
Definition: RandGen.cpp:92
unsigned char uint8_t
Definition: stdint.h:81
uint8_t f1
float vec[4]
struct Object * object
float vec[3][3]
EditNurb * editnurb
ListBase nurbs
short type
int mval[2]
Definition: ED_view3d.h:85
struct ViewLayer * view_layer
Definition: ED_view3d.h:77
struct Object * obedit
Definition: ED_view3d.h:79
struct View3D * v3d
Definition: ED_view3d.h:81
struct RegionView3D * rv3d
Definition: ED_view3d.h:83
__forceinline const avxb select(const avxb &m, const avxb &t, const avxb &f)
Definition: util_avxb.h:167