61 params->shape_info.tmpkey = skey;
102#define FACE_CUSTOMFILL 4
107#define FLT_FACE_SPLIT_EPSILON 0.00005f
148 return l_new ? l_new->
e :
nullptr;
162 const float no_dir[3],
174 float no_mid[3], no_ortho[3];
189 bool center_ok =
false;
192 float plane_a[4], plane_b[4], plane_c[4];
193 float v_a_no_ortho[3], v_b_no_ortho[3];
210 if (center_ok ==
false) {
217 float ofs_a[3], ofs_b[3], ofs_slerp[3];
218 float dist_a, dist_b;
243 float *co =
static_cast<float *
>(
252 else if (
params->use_smooth) {
255#define USE_SPHERE_DUAL_BLEND
257 const float eps_unit_vec = 1e-5f;
261#ifdef USE_SPHERE_DUAL_BLEND
262 float no_reflect[3], co_a[3], co_b[3];
268#ifndef USE_SPHERE_DUAL_BLEND
303 smooth =
fabsf(1.0f - 2.0f *
fabsf(0.5f - perc));
307 if (
params->use_smooth_even) {
312 if (smooth != 1.0f) {
318#undef USE_SPHERE_DUAL_BLEND
321 if (
params->use_fractal) {
322 float normal[3], co2[3], base1[3], base2[3], tvec[3];
353 if (
params->shape_info.totlayer > 1) {
359 i =
params->shape_info.totlayer - 1;
375 const float factor_edge_split,
376 const float factor_subd,
393 if (edge->v1->f2 & edge->v2->f2 & 1) {
396 if (edge->v1->f2 & edge->v2->f2 & 2) {
399 if (edge->v1->f2 & edge->v2->f2 & 4) {
422 float factor_edge_split, factor_subd;
425 factor_edge_split = BMO_slot_map_float_get(
params->slot_edge_percents, edge);
429 factor_edge_split = 1.0f /
float(totpoint + 1 - curpoint);
430 factor_subd =
float(curpoint + 1) /
float(totpoint + 1);
434 bm, edge, e_orig,
params, factor_edge_split, factor_subd, v_a, v_b, r_edge);
441 BMEdge *eed = edge, *e_new, e_tmp = *edge;
442 BMVert *
v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *
v2 = edge->v2;
443 int i, numcuts =
params->numcuts;
448 for (i = 0; i < numcuts; i++) {
459 if (
v->
e &&
v->
e->
l) {
491 if ((numcuts % 2) == 0) {
493 for (i = 0; i < numcuts; i++) {
494 if (i == numcuts / 2) {
502 for (i = 0; i < numcuts; i++) {
504 if (i == numcuts / 2) {
534 int i, numcuts =
params->numcuts;
536 for (i = 0; i < numcuts; i++) {
566 int i, numcuts =
params->numcuts;
568 v_last =
verts[numcuts];
570 for (i = numcuts - 1; i >= 0; i--) {
576 if (i != numcuts - 1) {
611 int i, numcuts =
params->numcuts;
613 for (i = 0; i < numcuts; i++) {
643 int i, add = 0, numcuts =
params->numcuts;
645 for (i = 0; i < numcuts; i++) {
646 if (i == numcuts / 2) {
647 if (numcuts % 2 != 0) {
650 add = numcuts * 2 + 2;
655 for (i = 0; i < numcuts / 2 + 1; i++) {
687 int numcuts =
params->numcuts;
688 int i, j, a,
b, s = numcuts + 2 ;
690 lines =
static_cast<BMVert **
>(
697 for (i = 0; i < numcuts + 2; i++) {
698 lines[i] =
verts[numcuts * 3 + 2 + (numcuts - i + 1)];
702 for (i = 0; i < numcuts + 2; i++) {
703 lines[(s - 1) * s + i] =
verts[numcuts + i];
707 for (i = 0; i < numcuts; i++) {
709 b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
719 v1 = lines[(i + 1) * s] =
verts[a];
720 v2 = lines[(i + 1) * s + s - 1] =
verts[
b];
723 for (a = 0; a < numcuts; a++) {
729 lines[(i + 1) * s + a + 1] =
v;
733 for (i = 1; i < numcuts + 2; i++) {
734 for (j = 1; j <= numcuts; j++) {
765 int i, numcuts =
params->numcuts;
767 for (i = 0; i < numcuts; i++) {
797 BMVert ***lines, *
v, v1_tmp, v2_tmp;
799 int i, j, a,
b, numcuts =
params->numcuts;
802 lines =
static_cast<BMVert ***
>(
803 MEM_callocN(
sizeof(
void *) * (numcuts + 2),
"triangle vert table"));
805 lines[0] = (
BMVert **)stackarr;
806 lines[0][0] =
verts[numcuts * 2 + 1];
808 lines[numcuts + 1] =
static_cast<BMVert **
>(
809 MEM_callocN(
sizeof(
void *) * (numcuts + 2),
"triangle vert table 2"));
810 for (i = 0; i < numcuts; i++) {
811 lines[numcuts + 1][i + 1] =
verts[i];
813 lines[numcuts + 1][0] =
verts[numcuts * 3 + 2];
814 lines[numcuts + 1][numcuts + 1] =
verts[numcuts];
816 for (i = 0; i < numcuts; i++) {
817 lines[i + 1] =
static_cast<BMVert **
>(
818 MEM_callocN(
sizeof(
void *) * (2 + i),
"triangle vert table row"));
819 a = numcuts * 2 + 2 + i;
820 b = numcuts + numcuts - i;
829 lines[i + 1][0] =
verts[a];
830 lines[i + 1][i + 1] =
verts[
b];
837 for (j = 0; j < i; j++) {
839 lines[i + 1][j + 1] =
v;
857 for (i = 1; i <= numcuts; i++) {
858 for (j = 0; j < i; j++) {
872 for (i = 1; i < numcuts + 2; i++) {
902#define PATTERNS_TOT ARRAY_SIZE(patterns)
917 BMIter viter, fiter, liter;
922 float smooth, fractal, along_normal;
923 bool use_sphere, use_single_edge, use_grid_fill, use_only_quads;
924 int cornertype,
seed, i, j, a,
b, numcuts, totesel, smooth_falloff;
943 switch (cornertype) {
955 if (use_single_edge) {
979 float *co =
static_cast<float *
>(
992 params.smooth_falloff = smooth_falloff;
995 params.along_normal = along_normal;
996 params.use_smooth = (smooth != 0.0f);
998 params.use_fractal = (fractal != 0.0f);
999 params.use_sphere = use_sphere;
1001 if (
params.use_fractal) {
1021 BMEdge *e1 =
nullptr, *e2 =
nullptr;
1022 float vec1[3], vec2[3];
1023 bool matched =
false;
1026 if (use_only_quads && face->len != 4) {
1031 verts.reinitialize(face->len);
1032 edges.reinitialize(face->len);
1036 edges[i] = l_new->
e;
1065 *BMO_slot_map_data_get(
params.slot_custom_patterns, face));
1066 for (i = 0; i < pat->
len; i++) {
1068 for (j = 0; j < pat->
len; j++) {
1069 a = (j + i) % pat->
len;
1098 if (pat->
len == face->len) {
1099 for (a = 0; a < pat->
len; a++) {
1101 for (
b = 0;
b < pat->
len;
b++) {
1102 j = (
b + a) % pat->
len;
1127 if (!matched && totesel) {
1134 fd->
start =
nullptr;
1144 for (i = 0; i < einput->
len; i++) {
1151 const float *co =
static_cast<const float *
>(
1156 using LoopPair = std::array<BMLoop *, 2>;
1171 loops.reinitialize(face->len);
1176 const int64_t vlen = loops.size();
1179 for (a = 0; a < vlen; a++) {
1190 b = (a + numcuts + 1) % vlen;
1194 for (j = 0; j < vlen; j++) {
1195 b = (j + a + numcuts + 1) % vlen;
1207 for (j = 0; j < numcuts; j++) {
1225 if (other_loop->
f != face) {
1239 loops_split[j][0] = loops[a];
1240 loops_split[j][1] = loops[
b];
1243 loops_split[j][0] =
nullptr;
1244 loops_split[j][1] =
nullptr;
1258 for (
const LoopPair &loop_split : loops_split) {
1259 if (loop_split[0]) {
1262 f_new =
BM_face_split(
bm, face, loop_split[0], loop_split[1], &l_new,
nullptr,
false);
1277 if (l_new->
v == fd->
start) {
1283 verts.reinitialize(face->len);
1285 b = (j - a + face->len) % face->len;
1295 const float *co =
static_cast<const float *
>(
1315 const char edge_hflag,
1317 const short smooth_falloff,
1318 const bool use_smooth_even,
1319 const float fractal,
1320 const float along_normal,
1323 const int cornertype,
1324 const short use_single_edge,
1325 const short use_grid_fill,
1326 const short use_only_quads,
1335 "subdivide_edges edges=%he "
1336 "smooth=%f smooth_falloff=%i use_smooth_even=%b "
1337 "fractal=%f along_normal=%f "
1339 "quad_corner_type=%i "
1340 "use_single_edge=%b use_grid_fill=%b "
1341 "use_only_quads=%b "
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
MINLINE float interpf(float target, float origin, float t)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
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
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)
bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], float t) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3(float r[3], const float a[3])
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[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])
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
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
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])
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE float normalize_v3_length(float n[3], float unit_length)
MINLINE float normalize_v3(float n[3])
float BLI_noise_generic_turbulence(float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis)
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
struct RNG * BLI_rng_new_srandom(unsigned int seed)
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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)
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#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.
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.
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
BMO_FLAG_BUFFER.
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
#define BMO_edge_flag_test(bm, e, oflag)
void BMO_slot_map_to_flag(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short 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)
BMOpSlot * BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
BMESH OPSTACK GET SLOT.
void BMO_op_exec(BMesh *bm, BMOperator *op)
BMESH OPSTACK EXEC OP.
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
#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)
bool BMO_op_initf(BMesh *bm, BMOperator *op, int flag, const char *fmt,...)
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.
#define BMO_FLAG_DEFAULTS
#define BMO_face_flag_test(bm, e, oflag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BM_CHECK_ELEMENT(el)
float bmesh_subd_falloff_calc(const int falloff, float val)
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
BMEdge * BM_edge_exists(BMVert *v_a, BMVert *v_b)
bool BM_vert_in_face(BMVert *v, BMFace *f)
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)
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 void quad_2edge_split_path(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
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
static void quad_2edge_split_fan(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static void quad_3edge_split(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static void tri_1edge_split(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static const SubDPattern * patterns[]
#define FLT_FACE_SPLIT_EPSILON
void(* subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, const SubDParams *params)
static const SubDPattern quad_2edge_fan
static const SubDPattern quad_4edge
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)
static void alter_co(BMVert *v, BMEdge *, const SubDParams *params, const float perc, const BMVert *v_a, const BMVert *v_b)
static const SubDPattern quad_3edge
static const SubDPattern quad_2edge_path
void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
static void quad_2edge_split_innervert(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
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)
static void tri_3edge_subdivide(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static const SubDPattern tri_1edge
static void quad_1edge_split(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static void bmo_subd_init_shape_info(BMesh *bm, SubDParams *params)
static void quad_4edge_subdivide(BMesh *bm, BMFace *, BMVert **verts, const SubDParams *params)
static const SubDPattern tri_3edge
static BMEdge * connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new)
static const SubDPattern quad_2edge_innervert
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *params, BMVert *v_a, BMVert *v_b)
static unsigned long seed
void reinitialize(const int64_t new_size)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
union BMOpSlot::@139 data
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
BMOpSlot * slot_custom_patterns
int cd_vert_shape_offset_tmp
struct SubDParams::@160 shape_info
BMOpSlot * slot_edge_percents
subd_pattern_fill_fp connectexec