Blender  V2.93
bmo_subdivide.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 
23 #include "MEM_guardedalloc.h"
24 
25 #include "BLI_array.h"
26 #include "BLI_math.h"
27 #include "BLI_noise.h"
28 #include "BLI_rand.h"
29 #include "BLI_stack.h"
30 
31 #include "BKE_customdata.h"
32 
33 #include "bmesh.h"
35 #include "intern/bmesh_private.h"
36 
37 typedef struct SubDParams {
38  int numcuts;
39  float smooth;
41  float fractal;
42  float along_normal;
43  // int beauty;
44  bool use_smooth;
46  bool use_sphere;
48  int seed;
50  BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
51  BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
52  float fractal_ofs[3];
53 
54  /* Runtime storage for shape key. */
55  struct {
58  int totlayer;
59 
60  /* Shape-key holding displaced vertex coordinates for current geometry. */
61  int tmpkey;
63 
65 
67 {
68  const int skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
69  params->shape_info.tmpkey = skey;
70  params->shape_info.cd_vert_shape_offset = CustomData_get_offset(&bm->vdata, CD_SHAPEKEY);
71  params->shape_info.cd_vert_shape_offset_tmp = CustomData_get_n_offset(
72  &bm->vdata, CD_SHAPEKEY, skey);
73  params->shape_info.totlayer = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY);
74 }
75 
76 typedef void (*subd_pattern_fill_fp)(BMesh *bm,
77  BMFace *face,
78  BMVert **verts,
79  const SubDParams *params);
80 
81 /*
82  * note: this is a pattern-based edge subdivider.
83  * it tries to match a pattern to edge selections on faces,
84  * then executes functions to cut them.
85  */
86 typedef struct SubDPattern {
87  int seledges[20]; /* selected edges mask, for splitting */
88 
89  /* verts starts at the first new vert cut, not the first vert in the face */
91  int len; /* total number of verts, before any subdivision */
93 
94 /* generic subdivision rules:
95  *
96  * - two selected edges in a face should make a link
97  * between them.
98  *
99  * - one edge should do, what? make pretty topology, or just
100  * split the edge only?
101  */
102 
103 /* flags for all elements share a common bitfield space */
104 #define SUBD_SPLIT 1
105 
106 #define EDGE_PERCENT 2
107 
108 /* I don't think new faces are flagged, currently, but
109  * better safe than sorry. */
110 #define FACE_CUSTOMFILL 4
111 #define ELE_INNER 8
112 #define ELE_SPLIT 16
113 
114 /* see bug T32665, 0.00005 means a we get face splits at a little under 1.0 degrees */
115 #define FLT_FACE_SPLIT_EPSILON 0.00005f
116 
117 /*
118  * NOTE: beauty has been renamed to flag!
119  */
120 
121 /* generic subdivision rules:
122  *
123  * - two selected edges in a face should make a link
124  * between them.
125  *
126  * - one edge should do, what? make pretty topology, or just
127  * split the edge only?
128  */
129 
130 /* connects face with smallest len, which I think should always be correct for
131  * edge subdivision */
132 static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new)
133 {
134  BMLoop *l_a, *l_b;
135  BMFace *f;
136 
137  /* this isn't the best thing in the world. it doesn't handle cases where there's
138  * multiple faces yet. that might require a convexity test to figure out which
139  * face is "best" and who knows what for non-manifold conditions.
140  *
141  * note: we allow adjacent here, since there's no chance this happens.
142  */
143  f = BM_vert_pair_share_face_by_len(v_a, v_b, &l_a, &l_b, true);
144 
145  if (f) {
146  BMFace *f_new;
147  BMLoop *l_new;
148 
150 
151  f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
152 
153  if (r_f_new) {
154  *r_f_new = f_new;
155  }
156  return l_new ? l_new->e : NULL;
157  }
158 
159  return NULL;
160 }
161 
166  const float co_a[3],
167  const float no_a[3],
168  const float co_b[3],
169  const float no_b[3],
170  const float no_dir[3], /* caller already knows, avoid normalize */
171  float fac,
172  float r_co[3])
173 {
174  /* center of the sphere defined by both normals */
175  float center[3];
176 
177  BLI_assert(len_squared_v3v3(no_a, no_b) != 0);
178 
179  /* calculate sphere 'center' */
180  {
181  /* use point on plane to */
182  float no_mid[3], no_ortho[3];
183  /* pass this as an arg instead */
184 #if 0
185  float no_dir[3];
186 #endif
187 
188  add_v3_v3v3(no_mid, no_a, no_b);
189  normalize_v3(no_mid);
190 
191 #if 0
192  sub_v3_v3v3(no_dir, co_a, co_b);
193  normalize_v3(no_dir);
194 #endif
195 
196  /* axis of slerp */
197  bool center_ok = false;
198  cross_v3_v3v3(no_ortho, no_mid, no_dir);
199  if (normalize_v3(no_ortho) != 0.0f) {
200  float plane_a[4], plane_b[4], plane_c[4];
201  float v_a_no_ortho[3], v_b_no_ortho[3];
202 
203  /* create planes */
204  cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a);
205  cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b);
206  project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho);
207  project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho);
208 
209  plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho);
210  plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho);
211  plane_from_point_normal_v3(plane_c, co_b, no_ortho);
212 
213  /* find the sphere center from 3 planes */
214  if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) {
215  center_ok = true;
216  }
217  }
218  if (center_ok == false) {
219  mid_v3_v3v3(center, co_a, co_b);
220  }
221  }
222 
223  /* calculate the final output 'r_co' */
224  {
225  float ofs_a[3], ofs_b[3], ofs_slerp[3];
226  float dist_a, dist_b;
227 
228  sub_v3_v3v3(ofs_a, co_a, center);
229  sub_v3_v3v3(ofs_b, co_b, center);
230 
231  dist_a = normalize_v3(ofs_a);
232  dist_b = normalize_v3(ofs_b);
233 
234  if (interp_v3_v3v3_slerp(ofs_slerp, ofs_a, ofs_b, fac)) {
235  madd_v3_v3v3fl(r_co, center, ofs_slerp, interpf(dist_b, dist_a, fac));
236  }
237  else {
238  interp_v3_v3v3(r_co, co_a, co_b, fac);
239  }
240  }
241 }
242 
243 /* calculates offset for co, based on fractal, sphere or smooth settings */
244 static void alter_co(BMVert *v,
245  BMEdge *UNUSED(e_orig),
246  const SubDParams *params,
247  const float perc,
248  const BMVert *v_a,
249  const BMVert *v_b)
250 {
251  float *co = BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset_tmp);
252  int i;
253 
254  copy_v3_v3(co, v->co);
255 
256  if (UNLIKELY(params->use_sphere)) { /* subdivide sphere */
257  normalize_v3_length(co, params->smooth);
258  }
259  else if (params->use_smooth) {
260  /* calculating twice and blending gives smoother results,
261  * removing visible seams. */
262 #define USE_SPHERE_DUAL_BLEND
263 
264  const float eps_unit_vec = 1e-5f;
265  float smooth;
266  float no_dir[3];
267 
268 #ifdef USE_SPHERE_DUAL_BLEND
269  float no_reflect[3], co_a[3], co_b[3];
270 #endif
271 
272  sub_v3_v3v3(no_dir, v_a->co, v_b->co);
273  normalize_v3(no_dir);
274 
275 #ifndef USE_SPHERE_DUAL_BLEND
276  if (len_squared_v3v3(v_a->no, v_b->no) < eps_unit_vec) {
277  interp_v3_v3v3(co, v_a->co, v_b->co, perc);
278  }
279  else {
280  interp_slerp_co_no_v3(v_a->co, v_a->no, v_b->co, v_b->no, no_dir, perc, co);
281  }
282 #else
283  /* sphere-a */
284  reflect_v3_v3v3(no_reflect, v_a->no, no_dir);
285  if (len_squared_v3v3(v_a->no, no_reflect) < eps_unit_vec) {
286  interp_v3_v3v3(co_a, v_a->co, v_b->co, perc);
287  }
288  else {
289  interp_slerp_co_no_v3(v_a->co, v_a->no, v_b->co, no_reflect, no_dir, perc, co_a);
290  }
291 
292  /* sphere-b */
293  reflect_v3_v3v3(no_reflect, v_b->no, no_dir);
294  if (len_squared_v3v3(v_b->no, no_reflect) < eps_unit_vec) {
295  interp_v3_v3v3(co_b, v_a->co, v_b->co, perc);
296  }
297  else {
298  interp_slerp_co_no_v3(v_a->co, no_reflect, v_b->co, v_b->no, no_dir, perc, co_b);
299  }
300 
301  /* blend both spheres */
302  interp_v3_v3v3(co, co_a, co_b, perc);
303 #endif /* USE_SPHERE_DUAL_BLEND */
304 
305  /* apply falloff */
306  if (params->smooth_falloff == SUBD_FALLOFF_LIN) {
307  smooth = 1.0f;
308  }
309  else {
310  smooth = fabsf(1.0f - 2.0f * fabsf(0.5f - perc));
311  smooth = 1.0f + bmesh_subd_falloff_calc(params->smooth_falloff, smooth);
312  }
313 
314  if (params->use_smooth_even) {
315  smooth *= shell_v3v3_mid_normalized_to_dist(v_a->no, v_b->no);
316  }
317 
318  smooth *= params->smooth;
319  if (smooth != 1.0f) {
320  float co_flat[3];
321  interp_v3_v3v3(co_flat, v_a->co, v_b->co, perc);
322  interp_v3_v3v3(co, co_flat, co, smooth);
323  }
324 
325 #undef USE_SPHERE_DUAL_BLEND
326  }
327 
328  if (params->use_fractal) {
329  float normal[3], co2[3], base1[3], base2[3], tvec[3];
330  const float len = len_v3v3(v_a->co, v_b->co);
331  float fac;
332 
333  fac = params->fractal * len;
334 
335  mid_v3_v3v3(normal, v_a->no, v_b->no);
336  ortho_basis_v3v3_v3(base1, base2, normal);
337 
338  add_v3_v3v3(co2, v->co, params->fractal_ofs);
339  mul_v3_fl(co2, 10.0f);
340 
341  tvec[0] = fac * (BLI_noise_generic_turbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f);
342  tvec[1] = fac * (BLI_noise_generic_turbulence(1.0, co2[1], co2[0], co2[2], 15, 0, 2) - 0.5f);
343  tvec[2] = fac * (BLI_noise_generic_turbulence(1.0, co2[1], co2[2], co2[0], 15, 0, 2) - 0.5f);
344 
345  /* add displacement */
346  madd_v3_v3fl(co, normal, tvec[0]);
347  madd_v3_v3fl(co, base1, tvec[1] * (1.0f - params->along_normal));
348  madd_v3_v3fl(co, base2, tvec[2] * (1.0f - params->along_normal));
349  }
350 
351  /* apply the new difference to the rest of the shape keys,
352  * note that this doesn't take rotations into account, we _could_ support
353  * this by getting the normals and coords for each shape key and
354  * re-calculate the smooth value for each but this is quite involved.
355  * for now its ok to simply apply the difference IMHO - campbell */
356 
357  if (params->shape_info.totlayer > 1) {
358  float tvec[3];
359 
360  sub_v3_v3v3(tvec, v->co, co);
361 
362  /* skip the last layer since its the temp */
363  i = params->shape_info.totlayer - 1;
364  co = BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset);
365  while (i--) {
366  BLI_assert(co != BM_ELEM_CD_GET_VOID_P(v, params->shape_info.cd_vert_shape_offset_tmp));
367  sub_v3_v3(co += 3, tvec);
368  }
369  }
370 }
371 
372 /* assumes in the edge is the correct interpolated vertices already */
373 /* percent defines the interpolation, rad and flag are for special options */
374 /* results in new vertex with correct coordinate, vertex normal and weight group info */
376  BMEdge *edge,
377  BMEdge *e_orig,
378  const SubDParams *params,
379  const float factor_edge_split,
380  const float factor_subd,
381  BMVert *v_a,
382  BMVert *v_b,
383  BMEdge **r_edge)
384 {
385  BMVert *v_new;
386 
387  v_new = BM_edge_split(bm, edge, edge->v1, r_edge, factor_edge_split);
388 
390 
391  /* offset for smooth or sphere or fractal */
392  alter_co(v_new, e_orig, params, factor_subd, v_a, v_b);
393 
394 #if 0 // BMESH_TODO
395  /* clip if needed by mirror modifier */
396  if (edge->v1->f2) {
397  if (edge->v1->f2 & edge->v2->f2 & 1) {
398  co[0] = 0.0f;
399  }
400  if (edge->v1->f2 & edge->v2->f2 & 2) {
401  co[1] = 0.0f;
402  }
403  if (edge->v1->f2 & edge->v2->f2 & 4) {
404  co[2] = 0.0f;
405  }
406  }
407 #endif
408 
409  interp_v3_v3v3(v_new->no, v_a->no, v_b->no, factor_subd);
410  normalize_v3(v_new->no);
411 
412  return v_new;
413 }
414 
416  BMEdge *edge,
417  BMEdge *e_orig,
418  int curpoint,
419  int totpoint,
420  const SubDParams *params,
421  BMVert *v_a,
422  BMVert *v_b,
423  BMEdge **r_edge)
424 {
425  BMVert *v_new;
426  float factor_edge_split, factor_subd;
427 
428  if (BMO_edge_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) {
429  factor_edge_split = BMO_slot_map_float_get(params->slot_edge_percents, edge);
430  factor_subd = 0.0f;
431  }
432  else {
433  factor_edge_split = 1.0f / (float)(totpoint + 1 - curpoint);
434  factor_subd = (float)(curpoint + 1) / (float)(totpoint + 1);
435  }
436 
438  bm, edge, e_orig, params, factor_edge_split, factor_subd, v_a, v_b, r_edge);
439  return v_new;
440 }
441 
443  BMesh *bm, BMEdge *edge, const SubDParams *params, BMVert *v_a, BMVert *v_b)
444 {
445  BMEdge *eed = edge, *e_new, e_tmp = *edge;
446  BMVert *v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
447  int i, numcuts = params->numcuts;
448 
449  e_tmp.v1 = &v1_tmp;
450  e_tmp.v2 = &v2_tmp;
451 
452  for (i = 0; i < numcuts; i++) {
453  v = subdivide_edge_num(bm, eed, &e_tmp, i, params->numcuts, params, v_a, v_b, &e_new);
454 
458 
460  if (v->e) {
461  BM_CHECK_ELEMENT(v->e);
462  }
463  if (v->e && v->e->l) {
464  BM_CHECK_ELEMENT(v->e->l->f);
465  }
466  }
467 
468  alter_co(v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp);
469  alter_co(v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp);
470 }
471 
472 /* note: the patterns are rotated as necessary to
473  * match the input geometry. they're based on the
474  * pre-split state of the face */
475 
486 static void quad_1edge_split(BMesh *bm,
487  BMFace *UNUSED(face),
488  BMVert **verts,
489  const SubDParams *params)
490 {
491  BMFace *f_new;
492  int i, add, numcuts = params->numcuts;
493 
494  /* if it's odd, the middle face is a quad, otherwise it's a triangle */
495  if ((numcuts % 2) == 0) {
496  add = 2;
497  for (i = 0; i < numcuts; i++) {
498  if (i == numcuts / 2) {
499  add -= 1;
500  }
501  connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
502  }
503  }
504  else {
505  add = 2;
506  for (i = 0; i < numcuts; i++) {
507  connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
508  if (i == numcuts / 2) {
509  add -= 1;
510  connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
511  }
512  }
513  }
514 }
515 
516 static const SubDPattern quad_1edge = {
517  {1, 0, 0, 0},
519  4,
520 };
521 
533  BMFace *UNUSED(face),
534  BMVert **verts,
535  const SubDParams *params)
536 {
537  BMFace *f_new;
538  int i, numcuts = params->numcuts;
539 
540  for (i = 0; i < numcuts; i++) {
541  connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
542  }
543  connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &f_new);
544 }
545 
546 static const SubDPattern quad_2edge_path = {
547  {1, 1, 0, 0},
549  4,
550 };
551 
563  BMFace *UNUSED(face),
564  BMVert **verts,
565  const SubDParams *params)
566 {
567  BMFace *f_new;
568  BMVert *v, *v_last;
569  BMEdge *e, *e_new, e_tmp;
570  int i, numcuts = params->numcuts;
571 
572  v_last = verts[numcuts];
573 
574  for (i = numcuts - 1; i >= 0; i--) {
575  e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
576 
577  e_tmp = *e;
578  v = bm_subdivide_edge_addvert(bm, e, &e_tmp, params, 0.5f, 0.5f, e->v1, e->v2, &e_new);
579 
580  if (i != numcuts - 1) {
581  connect_smallest_face(bm, v_last, v, &f_new);
582  }
583 
584  v_last = v;
585  }
586 
587  connect_smallest_face(bm, v_last, verts[numcuts * 2 + 2], &f_new);
588 }
589 
591  {1, 1, 0, 0},
593  4,
594 };
595 
607  BMFace *UNUSED(face),
608  BMVert **verts,
609  const SubDParams *params)
610 {
611  BMFace *f_new;
612  /* BMVert *v; */ /* UNUSED */
613  /* BMVert *v_last = verts[2]; */ /* UNUSED */
614  /* BMEdge *e, *e_new; */ /* UNUSED */
615  int i, numcuts = params->numcuts;
616 
617  for (i = 0; i < numcuts; i++) {
618  connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &f_new);
619  connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &f_new);
620  }
621 }
622 
623 static const SubDPattern quad_2edge_fan = {
624  {1, 1, 0, 0},
626  4,
627 };
628 
641 static void quad_3edge_split(BMesh *bm,
642  BMFace *UNUSED(face),
643  BMVert **verts,
644  const SubDParams *params)
645 {
646  BMFace *f_new;
647  int i, add = 0, numcuts = params->numcuts;
648 
649  for (i = 0; i < numcuts; i++) {
650  if (i == numcuts / 2) {
651  if (numcuts % 2 != 0) {
652  connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
653  }
654  add = numcuts * 2 + 2;
655  }
656  connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
657  }
658 
659  for (i = 0; i < numcuts / 2 + 1; i++) {
660  connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &f_new);
661  }
662 }
663 
664 static const SubDPattern quad_3edge = {
665  {1, 1, 1, 0},
667  4,
668 };
669 
683  BMFace *UNUSED(face),
684  BMVert **verts,
685  const SubDParams *params)
686 {
687  BMFace *f_new;
688  BMVert *v, *v1, *v2;
689  BMEdge *e, *e_new, e_tmp;
690  BMVert **lines;
691  int numcuts = params->numcuts;
692  int i, j, a, b, s = numcuts + 2 /* , totv = numcuts * 4 + 4 */;
693 
694  lines = MEM_callocN(sizeof(BMVert *) * (numcuts + 2) * (numcuts + 2), "q_4edge_split");
695  /* build a 2-dimensional array of verts,
696  * containing every vert (and all new ones)
697  * in the face */
698 
699  /* first line */
700  for (i = 0; i < numcuts + 2; i++) {
701  lines[i] = verts[numcuts * 3 + 2 + (numcuts - i + 1)];
702  }
703 
704  /* last line */
705  for (i = 0; i < numcuts + 2; i++) {
706  lines[(s - 1) * s + i] = verts[numcuts + i];
707  }
708 
709  /* first and last members of middle lines */
710  for (i = 0; i < numcuts; i++) {
711  a = i;
712  b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
713 
714  e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
715  if (!e) {
716  continue;
717  }
718 
721 
722  v1 = lines[(i + 1) * s] = verts[a];
723  v2 = lines[(i + 1) * s + s - 1] = verts[b];
724 
725  e_tmp = *e;
726  for (a = 0; a < numcuts; a++) {
727  v = subdivide_edge_num(bm, e, &e_tmp, a, numcuts, params, v1, v2, &e_new);
728 
729  BMESH_ASSERT(v != NULL);
730 
732  lines[(i + 1) * s + a + 1] = v;
733  }
734  }
735 
736  for (i = 1; i < numcuts + 2; i++) {
737  for (j = 1; j <= numcuts; j++) {
738  a = i * s + j;
739  b = (i - 1) * s + j;
740  e = connect_smallest_face(bm, lines[a], lines[b], &f_new);
741  if (!e) {
742  continue;
743  }
744 
747  }
748  }
749 
750  MEM_freeN(lines);
751 }
752 
765 static void tri_1edge_split(BMesh *bm,
766  BMFace *UNUSED(face),
767  BMVert **verts,
768  const SubDParams *params)
769 {
770  BMFace *f_new;
771  int i, numcuts = params->numcuts;
772 
773  for (i = 0; i < numcuts; i++) {
774  connect_smallest_face(bm, verts[i], verts[numcuts + 1], &f_new);
775  }
776 }
777 
778 static const SubDPattern tri_1edge = {
779  {1, 0, 0},
781  3,
782 };
783 
797  BMFace *UNUSED(face),
798  BMVert **verts,
799  const SubDParams *params)
800 {
801  BMFace *f_new;
802  BMEdge *e, *e_new, e_tmp;
803  BMVert ***lines, *v, v1_tmp, v2_tmp;
804  void *stackarr[1];
805  int i, j, a, b, numcuts = params->numcuts;
806 
807  /* number of verts in each lin */
808  lines = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table");
809 
810  lines[0] = (BMVert **)stackarr;
811  lines[0][0] = verts[numcuts * 2 + 1];
812 
813  lines[numcuts + 1] = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table 2");
814  for (i = 0; i < numcuts; i++) {
815  lines[numcuts + 1][i + 1] = verts[i];
816  }
817  lines[numcuts + 1][0] = verts[numcuts * 3 + 2];
818  lines[numcuts + 1][numcuts + 1] = verts[numcuts];
819 
820  for (i = 0; i < numcuts; i++) {
821  lines[i + 1] = MEM_callocN(sizeof(void *) * (2 + i), "triangle vert table row");
822  a = numcuts * 2 + 2 + i;
823  b = numcuts + numcuts - i;
824  e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
825  if (!e) {
826  goto cleanup;
827  }
828 
831 
832  lines[i + 1][0] = verts[a];
833  lines[i + 1][i + 1] = verts[b];
834 
835  e_tmp = *e;
836  v1_tmp = *verts[a];
837  v2_tmp = *verts[b];
838  e_tmp.v1 = &v1_tmp;
839  e_tmp.v2 = &v2_tmp;
840  for (j = 0; j < i; j++) {
841  v = subdivide_edge_num(bm, e, &e_tmp, j, i, params, verts[a], verts[b], &e_new);
842  lines[i + 1][j + 1] = v;
843 
845  }
846  }
847 
860  for (i = 1; i <= numcuts; i++) {
861  for (j = 0; j < i; j++) {
862  e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);
863 
866 
867  e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &f_new);
868 
871  }
872  }
873 
874 cleanup:
875  for (i = 1; i < numcuts + 2; i++) {
876  if (lines[i]) {
877  MEM_freeN(lines[i]);
878  }
879  }
880 
881  MEM_freeN(lines);
882 }
883 
884 static const SubDPattern tri_3edge = {
885  {1, 1, 1},
887  3,
888 };
889 
890 static const SubDPattern quad_4edge = {
891  {1, 1, 1, 1},
893  4,
894 };
895 
896 static const SubDPattern *patterns[] = {
897  NULL, /* quad single edge pattern is inserted here */
898  NULL, /* quad corner vert pattern is inserted here */
899  NULL, /* tri single edge pattern is inserted here */
900  NULL,
901  &quad_3edge,
902  NULL,
903 };
904 
905 #define PATTERNS_TOT ARRAY_SIZE(patterns)
906 
907 typedef struct SubDFaceData {
909  const SubDPattern *pat;
910  int totedgesel; /* only used if pat was NULL, e.g. no pattern was found */
913 
915 {
916  BMOpSlot *einput;
917  const SubDPattern *pat;
919  BLI_Stack *facedata;
920  BMIter viter, fiter, liter;
921  BMVert *v, **verts = NULL;
922  BMEdge *edge;
923  BMEdge **edges = NULL;
924  BLI_array_declare(edges);
925  BMLoop *(*loops_split)[2] = NULL;
926  BLI_array_declare(loops_split);
927  BMLoop **loops = NULL;
928  BLI_array_declare(loops);
929  BMLoop *l_new, *l;
930  BMFace *face;
932  float smooth, fractal, along_normal;
933  bool use_sphere, use_single_edge, use_grid_fill, use_only_quads;
934  int cornertype, seed, i, j, a, b, numcuts, totesel, smooth_falloff;
935 
937 
938  numcuts = BMO_slot_int_get(op->slots_in, "cuts");
939  seed = BMO_slot_int_get(op->slots_in, "seed");
940  smooth = BMO_slot_float_get(op->slots_in, "smooth");
941  smooth_falloff = BMO_slot_int_get(op->slots_in, "smooth_falloff");
942  fractal = BMO_slot_float_get(op->slots_in, "fractal");
943  along_normal = BMO_slot_float_get(op->slots_in, "along_normal");
944  cornertype = BMO_slot_int_get(op->slots_in, "quad_corner_type");
945 
946  use_single_edge = BMO_slot_bool_get(op->slots_in, "use_single_edge");
947  use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill");
948  use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads");
949  use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
950 
951  patterns[1] = NULL;
952  /* straight cut is patterns[1] == NULL */
953  switch (cornertype) {
954  case SUBD_CORNER_PATH:
956  break;
959  break;
960  case SUBD_CORNER_FAN:
961  patterns[1] = &quad_2edge_fan;
962  break;
963  }
964 
965  if (use_single_edge) {
966  patterns[0] = &quad_1edge;
967  patterns[2] = &tri_1edge;
968  }
969  else {
970  patterns[0] = NULL;
971  patterns[2] = NULL;
972  }
973 
974  if (use_grid_fill) {
975  patterns[3] = &quad_4edge;
976  patterns[5] = &tri_3edge;
977  }
978  else {
979  patterns[3] = NULL;
980  patterns[5] = NULL;
981  }
982 
983  /* add a temporary shapekey layer to store displacements on current geometry */
985 
987 
988  BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
989  float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
990  copy_v3_v3(co, v->co);
991  }
992 
993  /* first go through and tag edges */
995 
996  params.numcuts = numcuts;
997  params.op = op;
998  params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
999  params.slot_custom_patterns = BMO_slot_get(op->slots_in, "custom_patterns");
1000  params.smooth = smooth;
1001  params.smooth_falloff = smooth_falloff;
1002  params.seed = seed;
1003  params.fractal = fractal;
1004  params.along_normal = along_normal;
1005  params.use_smooth = (smooth != 0.0f);
1006  params.use_smooth_even = BMO_slot_bool_get(op->slots_in, "use_smooth_even");
1007  params.use_fractal = (fractal != 0.0f);
1008  params.use_sphere = use_sphere;
1009 
1010  if (params.use_fractal) {
1011  RNG *rng = BLI_rng_new_srandom(seed);
1012 
1013  params.fractal_ofs[0] = BLI_rng_get_float(rng) * 200.0f;
1014  params.fractal_ofs[1] = BLI_rng_get_float(rng) * 200.0f;
1015  params.fractal_ofs[2] = BLI_rng_get_float(rng) * 200.0f;
1016 
1017  BLI_rng_free(rng);
1018  }
1019 
1020  BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns", BM_FACE, FACE_CUSTOMFILL);
1021 
1022  BMO_slot_map_to_flag(bm, op->slots_in, "edge_percents", BM_EDGE, EDGE_PERCENT);
1023 
1024  facedata = BLI_stack_new(sizeof(SubDFaceData), __func__);
1025 
1026  BM_ITER_MESH (face, &fiter, bm, BM_FACES_OF_MESH) {
1027  BMEdge *e1 = NULL, *e2 = NULL;
1028  float vec1[3], vec2[3];
1029  bool matched = false;
1030 
1031  /* skip non-quads if requested */
1032  if (use_only_quads && face->len != 4) {
1033  continue;
1034  }
1035 
1036  /* figure out which pattern to use */
1037 
1038  BLI_array_clear(edges);
1040 
1041  BLI_array_grow_items(edges, face->len);
1042  BLI_array_grow_items(verts, face->len);
1043 
1044  totesel = 0;
1045  BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, i) {
1046  edges[i] = l_new->e;
1047  verts[i] = l_new->v;
1048 
1049  if (BMO_edge_flag_test(bm, edges[i], SUBD_SPLIT)) {
1050  if (!e1) {
1051  e1 = edges[i];
1052  }
1053  else {
1054  e2 = edges[i];
1055  }
1056 
1057  totesel++;
1058  }
1059  }
1060 
1061  /* make sure the two edges have a valid angle to each other */
1062  if (totesel == 2 && BM_edge_share_vert_check(e1, e2)) {
1063  sub_v3_v3v3(vec1, e1->v2->co, e1->v1->co);
1064  sub_v3_v3v3(vec2, e2->v2->co, e2->v1->co);
1065  normalize_v3(vec1);
1066  normalize_v3(vec2);
1067 
1068  if (fabsf(dot_v3v3(vec1, vec2)) > 1.0f - FLT_FACE_SPLIT_EPSILON) {
1069  totesel = 0;
1070  }
1071  }
1072 
1073  if (BMO_face_flag_test(bm, face, FACE_CUSTOMFILL)) {
1074  pat = *BMO_slot_map_data_get(params.slot_custom_patterns, face);
1075  for (i = 0; i < pat->len; i++) {
1076  matched = 1;
1077  for (j = 0; j < pat->len; j++) {
1078  a = (j + i) % pat->len;
1079  if ((!!BMO_edge_flag_test(bm, edges[a], SUBD_SPLIT)) != (!!pat->seledges[j])) {
1080  matched = 0;
1081  break;
1082  }
1083  }
1084  if (matched) {
1085  SubDFaceData *fd;
1086 
1087  fd = BLI_stack_push_r(facedata);
1088  fd->pat = pat;
1089  fd->start = verts[i];
1090  fd->face = face;
1091  fd->totedgesel = totesel;
1093  break;
1094  }
1095  }
1096 
1097  /* Obviously don't test for other patterns matching. */
1098  continue;
1099  }
1100 
1101  for (i = 0; i < PATTERNS_TOT; i++) {
1102  pat = patterns[i];
1103  if (!pat) {
1104  continue;
1105  }
1106 
1107  if (pat->len == face->len) {
1108  for (a = 0; a < pat->len; a++) {
1109  matched = 1;
1110  for (b = 0; b < pat->len; b++) {
1111  j = (b + a) % pat->len;
1112  if ((!!BMO_edge_flag_test(bm, edges[j], SUBD_SPLIT)) != (!!pat->seledges[b])) {
1113  matched = 0;
1114  break;
1115  }
1116  }
1117  if (matched) {
1118  break;
1119  }
1120  }
1121  if (matched) {
1122  SubDFaceData *fd;
1123 
1125 
1126  fd = BLI_stack_push_r(facedata);
1127  fd->pat = pat;
1128  fd->start = verts[a];
1129  fd->face = face;
1130  fd->totedgesel = totesel;
1131  break;
1132  }
1133  }
1134  }
1135 
1136  if (!matched && totesel) {
1137  SubDFaceData *fd;
1138 
1140 
1141  /* must initialize all members here */
1142  fd = BLI_stack_push_r(facedata);
1143  fd->start = NULL;
1144  fd->pat = NULL;
1145  fd->totedgesel = totesel;
1146  fd->face = face;
1147  }
1148  }
1149 
1150  einput = BMO_slot_get(op->slots_in, "edges");
1151 
1152  /* go through and split edges */
1153  for (i = 0; i < einput->len; i++) {
1154  edge = einput->data.buf[i];
1155  bm_subdivide_multicut(bm, edge, &params, edge->v1, edge->v2);
1156  }
1157 
1158  /* copy original-geometry displacements to current coordinates */
1159  BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
1160  const float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
1161  copy_v3_v3(v->co, co);
1162  }
1163 
1164  for (; !BLI_stack_is_empty(facedata); BLI_stack_discard(facedata)) {
1165  SubDFaceData *fd = BLI_stack_peek(facedata);
1166 
1167  face = fd->face;
1168 
1169  /* figure out which pattern to use */
1171 
1172  pat = fd->pat;
1173 
1174  if (!pat && fd->totedgesel == 2) {
1175  int vlen;
1176 
1177  /* ok, no pattern. we still may be able to do something */
1178  BLI_array_clear(loops);
1179  BLI_array_clear(loops_split);
1180 
1181  /* for case of two edges, connecting them shouldn't be too hard */
1182  BLI_array_grow_items(loops, face->len);
1183  BM_ITER_ELEM_INDEX (l, &liter, face, BM_LOOPS_OF_FACE, a) {
1184  loops[a] = l;
1185  }
1186 
1187  vlen = BLI_array_len(loops);
1188 
1189  /* find the boundary of one of the split edges */
1190  for (a = 0; a < vlen; a++) {
1191  if (!BMO_vert_flag_test(bm, loops[a ? (a - 1) : (vlen - 1)]->v, ELE_INNER) &&
1192  BMO_vert_flag_test(bm, loops[a]->v, ELE_INNER)) {
1193  break;
1194  }
1195  }
1196  /* Failure to break means there is an internal error. */
1197  BLI_assert(a < vlen);
1198 
1199  if (BMO_vert_flag_test(bm, loops[(a + numcuts + 1) % vlen]->v, ELE_INNER)) {
1200  b = (a + numcuts + 1) % vlen;
1201  }
1202  else {
1203  /* find the boundary of the other edge. */
1204  for (j = 0; j < vlen; j++) {
1205  b = (j + a + numcuts + 1) % vlen;
1206  if (!BMO_vert_flag_test(bm, loops[b == 0 ? vlen - 1 : b - 1]->v, ELE_INNER) &&
1207  BMO_vert_flag_test(bm, loops[b]->v, ELE_INNER)) {
1208  break;
1209  }
1210  }
1211  }
1212 
1213  b += numcuts - 1;
1214 
1215  BLI_array_grow_items(loops_split, numcuts);
1216  for (j = 0; j < numcuts; j++) {
1217  bool ok = true;
1218 
1219  /* Check for special case, see: T32500.
1220  * This edge pair could be used by more than one face,
1221  * in this case it used to (2.63), split both faces along the same verts
1222  * while it could be calculated which face should do the split,
1223  * it's ambiguous, so in this case we're better off to skip them as exceptional cases
1224  * and not try to be clever guessing which face to cut up.
1225  *
1226  * To avoid this case we need to check:
1227  * Do the verts of each share a face besides the one we are subdividing,
1228  * (but not connect to make an edge of that face).
1229  */
1230  {
1231  BMLoop *other_loop;
1232  BMIter other_fiter;
1233  BM_ITER_ELEM (other_loop, &other_fiter, loops[a]->v, BM_LOOPS_OF_VERT) {
1234  if (other_loop->f != face) {
1235  if (BM_vert_in_face(loops[b]->v, other_loop->f)) {
1236  /* we assume that these verts are not making an edge in the face */
1237  BLI_assert(other_loop->prev->v != loops[a]->v);
1238  BLI_assert(other_loop->next->v != loops[a]->v);
1239 
1240  ok = false;
1241  break;
1242  }
1243  }
1244  }
1245  }
1246 
1247  if (ok == true) {
1248  loops_split[j][0] = loops[a];
1249  loops_split[j][1] = loops[b];
1250  }
1251  else {
1252  loops_split[j][0] = NULL;
1253  loops_split[j][1] = NULL;
1254  }
1255 
1256  b = (b - 1) % vlen;
1257  a = (a + 1) % vlen;
1258  }
1259 
1260  /* Since these are newly created vertices, we don't need to worry about them being legal,
1261  * ... though there are some cases we _should_ check for
1262  * - concave corner of an ngon.
1263  * - 2 edges being used in 2+ ngons.
1264  */
1265  // BM_face_splits_check_legal(bm, face, loops_split, BLI_array_len(loops_split));
1266 
1267  for (j = 0; j < BLI_array_len(loops_split); j++) {
1268  if (loops_split[j][0]) {
1269  BMFace *f_new;
1270  BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL);
1271  f_new = BM_face_split(
1272  bm, face, loops_split[j][0], loops_split[j][1], &l_new, NULL, false);
1273  if (f_new) {
1274  BMO_edge_flag_enable(bm, l_new->e, ELE_INNER);
1275  }
1276  }
1277  }
1278 
1279  continue;
1280  }
1281  if (!pat) {
1282  continue;
1283  }
1284 
1285  a = 0;
1286  BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
1287  if (l_new->v == fd->start) {
1288  a = j + 1;
1289  break;
1290  }
1291  }
1292 
1293  BLI_array_grow_items(verts, face->len);
1294 
1295  BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
1296  b = (j - a + face->len) % face->len;
1297  verts[b] = l_new->v;
1298  }
1299 
1300  BM_CHECK_ELEMENT(face);
1301  pat->connectexec(bm, face, verts, &params);
1302  }
1303 
1304  /* copy original-geometry displacements to current coordinates */
1305  BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
1306  const float *co = BM_ELEM_CD_GET_VOID_P(v, params.shape_info.cd_vert_shape_offset_tmp);
1307  copy_v3_v3(v->co, co);
1308  }
1309 
1310  BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey);
1311 
1312  BLI_stack_free(facedata);
1313  if (edges) {
1314  BLI_array_free(edges);
1315  }
1316  if (verts) {
1318  }
1319  BLI_array_free(loops_split);
1320  BLI_array_free(loops);
1321 
1323  bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER);
1325  bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
1326 
1328  bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
1329 }
1330 
1331 /* editmesh-emulating function */
1333  const char edge_hflag,
1334  const float smooth,
1335  const short smooth_falloff,
1336  const bool use_smooth_even,
1337  const float fractal,
1338  const float along_normal,
1339  const int numcuts,
1340  const int seltype,
1341  const int cornertype,
1342  const short use_single_edge,
1343  const short use_grid_fill,
1344  const short use_only_quads,
1345  const int seed)
1346 {
1347  BMOperator op;
1348 
1349  /* `use_sphere` isn't exposed here since its only used for new primitives. */
1350  BMO_op_initf(bm,
1351  &op,
1353  "subdivide_edges edges=%he "
1354  "smooth=%f smooth_falloff=%i use_smooth_even=%b "
1355  "fractal=%f along_normal=%f "
1356  "cuts=%i "
1357  "quad_corner_type=%i "
1358  "use_single_edge=%b use_grid_fill=%b "
1359  "use_only_quads=%b "
1360  "seed=%i",
1361  edge_hflag,
1362  smooth,
1363  smooth_falloff,
1364  use_smooth_even,
1365  fractal,
1366  along_normal,
1367  numcuts,
1368  cornertype,
1369  use_single_edge,
1370  use_grid_fill,
1371  use_only_quads,
1372  seed);
1373 
1374  BMO_op_exec(bm, &op);
1375 
1376  switch (seltype) {
1377  case SUBDIV_SELECT_NONE:
1378  break;
1379  case SUBDIV_SELECT_ORIG:
1380  /* set the newly created data to be selected */
1382  bm, op.slots_out, "geom_inner.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
1384  break;
1385  case SUBDIV_SELECT_INNER:
1387  bm, op.slots_out, "geom_inner.out", BM_EDGE | BM_VERT, BM_ELEM_SELECT, true);
1388  break;
1389  case SUBDIV_SELECT_LOOPCUT:
1390  /* deselect input */
1393  bm, op.slots_out, "geom_inner.out", BM_EDGE, BM_ELEM_SELECT, true);
1394  break;
1395  }
1396 
1397  BMO_op_finish(bm, &op);
1398 }
1399 
1401 {
1402  BMOIter siter;
1403  BMEdge *e;
1404  SubDParams params = {0};
1405 
1406  params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
1407  params.op = op;
1408  params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
1409 
1411 
1413 
1414  /* tag edges in map */
1415  BMO_slot_map_to_flag(bm, op->slots_in, "edge_percents", BM_EDGE, EDGE_PERCENT);
1416 
1417  /* go through and split edges */
1418  BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
1419  bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
1420  }
1421 
1423  bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
1424 
1425  BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey);
1426 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
int CustomData_number_of_layers(const struct CustomData *data, int type)
int CustomData_get_n_offset(const struct CustomData *data, int type, int n)
int CustomData_get_offset(const struct CustomData *data, int type)
A (mainly) macro array library.
#define BLI_array_grow_items(arr, num)
Definition: BLI_array.h:99
#define BLI_array_declare(arr)
Definition: BLI_array.h:62
#define BLI_array_len(arr)
Definition: BLI_array.h:74
#define BLI_array_clear(arr)
Definition: BLI_array.h:130
#define BLI_array_free(arr)
Definition: BLI_array.h:116
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE float interpf(float a, float b, float t)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:243
MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3])
bool isect_plane_plane_plane_v3(const float plane_a[4], const float plane_b[4], const float plane_c[4], float r_isect_co[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_geom.c:2221
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3])
Definition: math_vector.c:818
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
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])
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
Definition: math_vector.c:777
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Definition: math_vector.c:270
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
Definition: math_vector.c:845
MINLINE float normalize_v3_length(float r[3], const float unit_scale)
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:74
float BLI_noise_generic_turbulence(float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis)
Definition: noise.c:1230
Random number functions.
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition: rand.cc:76
struct RNG * BLI_rng_new_srandom(unsigned int seed)
Definition: rand.cc:64
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: rand.cc:120
void * BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: stack.c:127
void * BLI_stack_peek(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: stack.c:220
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: stack.c:310
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
Definition: stack.c:114
void BLI_stack_discard(BLI_Stack *stack) ATTR_NONNULL()
Definition: stack.c:230
#define BLI_stack_new(esize, descr)
#define UNUSED(x)
#define UNLIKELY(x)
@ CD_SHAPEKEY
NSNotificationCenter * center
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
#define BM_ALL_NOLOOP
Definition: bmesh_class.h:411
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_SELECT
Definition: bmesh_class.h:471
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:530
#define BMESH_ASSERT(a)
Definition: bmesh_error.h:76
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
Definition: bmesh_interp.c:952
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:894
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_VERT
@ BM_LOOPS_OF_FACE
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_select_flush(BMesh *bm)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
BMVert * BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
Edge Split.
Definition: bmesh_mods.c:591
BMFace * BM_face_split(BMesh *bm, BMFace *f, BMLoop *l_a, BMLoop *l_b, BMLoop **r_l, BMEdge *example, const bool no_double)
Face Split.
Definition: bmesh_mods.c:252
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const char hflag, const bool do_flush)
BMO_FLAG_BUFFER.
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const short oflag)
BMO_FLAG_BUFFER.
void BMO_slot_map_to_flag(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const short oflag)
#define BMO_edge_flag_test(bm, e, oflag)
#define BMO_edge_flag_enable(bm, e, oflag)
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_vert_flag_enable(bm, e, oflag)
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt,...)
#define BMO_face_flag_enable(bm, e, oflag)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
#define BMO_vert_flag_test(bm, e, oflag)
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
void BMO_op_finish(BMesh *bm, BMOperator *op)
BMESH OPSTACK FINISH OP.
BMOpSlot * BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
BMESH OPSTACK GET SLOT.
#define BMO_FLAG_DEFAULTS
#define BMO_face_flag_test(bm, e, oflag)
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const short oflag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
@ SUBD_FALLOFF_LIN
@ SUBD_CORNER_FAN
@ SUBD_CORNER_PATH
@ SUBD_CORNER_INNERVERT
@ SUBDIV_SELECT_ORIG
@ SUBDIV_SELECT_INNER
@ SUBDIV_SELECT_LOOPCUT
@ SUBDIV_SELECT_NONE
#define BM_CHECK_ELEMENT(el)
Definition: bmesh_private.h:38
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
Definition: bmesh_query.c:1995
float bmesh_subd_falloff_calc(const int falloff, float val)
Definition: bmesh_query.c:2984
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
Definition: bmesh_query.c:1358
bool BM_vert_in_face(BMVert *v, BMFace *f)
Definition: bmesh_query.c:431
BMFace * BM_vert_pair_share_face_by_len(BMVert *v_a, BMVert *v_b, BMLoop **r_l_a, BMLoop **r_l_b, const bool allow_adjacent)
Definition: bmesh_query.c:261
BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) 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 BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag, const float smooth, const short smooth_falloff, const bool use_smooth_even, const float fractal, const float along_normal, const int numcuts, const int seltype, const int cornertype, const short use_single_edge, const short use_grid_fill, const short use_only_quads, const int seed)
static BMEdge * connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new)
static BMVert * subdivide_edge_num(BMesh *bm, BMEdge *edge, BMEdge *e_orig, int curpoint, int totpoint, const SubDParams *params, BMVert *v_a, BMVert *v_b, BMEdge **r_edge)
#define EDGE_PERCENT
static void interp_slerp_co_no_v3(const float co_a[3], const float no_a[3], const float co_b[3], const float no_b[3], const float no_dir[3], float fac, float r_co[3])
static const SubDPattern quad_1edge
struct SubDParams SubDParams
static const SubDPattern * patterns[]
#define FLT_FACE_SPLIT_EPSILON
void(* subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, const SubDParams *params)
Definition: bmo_subdivide.c:76
struct SubDPattern SubDPattern
static const SubDPattern quad_2edge_fan
static const SubDPattern quad_4edge
static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
static const SubDPattern quad_3edge
static void alter_co(BMVert *v, BMEdge *UNUSED(e_orig), const SubDParams *params, const float perc, const BMVert *v_a, const BMVert *v_b)
#define FACE_CUSTOMFILL
struct SubDFaceData SubDFaceData
static const SubDPattern quad_2edge_path
void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
static BMVert * bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, BMEdge *e_orig, const SubDParams *params, const float factor_edge_split, const float factor_subd, BMVert *v_a, BMVert *v_b, BMEdge **r_edge)
void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
#define ELE_INNER
static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
static void quad_2edge_split_fan(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
#define SUBD_SPLIT
static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
static const SubDPattern tri_1edge
static void bmo_subd_init_shape_info(BMesh *bm, SubDParams *params)
Definition: bmo_subdivide.c:66
static const SubDPattern tri_3edge
static const SubDPattern quad_2edge_innervert
#define ELE_SPLIT
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *params, BMVert *v_a, BMVert *v_b)
static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params)
#define PATTERNS_TOT
static unsigned long seed
Definition: btSoftBody.h:39
static float verts[][3]
IconTextureDrawCall normal
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define fabsf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void add(GHash *messages, MemArena *memarena, const Message *msg)
Definition: msgfmt.c:268
static unsigned a[3]
Definition: RandGen.cpp:92
BMVert * v1
Definition: bmesh_class.h:134
BMVert * v2
Definition: bmesh_class.h:134
struct BMLoop * l
Definition: bmesh_class.h:140
int len
Definition: bmesh_class.h:279
struct BMVert * v
Definition: bmesh_class.h:165
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMLoop * prev
Definition: bmesh_class.h:245
struct BMFace * f
Definition: bmesh_class.h:183
struct BMLoop * next
Definition: bmesh_class.h:245
union BMOpSlot::@139 data
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:99
struct BMEdge * e
Definition: bmesh_class.h:109
float no[3]
Definition: bmesh_class.h:100
CustomData vdata
Definition: bmesh_class.h:337
Definition: rand.cc:48
BMVert * start
BMFace * face
const SubDPattern * pat
bool use_sphere
Definition: bmo_subdivide.c:46
float fractal
Definition: bmo_subdivide.c:41
bool use_smooth_even
Definition: bmo_subdivide.c:45
float fractal_ofs[3]
Definition: bmo_subdivide.c:52
BMOpSlot * slot_custom_patterns
Definition: bmo_subdivide.c:51
int cd_vert_shape_offset
Definition: bmo_subdivide.c:56
BMOperator * op
Definition: bmo_subdivide.c:49
bool use_fractal
Definition: bmo_subdivide.c:47
int cd_vert_shape_offset_tmp
Definition: bmo_subdivide.c:57
struct SubDParams::@160 shape_info
float smooth
Definition: bmo_subdivide.c:39
bool use_smooth
Definition: bmo_subdivide.c:44
int smooth_falloff
Definition: bmo_subdivide.c:40
float along_normal
Definition: bmo_subdivide.c:42
BMOpSlot * slot_edge_percents
Definition: bmo_subdivide.c:50
subd_pattern_fill_fp connectexec
Definition: bmo_subdivide.c:90
int seledges[20]
Definition: bmo_subdivide.c:87
uint len