198 const Mesh *mesh = meshData;
210 const int quad_ord[4] = {
216 const int quad_ord_ofs[4] = {
223 uint maxVerts = 0, maxEdges = 0, maxPolys = 0;
224 const uint totvert =
uint(mesh->verts_num);
225 const uint totedge =
uint(mesh->edges_num);
226 const uint faces_num =
uint(mesh->faces_num);
228 uint *edge_face_map =
nullptr;
229 uint *vert_loop_map =
nullptr;
232 const uint mloopuv_layers_tot =
uint(
237 float uv_v_range_inv;
238 float uv_axis_plane[4];
240 char axis_char =
'X';
242 float angle = ltmd->
angle;
244 float axis_vec[3] = {0.0f, 0.0f, 0.0f};
245 float tmp_vec1[3], tmp_vec2[3];
249 float mtx_tx_inv[4][4];
250 float mtx_tmp_a[4][4];
252 uint vc_tot_linked = 0;
253 short other_axis_1, other_axis_2;
254 const float *tmpf1, *tmpf2;
270 switch (ltmd->
axis) {
285 axis_vec[ltmd->
axis] = 1.0f;
287 if (ob_axis !=
nullptr) {
290 copy_m4_m4(mtx_tx_inv, ob_axis->object_to_world().ptr());
300 float totlen =
len_v3(mtx_tx[3]);
302 if (totlen != 0.0f) {
303 const float zero[3] = {0.0f, 0.0f, 0.0f};
315 if (ltmd->
flag & MOD_SCREW_OBJECT_ANGLE) {
319 float vec[3] = {0, 1, 0};
338 if (
len_v3v3(axis_tmp, axis_vec) > 1.0f) {
346 axis_char = char(axis_char + ltmd->
axis);
350 axis_vec[ltmd->
axis] = 1.0f;
356 uv_u_scale = 1.0f /
float(step_tot);
359 step_tot = ((step_tot + 1) * ltmd->
iter) - (ltmd->
iter - 1);
364 if (
fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) &&
370 maxVerts = totvert * step_tot;
371 maxEdges = (totvert * step_tot) +
372 (totedge * step_tot);
373 maxPolys = totedge * step_tot;
383 maxVerts = totvert * step_tot;
384 maxEdges = (totvert * (step_tot - 1)) +
385 (totedge * step_tot);
386 maxPolys = totedge * (step_tot - 1);
390 uv_u_scale = (uv_u_scale /
float(ltmd->
iter)) * (angle / (
float(
M_PI) * 2.0f));
397 mesh,
int(maxVerts),
int(maxEdges),
int(maxPolys),
int(maxPolys) * 4);
416 "sharp_face", bke::AttrDomain::Face);
422 int *origindex =
static_cast<int *
>(
427 if (mloopuv_layers_tot) {
428 const float zero_co[3] = {0};
432 if (mloopuv_layers_tot) {
434 for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
436 &result->corner_data,
CD_PROP_FLOAT2,
int(uv_lay), result->corners_num));
440 for (
uint i = 0; i < totvert; i++) {
442 uv_v_minmax[0] =
min_ff(
v, uv_v_minmax[0]);
443 uv_v_minmax[1] =
max_ff(
v, uv_v_minmax[1]);
449 uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0];
450 uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f;
457 edge_new = edges_new.
data();
458 for (
uint i = 0; i < totedge; i++, edge_orig++, edge_new++) {
459 *edge_new = *edge_orig;
465 edge_face_map =
static_cast<uint *
>(
467 memset(edge_face_map, 0xff,
sizeof(*edge_face_map) * totedge);
469 vert_loop_map =
static_cast<uint *
>(
471 memset(vert_loop_map, 0xff,
sizeof(*vert_loop_map) * totvert);
474 for (
const int64_t corner : faces_orig[i]) {
475 const int vert_i = corner_verts_orig[corner];
476 const int edge_i = corner_edges_orig[corner];
477 edge_face_map[edge_i] =
uint(i);
478 vert_loop_map[vert_i] =
uint(corner);
481 if (edges_new[edge_i][0] != vert_i) {
482 std::swap(edges_new[edge_i][0], edges_new[edge_i][1]);
504 edge_new = edges_new.
data();
506 if (ob_axis !=
nullptr) {
508 for (
uint i = 0; i < totvert; i++, vc++) {
509 vc->
co[0] = vert_positions_new[i][0] = vert_positions_orig[i][0];
510 vc->
co[1] = vert_positions_new[i][1] = vert_positions_orig[i][1];
511 vc->
co[2] = vert_positions_new[i][2] = vert_positions_orig[i][2];
514 vc->
e[0] = vc->
e[1] =
nullptr;
519 vc->
dist_sq = vc->
co[other_axis_1] * vc->
co[other_axis_1] +
520 vc->
co[other_axis_2] * vc->
co[other_axis_2];
526 for (
uint i = 0; i < totvert; i++, vc++) {
527 vc->
co[0] = vert_positions_new[i][0] = vert_positions_orig[i][0];
528 vc->
co[1] = vert_positions_new[i][1] = vert_positions_orig[i][1];
529 vc->
co[2] = vert_positions_new[i][2] = vert_positions_orig[i][2];
532 vc->
e[0] = vc->
e[1] =
nullptr;
536 vc->
dist_sq = vc->
co[other_axis_1] * vc->
co[other_axis_1] +
537 vc->
co[other_axis_2] * vc->
co[other_axis_2];
544 for (
uint i = 0; i < totedge; i++, edge_new++) {
545 vc = &vert_connect[(*edge_new)[0]];
548 vc->
v[0] =
uint((*edge_new)[1]);
552 vc->
v[1] =
uint((*edge_new)[1]);
559 vc = &vert_connect[(*edge_new)[1]];
563 vc->
v[0] =
uint((*edge_new)[0]);
567 vc->
v[1] =
uint((*edge_new)[0]);
577 for (
uint i = 0; i < totvert; i++, vc++) {
587 bool ed_loop_flip =
false;
591 for (j = 0; j < 2; j++) {
608 if (fl <= lt_iter.v_poin->dist_sq) {
627 if (vc_tot_linked > 1) {
628 float vf_1, vf_2, vf_best;
630 vc_tmp = &vert_connect[v_best];
632 tmpf1 = vert_connect[vc_tmp->
v[0]].
co;
633 tmpf2 = vert_connect[vc_tmp->
v[1]].
co;
640 vf_1 = tmpf1[ltmd->
axis];
641 vf_2 = tmpf2[ltmd->
axis];
642 vf_best = vc_tmp->
co[ltmd->
axis];
644 if (vf_1 < vf_best && vf_best < vf_2) {
645 ed_loop_flip =
false;
647 else if (vf_1 > vf_best && vf_best > vf_2) {
657 if (tmp_vec1[ltmd->
axis] < tmp_vec2[ltmd->
axis]) {
661 ed_loop_flip =
false;
667 if (tmpf1[ltmd->
axis] < vc_tmp->
co[ltmd->
axis]) {
671 ed_loop_flip =
false;
676 printf(
"No Connected ___\n");
686 ed_loop_flip = !ed_loop_flip;
691 ed_loop_flip = !ed_loop_flip;
695 for (j = ed_loop_closed; j < 2; j++) {
706 ed_loop_flip = !ed_loop_flip;
714 if (lt_iter.
v ==
uint((*lt_iter.
e)[0])) {
715 if (ed_loop_flip == 0) {
717 std::swap((*lt_iter.
e)[0], (*lt_iter.
e)[1]);
721 printf(
"\t\t\tFlipping Not 0\n");
725 else if (lt_iter.
v ==
uint((*lt_iter.
e)[1])) {
726 if (ed_loop_flip == 1) {
728 std::swap((*lt_iter.
e)[0], (*lt_iter.
e)[1]);
732 printf(
"\t\t\tFlipping Not 1\n");
738 printf(
"\t\tIncorrect edge topology");
744 printf(
"\t\tNo Edge at this point\n");
756 for (
uint i = 0; i < totvert; i++) {
757 copy_v3_v3(vert_positions_new[i], vert_positions_orig[i]);
763 for (step = 1; step < step_tot; step++) {
764 const uint varray_stride = totvert * step;
768 step_angle = (angle /
float(step_tot - (!close))) *
float(step);
770 if (ob_axis !=
nullptr) {
779 madd_v3_v3fl(mat[3], axis_vec, screw_ofs * (
float(step) /
float(step_tot - 1)));
784 &mesh->vert_data, &result->vert_data, 0,
int(varray_stride),
int(totvert));
787 for (j = 0; j < totvert; j++) {
788 const int vert_new =
int(varray_stride) +
int(j);
790 copy_v3_v3(vert_positions_new[vert_new], vert_positions_new[j]);
795 if (ob_axis !=
nullptr) {
796 sub_v3_v3(vert_positions_new[vert_new], mtx_tx[3]);
798 mul_m4_v3(mat, vert_positions_new[vert_new]);
800 add_v3_v3(vert_positions_new[vert_new], mtx_tx[3]);
803 mul_m4_v3(mat, vert_positions_new[vert_new]);
807 (*edge_new)[0] =
int(varray_stride + j);
808 (*edge_new)[1] = (*edge_new)[0] -
int(totvert);
816 vert_connect =
nullptr;
821 const uint varray_stride = (step_tot - 1) * totvert;
823 for (
uint i = 0; i < totvert; i++) {
824 (*edge_new)[0] =
int(i);
825 (*edge_new)[1] =
int(varray_stride + i);
830 int new_loop_index = 0;
831 med_new_firstloop = edges_new.
data();
834 edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1)));
837 const VArraySpan src_material_index = *src_attributes.lookup<
int>(
"material_index",
838 bke::AttrDomain::Face);
842 "material_index", bke::AttrDomain::Face);
844 for (
uint i = 0; i < totedge; i++, med_new_firstloop++) {
845 const uint step_last = step_tot - (close ? 1 : 2);
846 const uint face_index_orig = faces_num ? edge_face_map[i] :
UINT_MAX;
847 const bool has_mpoly_orig = (face_index_orig !=
UINT_MAX);
848 float uv_v_offset_a, uv_v_offset_b;
850 const uint mloop_index_orig[2] = {
851 vert_loop_map ? vert_loop_map[edges_new[i][0]] :
UINT_MAX,
852 vert_loop_map ? vert_loop_map[edges_new[i][1]] :
UINT_MAX,
854 const bool has_mloop_orig = mloop_index_orig[0] !=
UINT_MAX;
859 i1 =
uint((*med_new_firstloop)[0]);
860 i2 =
uint((*med_new_firstloop)[1]);
862 if (has_mpoly_orig) {
863 mat_nr = src_material_index.
is_empty() ? 0 : src_material_index[face_index_orig];
869 if (has_mloop_orig ==
false && mloopuv_layers_tot) {
874 uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv;
875 uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv;
879 for (step = 0; step <= step_last; step++) {
882 if (has_mpoly_orig) {
884 &mesh->face_data, &result->face_data,
int(face_index_orig),
int(face_index), 1);
885 origindex[face_index] =
int(face_index_orig);
889 dst_material_index.
span[face_index] = mat_nr;
890 sharp_faces.
span[face_index] = use_flat_shading;
892 face_offests_new[face_index] = face_index * 4;
895 if (has_mloop_orig) {
898 &result->corner_data,
899 int(mloop_index_orig[0]),
903 &result->corner_data,
904 int(mloop_index_orig[1]),
908 &result->corner_data,
909 int(mloop_index_orig[1]),
913 &result->corner_data,
914 int(mloop_index_orig[0]),
918 if (mloopuv_layers_tot) {
920 const float uv_u_offset_a =
float(step) * uv_u_scale;
921 const float uv_u_offset_b =
float(step + 1) * uv_u_scale;
922 for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
925 mluv[quad_ord[0]][0] += uv_u_offset_a;
926 mluv[quad_ord[1]][0] += uv_u_offset_a;
927 mluv[quad_ord[2]][0] += uv_u_offset_b;
928 mluv[quad_ord[3]][0] += uv_u_offset_b;
933 if (mloopuv_layers_tot) {
935 const float uv_u_offset_a =
float(step) * uv_u_scale;
936 const float uv_u_offset_b =
float(step + 1) * uv_u_scale;
937 for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
940 copy_v2_fl2(mluv[quad_ord[0]], uv_u_offset_a, uv_v_offset_a);
941 copy_v2_fl2(mluv[quad_ord[1]], uv_u_offset_a, uv_v_offset_b);
942 copy_v2_fl2(mluv[quad_ord[2]], uv_u_offset_b, uv_v_offset_b);
943 copy_v2_fl2(mluv[quad_ord[3]], uv_u_offset_b, uv_v_offset_a);
949 if (!(close && step == step_last)) {
951 corner_verts_new[new_loop_index + quad_ord[0]] =
int(i1);
952 corner_verts_new[new_loop_index + quad_ord[1]] =
int(i2);
953 corner_verts_new[new_loop_index + quad_ord[2]] =
int(i2 + totvert);
954 corner_verts_new[new_loop_index + quad_ord[3]] =
int(i1 + totvert);
956 corner_edges_new[new_loop_index + quad_ord_ofs[0]] =
int(
957 step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1);
958 corner_edges_new[new_loop_index + quad_ord_ofs[1]] =
int(totedge + i2);
959 corner_edges_new[new_loop_index + quad_ord_ofs[2]] =
int(edge_offset + step +
960 (i * (step_tot - 1)));
961 corner_edges_new[new_loop_index + quad_ord_ofs[3]] =
int(totedge + i1);
965 (*edge_new)[0] =
int(i1);
966 (*edge_new)[1] =
int(i2);
974 corner_verts_new[new_loop_index + quad_ord[0]] =
int(i1);
975 corner_verts_new[new_loop_index + quad_ord[1]] =
int(i2);
976 corner_verts_new[new_loop_index + quad_ord[2]] =
int((*med_new_firstloop)[1]);
977 corner_verts_new[new_loop_index + quad_ord[3]] =
int((*med_new_firstloop)[0]);
979 corner_edges_new[new_loop_index + quad_ord_ofs[0]] =
int(
980 (edge_offset + step + (i * (step_tot - 1))) - 1);
981 corner_edges_new[new_loop_index + quad_ord_ofs[1]] =
int(totedge + i2);
982 corner_edges_new[new_loop_index + quad_ord_ofs[2]] =
int(i);
983 corner_edges_new[new_loop_index + quad_ord_ofs[3]] =
int(totedge + i1);
991 (*edge_new)[0] =
int(i1);
992 (*edge_new)[1] =
int(i2);
1001 for (; i < maxPolys * 4; i += 4) {
1003 ml_new = mloop_new + i;
1004 ii = findEd(edges_new, maxEdges, ml_new[0].
v, ml_new[1].
v);
1005 printf(
"%d %d -- ", ii, ml_new[0].
e);
1008 ii = findEd(edges_new, maxEdges, ml_new[1].
v, ml_new[2].
v);
1009 printf(
"%d %d -- ", ii, ml_new[1].
e);
1012 ii = findEd(edges_new, maxEdges, ml_new[2].
v, ml_new[3].
v);
1013 printf(
"%d %d -- ", ii, ml_new[2].
e);
1016 ii = findEd(edges_new, maxEdges, ml_new[3].
v, ml_new[0].
v);
1017 printf(
"%d %d\n", ii, ml_new[3].
e);
1025 if (edge_face_map) {
1029 if (vert_loop_map) {
1033 if (do_remove_doubles) {
1039 ob_axis !=
nullptr ? mtx_tx[3] :
nullptr,
1043 dst_material_index.
finish();