205 only_selected_uvs =
options.only_selected_uvs;
206 only_selected_faces =
options.only_selected_faces;
207 use_seams = !
options.topology_from_uvs ||
options.topology_from_uvs_use_seams;
208 correct_aspect =
options.correct_aspect;
209 pin_unselected =
options.pin_unselected;
217 bool subsurf =
options->use_subsurf;
240 *r_use_subsurf = subsurf;
248 options.topology_from_uvs =
false;
249 options.topology_from_uvs_use_seams =
false;
250 options.only_selected_faces =
false;
251 options.only_selected_uvs =
false;
252 options.pin_unselected =
false;
254 options.slim.skip_init =
false;
292 if (
options.weight_group[0] ==
'\0' ||
options.use_weights ==
false) {
293 options.slim.weight_influence = 0.0f;
305 bool use_subsurf_final;
307 options.use_subsurf = use_subsurf_final;
354 int value_i = *value_p;
435 if (offsets.
uv == -1) {
457 if (
options->only_selected_uvs && !
l) {
471 bool have_select =
false;
472 for (
Object *obedit : objects) {
483 const int material_index,
487 if (
UNLIKELY(material_index < 0 || material_index >= ob->
totcol)) {
502 bool selected =
false;
517 return aspect[0] / aspect[1];
533 if (
options->only_selected_uvs) {
559 if (
options->pin_unselected && !pin) {
576 const int cd_weight_offset,
577 const int cd_weight_index)
606 if (cd_weight_offset >= 0 && cd_weight_index >= 0) {
631 if (
options->topology_from_uvs && !
options->topology_from_uvs_use_seams) {
636 if (offsets.
uv == -1) {
673 int *r_count_failed =
nullptr)
701 handle, scene, efa, i,
options, offsets, cd_weight_offset, cd_weight_index);
708 handle,
options->fill_holes,
options->topology_from_uvs, r_count_failed);
736 for (
Object *obedit : objects) {
742 if (offsets.
uv == -1) {
758 handle, scene, efa, i + offset,
options, offsets, cd_weight_offset, cd_weight_index);
768 handle,
options->fill_holes,
options->topology_from_uvs,
nullptr);
809 em->
bm,
nullptr,
static_cast<const Mesh *
>(object->data));
818 if (settings.level == 1) {
845 int *r_count_failed =
nullptr)
884 const int *origVertIndices =
static_cast<const int *
>(
886 const int *origEdgeIndices =
static_cast<const int *
>(
888 const int *origPolyIndices =
static_cast<const int *
>(
898 for (
int i = 0; i < subdiv_mesh->
faces_num; i++) {
902 edgeMap =
static_cast<BMEdge **
>(
906 for (
int i = 0; i < subdiv_mesh->
edges_num; i++) {
915 ParamKey key, vkeys[4];
940 vkeys[0] = (
ParamKey)poly_corner_verts[0];
941 vkeys[1] = (
ParamKey)poly_corner_verts[1];
942 vkeys[2] = (
ParamKey)poly_corner_verts[2];
943 vkeys[3] = (
ParamKey)poly_corner_verts[3];
945 co[0] = subsurf_positions[poly_corner_verts[0]];
946 co[1] = subsurf_positions[poly_corner_verts[1]];
947 co[2] = subsurf_positions[poly_corner_verts[2]];
948 co[3] = subsurf_positions[poly_corner_verts[3]];
951 if (cd_weight_index >= 0) {
974 origVertIndices[poly_corner_verts[0]],
981 origVertIndices[poly_corner_verts[1]],
988 origVertIndices[poly_corner_verts[2]],
995 origVertIndices[poly_corner_verts[3]],
1001 handle, key, 4, vkeys, co, uv, weight, pin,
select);
1016 handle,
options->fill_holes,
options->topology_from_uvs, r_count_failed);
1048 options.topology_from_uvs =
true;
1050 options.only_selected_faces =
true;
1051 options.only_selected_uvs =
true;
1052 options.correct_aspect =
true;
1061 MinStretch *ms = MEM_new<MinStretch>(__func__);
1071 if (ms->
blend != 0.0f) {
1169 for (i = 0; i < iterations; i++) {
1196 switch (event->
type) {
1209 if (ms->
blend < 0.95f) {
1220 if (ms->
blend > 0.05f) {
1255 ot->
name =
"Minimize Stretch";
1256 ot->
idname =
"UV_OT_minimize_stretch";
1258 ot->
description =
"Reduce UV stretching by relaxing angles";
1272 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
1273 "preserve symmetry");
1280 "Blend factor between stretch minimized and original",
1289 "Number of iterations to run, 0 is unlimited when run interactively",
1297 const float matrix[2][2],
1298 const float pre_translate[2]
1312 const int cd_loop_uv_offset = island->
offsets.
uv;
1313 const int faces_len = island->
faces_len;
1314 for (
int i = 0; i < faces_len; i++) {
1329 const float coords[2],
1330 float nearest_tile_co[2])
1335 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1336 add_v2_fl(nearest_tile_center_co, 0.5f);
1345 const float coords[2],
1346 float nearest_tile_co[2])
1348 const float coords_floor[2] = {
floorf(coords[0]),
floorf(coords[1])};
1350 if (coords[0] > udim_grid[0]) {
1351 nearest_tile_co[0] = udim_grid[0] - 1;
1353 else if (coords[0] < 0) {
1354 nearest_tile_co[0] = 0;
1357 nearest_tile_co[0] = coords_floor[0];
1360 if (coords[1] > udim_grid[1]) {
1361 nearest_tile_co[1] = udim_grid[1] - 1;
1363 else if (coords[1] < 0) {
1364 nearest_tile_co[1] = 0;
1367 nearest_tile_co[1] = coords_floor[1];
1371 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1372 add_v2_fl(nearest_tile_center_co, 0.5f);
1381 const bool pin_unselected =
params->pin_unselected;
1382 const bool only_selected_faces =
params->only_selected_faces;
1386 for (
int i = 0; i < island->
faces_len; i++) {
1419 BMesh **bmesh_override,
1421 const bool original_selection,
1422 const bool notify_wm,
1428 for (
const int ob_index : objects.index_range()) {
1429 Object *obedit = objects[ob_index];
1431 if (bmesh_override) {
1433 bm = bmesh_override[ob_index];
1442 if (offsets.
uv == -1) {
1448 bool only_selected_faces =
params->only_selected_faces;
1449 bool only_selected_uvs =
params->only_selected_uvs;
1451 if (ignore_pinned &&
params->pin_unselected) {
1452 only_selected_faces =
false;
1453 only_selected_uvs =
false;
1459 only_selected_faces,
1469 if (ignore_pinned && pinned) {
1474 island_vector.
append(island);
1475 pinned_vector.
append(pinned);
1484 float selection_min_co[2], selection_max_co[2];
1487 for (
int index = 0; index < island_vector.
size(); index++) {
1490 for (
int i = 0; i < island->
faces_len; i++) {
1497 float selection_center[2];
1498 mid_v2_v2v2(selection_center, selection_min_co, selection_max_co);
1500 if (original_selection) {
1502 if ((selection_max_co[0] - selection_min_co[0]) * (selection_max_co[1] - selection_min_co[1]) >
1506 params->target_extent = selection_max_co[1] - selection_min_co[1];
1507 params->target_aspect_y = (selection_max_co[0] - selection_min_co[0]) /
1508 (selection_max_co[1] - selection_min_co[1]);
1516 for (
int i = 0; i < island_vector.
size(); i++) {
1521 pack_island->
pinned = pinned_vector[i];
1522 pack_island_vector.
append(pack_island);
1524 for (
int i = 0; i < face_island->
faces_len; i++) {
1547 const bool is_cancelled =
params->isCancelled();
1549 float base_offset[2] = {0.0f, 0.0f};
1552 if (udim_source_closest) {
1553 const Image *image = udim_source_closest->
image;
1557 if (is_valid_udim) {
1558 base_offset[0] =
floorf(selection_center[0]);
1559 base_offset[1] =
floorf(selection_center[1]);
1564 float nearest_image_tile_dist =
FLT_MAX, nearest_grid_tile_dist =
FLT_MAX;
1567 image, selection_center, nearest_image_tile_co);
1570 float nearest_grid_tile_co[2] = {0.0f, 0.0f};
1572 udim_grid, selection_center, nearest_grid_tile_co);
1574 base_offset[0] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1575 nearest_image_tile_co[0] :
1576 nearest_grid_tile_co[0];
1577 base_offset[1] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1578 nearest_image_tile_co[1] :
1579 nearest_grid_tile_co[1];
1584 float matrix_inverse[2][2];
1585 float pre_translate[2];
1592 const float island_scale = pack_island->
can_scale_(*
params) ? scale : 1.0f;
1597 mul_v2_m2v2(pre_translate, matrix_inverse, base_offset);
1610 pack_island_vector[i] =
nullptr;
1614 if (notify_wm && !is_cancelled) {
1615 for (
Object *obedit : objects) {
1708 options.topology_from_uvs =
true;
1709 options.only_selected_faces =
true;
1710 options.only_selected_uvs =
true;
1712 options.correct_aspect =
true;
1734 pid->
objects = std::move(objects);
1743 pack_island_params = default_params;
1808 "Use scale of existing UVs to multiply margin"},
1814 "Specify a precise fraction of final UV output"},
1815 {0,
nullptr, 0,
nullptr,
nullptr},
1824 "Only 90 degree rotations are allowed"},
1827#define PACK_ROTATE_METHOD_AXIS_ALIGNED_OFFSET 3
1832 "Rotated to a minimal rectangle, either vertical or horizontal"},
1836 "Axis-aligned (Horizontal)",
1837 "Rotate islands to be aligned horizontally"},
1841 "Axis-aligned (Vertical)",
1842 "Rotate islands to be aligned vertically"},
1843 {0,
nullptr, 0,
nullptr,
nullptr},
1851 {0,
nullptr, 0,
nullptr,
nullptr},
1866 "Rotation and Scale",
1867 "Pinned islands will translate only"},
1869 {0,
nullptr, 0,
nullptr,
nullptr},
1914 "Pack islands to active UDIM image tile or UDIM grid tile where 2D cursor is located"},
1918 "Original bounding box",
1919 "Pack to starting bounding box of islands"},
1920 {0,
nullptr, 0,
nullptr,
nullptr},
1923 ot->
name =
"Pack Islands";
1926 "Transform all islands so that they fill up the UV/UDIM space as much as possible";
1928#ifdef USE_INTERACTIVE_PACK
1938#ifdef USE_INTERACTIVE_PACK
1957 ot->
srna,
"merge_overlap",
false,
"Merge Overlapping",
"Overlapping islands stick together");
1965 ot->
srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
1969 "Lock Pinned Islands",
1970 "Constrain islands containing any pinned UV's");
1999 options.topology_from_uvs =
true;
2000 options.only_selected_faces =
true;
2001 options.only_selected_uvs =
true;
2003 options.correct_aspect =
true;
2021 for (
Object *obedit : objects) {
2037 ot->
name =
"Average Islands Scale";
2038 ot->
idname =
"UV_OT_average_islands_scale";
2039 ot->
description =
"Average the size of separate UV islands, based on their area in 3D space";
2098 options.topology_from_uvs =
false;
2099 options.only_selected_faces =
false;
2100 options.only_selected_uvs =
false;
2111 options.slim.skip_init =
true;
2197#define VIEW_ON_EQUATOR 0
2198#define VIEW_ON_POLES 1
2199#define ALIGN_TO_OBJECT 2
2225 uint center_accum_num = 0;
2232 center_accum_num += 1;
2235 mul_v3_fl(r_center, 1.0f /
float(center_accum_num));
2243 float r_bounds[2][3])
2246 const int around = (v3d) ? scene->toolsettings->transform_pivot_point :
2251 bool is_minmax_set =
false;
2257 is_minmax_set =
true;
2268 mul_v3_m4v3(r_center, ob->world_to_object().ptr(), scene->cursor.location);
2287 if (!is_minmax_set) {
2301 const float offset[4])
2303 float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
2304 float sideangle = 0.0f, upangle = 0.0f;
2318 copy_m4_m4(rotobj, ob->object_to_world().ptr());
2323 rotobj[3][3] = 0.0f;
2331 sideangle =
float(
M_PI) * (sideangledeg + 180.0f) / 180.0f;
2332 rotside[0][0] =
cosf(sideangle);
2333 rotside[0][1] = -
sinf(sideangle);
2334 rotside[1][0] =
sinf(sideangle);
2335 rotside[1][1] =
cosf(sideangle);
2336 rotside[2][2] = 1.0f;
2338 upangle =
float(
M_PI) * upangledeg / 180.0f;
2339 rotup[1][1] =
cosf(upangle) / radius;
2340 rotup[1][2] = -
sinf(upangle) / radius;
2341 rotup[2][1] =
sinf(upangle) / radius;
2342 rotup[2][2] =
cosf(upangle) / radius;
2343 rotup[0][0] = 1.0f / radius;
2365 rotmat[0][0] = 0.0f;
2366 rotmat[0][1] = 1.0f;
2367 rotmat[1][0] = -1.0f;
2368 rotmat[1][1] = 0.0f;
2373 const float up_angle_deg = (direction ==
VIEW_ON_EQUATOR) ? 90.0f : 0.0f;
2376 const float offset[4] = {0};
2377 float rotmat4[4][4];
2385 {
VIEW_ON_EQUATOR,
"VIEW_ON_EQUATOR", 0,
"View on Equator",
"3D view is on the equator"},
2386 {
VIEW_ON_POLES,
"VIEW_ON_POLES", 0,
"View on Poles",
"3D view is on the poles"},
2391 "Align according to object transform"},
2392 {0,
nullptr, 0,
nullptr,
nullptr},
2395 {
POLAR_ZX,
"POLAR_ZX", 0,
"Polar ZX",
"Polar 0 is X"},
2396 {
POLAR_ZY,
"POLAR_ZY", 0,
"Polar ZY",
"Polar 0 is Y"},
2397 {0,
nullptr, 0,
nullptr,
nullptr},
2401 {
PINCH,
"PINCH", 0,
"Pinch",
"UVs are pinched at the poles"},
2402 {
FAN,
"FAN", 0,
"Fan",
"UVs are fanned at the poles"},
2403 {0,
nullptr, 0,
nullptr,
nullptr},
2411 "Direction of the sphere or cylinder");
2417 "How to determine rotation around the pole");
2423 "Separate projections by islands isolated by seams");
2432 "Radius of the sphere or cylinder",
2439 const int cd_loop_uv_offset,
2440 const float aspect_y)
2449 if (aspect_y > 1.0f) {
2451 luv[0] = luv[0] / aspect_y + (0.5f - 0.5f / aspect_y);
2455 luv[1] = luv[1] * aspect_y + (0.5f - 0.5f * aspect_y);
2464 if (aspect_y == 1.0f) {
2479 const int materials_num = ob->
totcol;
2480 if (materials_num == 0) {
2497 const int material_index = efa->
mat_nr;
2498 if (
UNLIKELY(material_index < 0 || material_index >= materials_num)) {
2503 float aspect_y = material_aspect_y[material_index];
2504 if (aspect_y == -1.0f) {
2508 aspect_y = aspx / aspy;
2509 material_aspect_y[material_index] = aspect_y;
2512 if (aspect_y == 1.0f) {
2520#undef VIEW_ON_EQUATOR
2522#undef ALIGN_TO_OBJECT
2539 "Map UVs taking image aspect ratio into account");
2541 if (clip_to_bounds) {
2546 "Clip UV coordinates to bounds after unwrapping");
2552 "Scale UV coordinates to bounds after unwrapping");
2570 bool per_face_aspect,
2571 bool only_selected_uvs)
2576 float dx, dy,
min[2], max[2];
2584 for (
Object *ob : objects) {
2589 if (correct_aspect) {
2590 if (per_face_aspect) {
2598 if (scale_to_bounds) {
2615 else if (clip_to_bounds) {
2634 if (scale_to_bounds) {
2636 dx = (max[0] -
min[0]);
2637 dy = (max[1] -
min[1]);
2646 if (dx == 1.0f && dy == 1.0f &&
min[0] == 0.0f &&
min[1] == 0.0f) {
2651 for (
Object *ob : objects) {
2667 luv[0] = (luv[0] -
min[0]) * dx;
2668 luv[1] = (luv[1] -
min[1]) * dy;
2685 int *r_count_changed,
2686 int *r_count_failed)
2723 int *r_count_changed =
nullptr,
2724 int *r_count_failed =
nullptr)
2726 for (
Object *obedit : objects) {
2735 if (scene->toolsettings->edge_mode_live_unwrap) {
2737 options.topology_from_uvs =
false;
2738 options.only_selected_faces =
false;
2739 options.only_selected_uvs =
false;
2748 pack_island_params.
margin = scene->toolsettings->uvcalc_margin;
2763 int reported_errors = 0;
2771 options.topology_from_uvs =
false;
2772 options.only_selected_faces =
true;
2773 options.only_selected_uvs =
false;
2777 bool subsurf_error =
options.use_subsurf;
2781 options.only_selected_uvs =
true;
2782 options.pin_unselected =
true;
2790 for (
Object *obedit : objects) {
2792 bool use_subsurf_final;
2798 if (subsurf_error) {
2802 if (use_subsurf_final) {
2803 subsurf_error =
false;
2812 if (!(
fabsf(obsize[0] - obsize[1]) < 1e-4f &&
fabsf(obsize[1] - obsize[2]) < 1e-4f)) {
2816 "Object has non-uniform scale, unwrap will operate on a non-scaled version of "
2826 "Object has negative scale, unwrap will operate on a non-flipped version of the mesh");
2832 if (subsurf_error) {
2835 "Subdivision Surface modifier needs to be first to work with unwrap");
2839 int count_changed = 0;
2840 int count_failed = 0;
2853 if (count_failed == 0 && count_changed == 0) {
2856 "Unwrap could not solve any island(s), edge seams may need to be added");
2858 else if (count_failed) {
2861 "Unwrap failed to solve %d of %d island(s), edge seams may need to be added",
2863 count_changed + count_failed);
2919 {0,
nullptr, 0,
nullptr,
nullptr},
2924 ot->
description =
"Unwrap the mesh of the object being edited";
2942 "Unwrapping method (Angle Based usually gives better results than Conformal, while "
2943 "being somewhat slower)");
2948 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
2949 "preserve symmetry");
2954 "Map UVs taking image aspect ratio into account");
2959 "Use Subdivision Surface",
2960 "Map UVs taking vertex position after Subdivision Surface modifier has been applied");
2968 ot->
srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
2975 "Prevent flipping UV's, "
2976 "flipping may lower distortion depending on the position of pins");
2984 "Number of iterations when \"Minimum Stretch\" method is used",
2991 "Importance Weights",
2992 "Whether to take into account per-vertex importance weights");
2998 "Vertex group name for importance weights (modulating the deform)");
3006 "How much influence the weightmap has for weighted parameterization, 0 being no influence",
3049 const uint thick_faces_len,
3051 const float project_angle_limit_half_cos,
3052 const float project_angle_limit_cos,
3053 const float area_weight)
3055 if (
UNLIKELY(thick_faces_len == 0)) {
3059 const float *project_normal = thick_faces[0].
efa->
no;
3067 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3072 if (
dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) {
3073 project_thick_faces.
append(&thick_faces[f_index]);
3078 float average_normal[3] = {0.0f, 0.0f, 0.0f};
3080 if (area_weight <= 0.0f) {
3081 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3082 const ThickFace *tf = project_thick_faces[f_proj_index];
3086 else if (area_weight >= 1.0f) {
3087 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3088 const ThickFace *tf = project_thick_faces[f_proj_index];
3093 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3094 const ThickFace *tf = project_thick_faces[f_proj_index];
3095 const float area_blend = (tf->
area * area_weight) + (1.0f - area_weight);
3102 project_normal_array.
append(average_normal);
3106 float anble_best = 1.0f;
3107 uint angle_best_index = 0;
3109 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3114 float angle_test = -1.0f;
3115 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3116 angle_test =
max_ff(angle_test,
3117 dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no));
3120 if (angle_test < anble_best) {
3121 anble_best = angle_test;
3122 angle_best_index = f_index;
3126 if (anble_best < project_angle_limit_cos) {
3127 project_normal = thick_faces[angle_best_index].
efa->
no;
3128 project_thick_faces.
clear();
3129 project_thick_faces.
append(&thick_faces[angle_best_index]);
3133 if (project_normal_array.
size() >= 1) {
3141 return project_normal_array;
3152 bool only_selected_uvs =
false;
3155 only_selected_uvs =
true;
3162 const float project_angle_limit_cos =
cosf(project_angle_limit);
3163 const float project_angle_limit_half_cos =
cosf(project_angle_limit / 2);
3169 scene, view_layer, v3d);
3176 for (
const int ob_index : objects.index_range()) {
3177 Object *obedit = objects[ob_index];
3179 bool changed =
false;
3190 uint thick_faces_len = 0;
3196 if (only_selected_uvs) {
3204 thick_faces[thick_faces_len].
efa = efa;
3211 while ((thick_faces_len > 0) &&
3224 thick_faces_len -= 1;
3231 project_angle_limit_half_cos,
3232 project_angle_limit_cos,
3235 if (project_normal_array.
is_empty()) {
3242 MEM_callocN(
sizeof(*thickface_project_groups) * project_normal_array.
size(), __func__));
3246 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3247 const float *f_normal = thick_faces[f_index].
efa->
no;
3249 float angle_best =
dot_v3v3(f_normal, project_normal_array[0]);
3250 uint angle_best_index = 0;
3252 for (
int p_index = 1; p_index < project_normal_array.
size(); p_index++) {
3253 const float angle_test =
dot_v3v3(f_normal, project_normal_array[p_index]);
3254 if (angle_test > angle_best) {
3255 angle_best = angle_test;
3256 angle_best_index = p_index;
3261 &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena);
3264 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3265 if (thickface_project_groups[p_index] ==
nullptr) {
3269 float axis_mat[3][3];
3272 for (
LinkNode *list = thickface_project_groups[p_index]; list; list = list->
next) {
3290 objects_changed.
append(obedit);
3299 scene->toolsettings->uvcalc_margin = island_margin;
3306 params.only_selected_uvs = only_selected_uvs;
3307 params.only_selected_faces =
true;
3308 params.correct_aspect = correct_aspect;
3316 const bool per_face_aspect =
false;
3326 C, op, event,
IFACE_(
"Smart UV Project"),
IFACE_(
"Unwrap"));
3334 ot->
name =
"Smart UV Project";
3335 ot->
idname =
"UV_OT_smart_project";
3336 ot->
description =
"Projection unwraps the selected faces of mesh objects";
3353 "Lower for more projection groups, higher for less distortion",
3378 "Margin to reduce bleed from adjacent islands",
3387 "Weight projection's vector by faces with larger areas",
3433 float objects_pos_offset[4];
3439 scene, view_layer, v3d);
3441 if (use_orthographic) {
3443 float objects_pos_avg[4] = {0};
3445 for (
Object *
object : objects) {
3446 add_v4_v4(objects_pos_avg, object->object_to_world().location());
3449 mul_v4_fl(objects_pos_avg, 1.0f / objects.size());
3455 for (
Object *obedit : objects) {
3457 bool changed =
false;
3466 if (use_orthographic) {
3485 obedit->object_to_world().ptr(),
3486 camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f,
3487 camera_bounds ? (scene->r.ysch * scene->r.yasp) : 1.0f);
3506 copy_m4_m4(rotmat, obedit->object_to_world().ptr());
3516 luv,
l->
v->
co, rv3d->
persmat, rotmat, region->winx, region->winy);
3523 changed_objects.
append(obedit);
3533 const bool per_face_aspect =
true;
3534 const bool only_selected_uvs =
false;
3547 return (rv3d !=
nullptr);
3553 ot->
name =
"Project from View";
3554 ot->
idname =
"UV_OT_project_from_view";
3555 ot->
description =
"Project the UV vertices of the mesh as seen in current 3D view";
3570 "Map UVs to the camera region taking resolution and aspect into account");
3587 scene, view_layer, v3d);
3588 for (
Object *obedit : objects) {
3631 const bool *regular,
3633 const int cd_loop_uv_offset)
3647 float right_u = -1.0e30f;
3655 if (luv[0] >= 1.0f) {
3658 right_u =
max_ff(right_u, luv[0]);
3661 float left_u = 1.0e30f;
3664 if (right_u <= luv[0] + 0.5f) {
3665 left_u =
min_ff(left_u, luv[0]);
3671 if (luv[0] + 0.5f < right_u) {
3672 if (2 * luv[0] + 1.0f < left_u + right_u) {
3686 float minmax_u[2] = {1.0e30f, -1.0e30f};
3688 for (
int i = 0; i < efa->
len; i++) {
3690 minmax_u[0] =
min_ff(minmax_u[0], uvs[i][0]);
3691 minmax_u[1] =
max_ff(minmax_u[1], uvs[i][0]);
3697 if (
ELEM(pole_count, 0, efa->
len)) {
3700 for (
int i = 0; i < efa->
len; i++) {
3706 const int i_plus = (i + 1) % efa->
len;
3707 const int i_minus = (i + efa->
len - 1) % efa->
len;
3708 if (regular[i_plus]) {
3709 u += uvs[i_plus][0];
3712 if (regular[i_minus]) {
3713 u += uvs[i_minus][0];
3717 u += minmax_u[0] + minmax_u[1];
3720 uvs[i][0] = u /
sum;
3755 const float center[3],
3756 const float rotmat[3][3],
3759 const bool only_selected_uvs,
3760 const bool use_seams,
3761 const float branch_init)
3770 stack.
append({efa_init, branch_init});
3772 while (stack.
size()) {
3788 if (only_selected_uvs) {
3806 regular[i] =
map_to_sphere(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
3812 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
3813 max_u =
max_ff(max_u, luv[0]);
3825 stack.
append({efa2, luv[0]});
3840 bool only_selected_uvs =
false;
3843 only_selected_uvs =
true;
3848 scene, view_layer, v3d);
3849 for (
Object *obedit : objects) {
3864 float center[3], rotmat[3][3];
3876 float island_offset = 0.0f;
3887 island_offset + 0.5f);
3888 island_offset =
ceilf(
max_ff(max_u, island_offset));
3891 const bool per_face_aspect =
true;
3904 ot->
name =
"Sphere Projection";
3905 ot->
idname =
"UV_OT_sphere_project";
3906 ot->
description =
"Project the UV vertices of the mesh over the curved surface of a sphere";
3929 const float center[3],
3930 const float rotmat[3][3],
3933 const bool only_selected_uvs,
3934 const bool use_seams,
3935 const float branch_init)
3946 stack.
append({efa_init, branch_init});
3948 while (stack.
size()) {
3964 if (only_selected_uvs) {
3982 regular[i] =
map_to_tube(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
3989 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
3990 max_u =
max_ff(max_u, luv[0]);
4002 stack.
append({efa2, luv[0]});
4018 bool only_selected_uvs =
false;
4021 only_selected_uvs =
true;
4026 scene, view_layer, v3d);
4027 for (
Object *obedit : objects) {
4042 float center[3], rotmat[3][3];
4054 float island_offset = 0.0f;
4075 island_offset + 0.5f);
4076 island_offset =
ceilf(
max_ff(max_u, island_offset));
4079 const bool per_face_aspect =
true;
4092 ot->
name =
"Cylinder Projection";
4093 ot->
idname =
"UV_OT_cylinder_project";
4094 ot->
description =
"Project the UV vertices of the mesh over the curved wall of a cylinder";
4116 const bool use_select,
4117 const bool only_selected_uvs,
4118 const float center[3])
4155 luv[0] = 0.5f + ((
l->
v->
co[cox] - loc[cox]) / cube_size);
4156 luv[1] = 0.5f + ((
l->
v->
co[coy] - loc[coy]) / cube_size);
4166 bool only_selected_uvs =
false;
4169 only_selected_uvs =
true;
4177 scene, view_layer, v3d);
4178 for (
const int ob_index : objects.index_range()) {
4179 Object *obedit = objects[ob_index];
4192 float(*bounds_buf)[3] =
nullptr;
4195 bounds_buf = bounds;
4202 float cube_size = cube_size_init;
4207 if (ob_index == 0) {
4215 const bool per_face_aspect =
true;
4228 ot->
name =
"Cube Projection";
4230 ot->
description =
"Project the UV vertices of the mesh over the six faces of a cube";
4245 "Size of the cube to project on",
4268 scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION;
4274 bm_from_me_params.calc_vert_normal =
true;
4285 params.only_selected_uvs =
false;
4286 params.only_selected_faces =
false;
4287 params.correct_aspect =
false;
4299 if (sync_selection) {
SpaceImage * CTX_wm_space_image(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
int BKE_image_find_nearest_tile_with_offset(const Image *image, const float co[2], float r_uv_offset[2]) ATTR_NONNULL(2
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
blender::bke::subdiv::Settings BKE_subsurf_modifier_settings_init(const SubsurfModifierData *smd, bool use_render_params)
#define BLI_assert_unreachable()
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
Heap * BLI_heap_new(void) ATTR_WARN_UNUSED_RESULT
void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, struct MemArena *ma) ATTR_NONNULL(1
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
bool map_to_tube(float *r_u, float *r_v, float x, float y, float z)
MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
bool invert_m2_m2(float inverse[2][2], const float mat[2][2])
void mul_m3_v3(const float M[3][3], float r[3])
void zero_m4(float m[4][4])
void unit_m3(float m[3][3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void unit_m4(float m[4][4])
#define mul_m4_series(...)
void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool is_negative_m4(const float mat[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mat4_to_size(float size[3], const float M[4][4])
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v2_fl(float r[2], float f)
MINLINE void negate_v4_v4(float r[4], const float a[4])
MINLINE void clamp_v2(float vec[2], float min, float max)
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v2(float r[2])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
void void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
#define STRNCPY(dst, src)
#define SNPRINTF(dst, format,...)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define INIT_MINMAX2(min, max)
#define INIT_MINMAX(min, max)
void BLI_uvproject_from_view(float target[2], float source[3], float persmat[4][4], float rotmat[4][4], float winx, float winy)
void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4])
void BLI_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci)
struct ProjCameraInfo * BLI_uvproject_camera_info(const struct Object *ob, const float rotmat[4][4], float winx, float winy)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define DNA_struct_default_get(struct_name)
@ eSubsurfModifierFlag_ControlEdges
Object is a sort of wrapper for general info.
@ UVCALC_UNWRAP_USE_WEIGHTS
@ UVCALC_NO_ASPECT_CORRECT
@ UVCALC_UNWRAP_METHOD_MINIMUM_STRETCH
@ UVCALC_UNWRAP_METHOD_CONFORMAL
@ UVCALC_UNWRAP_METHOD_ANGLE
@ V3D_AROUND_CENTER_BOUNDS
@ V3D_AROUND_CENTER_MEDIAN
@ V3D_AROUND_LOCAL_ORIGINS
void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *r_aspx, float *r_aspy)
void ED_mesh_uv_ensure(Mesh *mesh, const char *name)
int ED_mesh_uv_add(Mesh *mesh, const char *name, bool active_set, bool do_init, ReportList *reports)
void ED_mesh_uv_loop_reset(bContext *C, Mesh *mesh)
void EDBM_mesh_elem_index_ensure_multi(blender::Span< Object * > objects, char htype)
bool ED_operator_uvmap(bContext *C)
void ED_area_status_text(ScrArea *area, const char *str)
void ED_workspace_status_text(bContext *C, const char *str)
bool ED_operator_uvedit(bContext *C)
void ED_undo_push(bContext *C, const char *str)
bool ED_object_get_active_image(Object *ob, int mat_nr, Image **r_ima, ImageUser **r_iuser, const bNode **r_node, const bNodeTree **r_ntree)
void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob)
void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit, struct wmWindow *win_modal)
bool uvedit_face_select_test(const Scene *scene, BMFace *efa, BMUVOffsets offsets)
float ED_uvedit_get_aspect_y(Object *obedit)
void ED_uvedit_get_aspect_from_material(Object *ob, const int material_index, float *r_aspx, float *r_aspy)
bool ED_uvedit_live_unwrap_timer_check(const wmTimer *timer)
bool ED_uvedit_test(Object *obedit)
void ED_uvedit_select_all(BMesh *bm)
void ED_uvedit_live_unwrap_re_solve()
int bm_mesh_calc_uv_islands(const Scene *scene, BMesh *bm, ListBase *island_list, const bool only_selected_faces, const bool only_selected_uvs, const bool use_seams, const float aspect_y, BMUVOffsets offsets)
void ED_uvedit_get_aspect(Object *obedit, float *r_aspx, float *r_aspy)
void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa, BMUVOffsets offsets)
void ED_uvedit_live_unwrap_end(bool cancel)
bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2])
void ED_uvedit_live_unwrap(const Scene *scene, blender::Span< Object * > objects)
bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, BMUVOffsets offsets)
Camera * ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d)
eUVPackIsland_MarginMethod
@ ED_UVPACK_MARGIN_FRACTION
@ ED_UVPACK_MARGIN_SCALED
eUVPackIsland_ShapeMethod
@ ED_UVPACK_SHAPE_CONCAVE
@ ED_UVPACK_PIN_LOCK_ROTATION_SCALE
@ ED_UVPACK_PIN_LOCK_SCALE
@ ED_UVPACK_PIN_LOCK_ROTATION
eUVPackIsland_RotationMethod
@ ED_UVPACK_ROTATION_AXIS_ALIGNED_X
@ ED_UVPACK_ROTATION_AXIS_ALIGNED
@ ED_UVPACK_ROTATION_CARDINAL
@ ED_UVPACK_ROTATION_NONE
@ ED_UVPACK_ROTATION_AXIS_ALIGNED_Y
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
#define RNA_ENUM_ITEM_SEPR
void uiLayoutSetActive(uiLayout *layout, bool active)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
#define BM_ELEM_CD_GET_BOOL(ele, offset)
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_ELEM_CD_SET_BOOL(ele, offset, f)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
void BM_uv_map_ensure_vert_select_attr(BMesh *bm, const char *uv_map_name)
void BM_uv_map_ensure_edge_select_attr(BMesh *bm, const char *uv_map_name)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMFace * BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
void BM_editselection_center(BMEditSelection *ese, float r_center[3])
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
const BMAllocTemplate bm_mesh_allocsize_default
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
BLI_INLINE BMEdge * BM_edge_at_index(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
void BM_face_calc_bounds_expand(const BMFace *f, float min[3], float max[3])
float BM_face_calc_area(const BMFace *f)
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
ATTR_WARN_UNUSED_RESULT const BMLoop * l
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd_loop_uv_offset)
static T sum(const btAlignedObjectArray< T > &items)
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
void append(const T &value)
IndexRange index_range() const
bool can_scale_(const UVPackIsland_Params ¶ms) const
void add_polygon(Span< float2 > uvs, MemArena *arena, Heap *heap)
void build_transformation(float scale, double rotation, float r_matrix[2][2]) const
eUVPackIsland_RotationMethod rotate_method
eUVPackIsland_MarginMethod margin_method
eUVPackIsland_ShapeMethod shape_method
void setUDIMOffsetFromSpaceImage(const SpaceImage *sima)
eUVPackIsland_PinMethod pin_method
void setFromUnwrapOptions(const UnwrapOptions &options)
float udim_base_offset[2]
IndexRange index_range() const
CCL_NAMESPACE_BEGIN struct Options options
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
void free(Subdiv *subdiv)
Subdiv * new_from_mesh(const Settings *settings, const Mesh *mesh)
Mesh * subdiv_to_mesh(Subdiv *subdiv, const ToMeshSettings *settings, const Mesh *coarse_mesh)
bool uv_parametrizer_is_slim(const ParamHandle *phandle)
void uv_parametrizer_construct_end(ParamHandle *phandle, bool fill_holes, bool topology_from_uvs, int *r_count_failed=nullptr)
void uv_parametrizer_edge_set_seam(ParamHandle *phandle, const ParamKey *vkeys)
void uv_parametrizer_average(ParamHandle *handle, bool ignore_pinned, bool scale_uv, bool shear)
void uv_parametrizer_flush(ParamHandle *handle)
void uv_parametrizer_slim_live_begin(ParamHandle *phandle, const ParamSlimOptions *slim_options)
void uv_parametrizer_slim_live_solve_iteration(ParamHandle *phandle)
ParamKey uv_find_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2])
void uv_prepare_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2])
void uv_parametrizer_slim_live_end(ParamHandle *phandle)
void uv_parametrizer_stretch_blend(ParamHandle *handle, float blend)
void uv_parametrizer_slim_solve(ParamHandle *phandle, const ParamSlimOptions *slim_options, int *count_changed, int *count_failed)
void mul_v2_m2_add_v2v2(float r[2], const float mat[2][2], const float a[2], const float b[2])
void uv_parametrizer_lscm_end(ParamHandle *handle)
void uv_parametrizer_aspect_ratio(ParamHandle *handle, float aspect_y)
void uv_parametrizer_stretch_begin(ParamHandle *handle)
void uv_parametrizer_flush_restore(ParamHandle *handle)
void uv_parametrizer_lscm_begin(ParamHandle *handle, bool live, bool abf)
float pack_islands(Span< PackIsland * > islands, const UVPackIsland_Params ¶ms)
void uv_parametrizer_lscm_solve(ParamHandle *handle, int *count_changed, int *count_failed)
void uv_parametrizer_stretch_iter(ParamHandle *handle)
void uv_parametrizer_stretch_end(ParamHandle *handle)
void uv_parametrizer_face_add(ParamHandle *handle, const ParamKey key, const int nverts, const ParamKey *vkeys, const float **co, float **uv, const float *weight, const bool *pin, const bool *select)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
PropertyRNA * RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
PropertyRNA * RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
Vector< Object * > objects_edit
ObjectRuntimeHandle * runtime
Vector< Object * > objects
blender::geometry::UVPackIsland_Params pack_island_params
bool topology_from_uvs_use_seams
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* ui)(bContext *C, wmOperator *op)
void(* cancel)(bContext *C, wmOperator *op)
struct ReportList * reports
struct wmOperatorType * type
void UV_OT_cylinder_project(wmOperatorType *ot)
void UV_OT_project_from_view(wmOperatorType *ot)
void UV_OT_smart_project(wmOperatorType *ot)
void UV_OT_unwrap(wmOperatorType *ot)
void UV_OT_sphere_project(wmOperatorType *ot)
void UV_OT_cube_project(wmOperatorType *ot)
void UV_OT_average_islands_scale(wmOperatorType *ot)
void UV_OT_reset(wmOperatorType *ot)
void UV_OT_minimize_stretch(wmOperatorType *ot)
void UV_OT_pack_islands(wmOperatorType *ot)
static int uv_from_view_exec(bContext *C, wmOperator *op)
static void uv_map_transform_center(const Scene *scene, View3D *v3d, Object *ob, BMEditMesh *em, float r_center[3], float r_bounds[2][3])
static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *)
static int cube_project_exec(bContext *C, wmOperator *op)
static bool uv_from_view_poll(bContext *C)
static void uv_map_clip_correct(const Scene *scene, const Span< Object * > objects, wmOperator *op, bool per_face_aspect, bool only_selected_uvs)
static int cylinder_project_exec(bContext *C, wmOperator *op)
static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel)
static void pack_islands_freejob(void *pidv)
@ UNWRAP_ERROR_NONUNIFORM
static bool island_has_pins(const Scene *scene, FaceIsland *island, const blender::geometry::UVPackIsland_Params *params)
static void construct_param_edge_set_seams(ParamHandle *handle, BMesh *bm, const UnwrapOptions *options)
static void uv_map_mirror(BMFace *efa, const bool *regular, const bool fan, const int cd_loop_uv_offset)
static void uvedit_unwrap_cube_project(const Scene *scene, BMesh *bm, float cube_size, const bool use_select, const bool only_selected_uvs, const float center[3])
static const EnumPropertyItem pack_margin_method_items[]
static Mesh * subdivide_edit_mesh(const Object *object, const BMEditMesh *em, const SubsurfModifierData *smd)
static float uv_cylinder_project(const Scene *scene, BMesh *bm, BMFace *efa_init, const float center[3], const float rotmat[3][3], const bool fan, const BMUVOffsets offsets, const bool only_selected_uvs, const bool use_seams, const float branch_init)
static void minimize_stretch_cancel(bContext *C, wmOperator *op)
static float uv_nearest_grid_tile_distance(const int udim_grid[2], const float coords[2], float nearest_tile_co[2])
static void uv_transform_properties(wmOperatorType *ot, int radius)
static ParamHandle * construct_param_handle_subsurfed(const Scene *scene, Object *ob, BMEditMesh *em, const UnwrapOptions *options, int *r_count_failed=nullptr)
static void construct_param_handle_face_add(ParamHandle *handle, const Scene *scene, BMFace *efa, blender::geometry::ParamKey face_index, const UnwrapOptions *options, const BMUVOffsets offsets, const int cd_weight_offset, const int cd_weight_index)
static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void uvedit_unwrap(const Scene *scene, Object *obedit, const UnwrapOptions *options, int *r_count_changed, int *r_count_failed)
static void pack_islands_startjob(void *pidv, wmJobWorkerStatus *worker_status)
static int minimize_stretch_exec(bContext *C, wmOperator *op)
static void uv_pack_islands_ui(bContext *, wmOperator *op)
static const EnumPropertyItem pack_shape_method_items[]
static bool rna_property_sync_string(PointerRNA *ptr, const char *prop_name, char value_p[])
static const float smart_uv_project_area_ignore
static int unwrap_exec(bContext *C, wmOperator *op)
static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p)
static UnwrapOptions unwrap_options_get(wmOperator *op, Object *ob, const ToolSettings *ts)
static void correct_uv_aspect(Object *ob, BMEditMesh *em)
static void pack_islands_endjob(void *pidv)
static bool uvedit_live_unwrap_timer_validate(const wmWindowManager *wm)
static int pack_islands_exec(bContext *C, wmOperator *op)
static void uv_map_transform(bContext *C, wmOperator *op, float rotmat[3][3])
static void uv_map_transform_calc_center_median(BMEditMesh *em, float r_center[3])
static void uv_map_clip_correct_properties(wmOperatorType *ot)
static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_bounds)
static ParamHandle * construct_param_handle_multi(const Scene *scene, const Span< Object * > objects, const UnwrapOptions *options)
static const EnumPropertyItem pack_rotate_method_items[]
static void uv_map_rotation_matrix_ex(float result[4][4], RegionView3D *rv3d, Object *ob, float upangledeg, float sideangledeg, float radius, const float offset[4])
static void unwrap_options_sync_toolsettings(wmOperator *op, ToolSettings *ts)
static bool rna_property_sync_enum(PointerRNA *ptr, const char *prop_name, int *value_p)
static bool rna_property_sync_enum_char(PointerRNA *ptr, const char *prop_name, char *value_p)
static float uv_nearest_image_tile_distance(const Image *image, const float coords[2], float nearest_tile_co[2])
static int average_islands_scale_exec(bContext *C, wmOperator *op)
static int sphere_project_exec(bContext *C, wmOperator *op)
static void uvedit_prepare_pinned_indices(ParamHandle *handle, const Scene *scene, BMFace *efa, const UnwrapOptions *options, const BMUVOffsets offsets)
static bool rna_property_sync_float(PointerRNA *ptr, const char *prop_name, float *value_p)
static bool rna_property_sync_int(PointerRNA *ptr, const char *prop_name, int *value_p)
static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *)
static void uvedit_pack_islands_multi(const Scene *scene, const Span< Object * > objects, BMesh **bmesh_override, const SpaceImage *udim_source_closest, const bool original_selection, const bool notify_wm, blender::geometry::UVPackIsland_Params *params)
static int smart_project_exec(bContext *C, wmOperator *op)
static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interactive)
static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const UnwrapOptions *options)
static bool uvedit_is_face_affected(const Scene *scene, BMFace *efa, const UnwrapOptions *options, const BMUVOffsets offsets)
#define PACK_ROTATE_METHOD_AXIS_ALIGNED_OFFSET
static bool minimize_stretch_init(bContext *C, wmOperator *op)
static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3])
static int smart_project_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void unwrap_draw(bContext *, wmOperator *op)
static bool rna_property_sync_flag(PointerRNA *ptr, const char *prop_name, char flag, bool flipped, char *value_p)
static bool ED_uvedit_ensure_uvs(Object *obedit)
static void uvedit_unwrap_multi(const Scene *scene, const Span< Object * > objects, const UnwrapOptions *options, int *r_count_changed=nullptr, int *r_count_failed=nullptr)
static void shrink_loop_uv_by_aspect_ratio(BMFace *efa, const int cd_loop_uv_offset, const float aspect_y)
static void correct_uv_aspect_per_face(Object *ob, BMEditMesh *em)
static ParamHandle * construct_param_handle(const Scene *scene, Object *ob, BMesh *bm, const UnwrapOptions *options, int *r_count_failed=nullptr)
static void island_uv_transform(FaceIsland *island, const float matrix[2][2], const float pre_translate[2])
static float uv_sphere_project(const Scene *scene, BMesh *bm, BMFace *efa_init, const float center[3], const float rotmat[3][3], const bool fan, const BMUVOffsets offsets, const bool only_selected_uvs, const bool use_seams, const float branch_init)
static const EnumPropertyItem pinned_islands_method_items[]
static struct @598 g_live_unwrap
static void modifier_unwrap_state(Object *obedit, const UnwrapOptions *options, bool *r_use_subsurf)
static void texface_from_original_index(const Scene *scene, const BMUVOffsets offsets, BMFace *efa, int index, float **r_uv, bool *r_pin, bool *r_select)
static blender::Vector< blender::float3 > smart_uv_project_calculate_project_normals(const ThickFace *thick_faces, const uint thick_faces_len, BMesh *bm, const float project_angle_limit_half_cos, const float project_angle_limit_cos, const float area_weight)
static int uv_pack_islands_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool uvedit_have_selection_multi(const Scene *scene, const Span< Object * > objects, const UnwrapOptions *options)
static int reset_exec(bContext *C, wmOperator *)
void WM_cursor_wait(bool val)
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_set_locked_interface(wmWindowManager *wm, bool lock)
void WM_jobs_timer(wmJob *wm_job, double time_step, uint note, uint endnote)
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, const eWM_JobFlag flag, const eWM_JobType job_type)
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *customdata))
int WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *)
int WM_operator_props_popup_confirm_ex(bContext *C, wmOperator *op, const wmEvent *, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const int event_type, const double time_step)