136 "Map UVs taking aspect ratio of the image associated with the material into account");
229 bool subsurf =
options->use_subsurf;
252 *r_use_subsurf = subsurf;
260 options.topology_from_uvs =
false;
261 options.topology_from_uvs_use_seams =
false;
262 options.only_selected_faces =
false;
263 options.only_selected_uvs =
false;
264 options.pin_unselected =
false;
266 options.slim.skip_init =
false;
304 if (
options.weight_group[0] ==
'\0' ||
options.use_weights ==
false) {
305 options.slim.weight_influence = 0.0f;
317 bool use_subsurf_final;
319 options.use_subsurf = use_subsurf_final;
366 int value_i = *value_p;
447 if (offsets.
uv == -1) {
469 if (
options->only_selected_uvs && !
l) {
483 bool have_select =
false;
484 for (
Object *obedit : objects) {
495 const int material_index,
499 if (
UNLIKELY(material_index < 0 || material_index >= ob->
totcol)) {
514 bool selected =
false;
529 return aspect[0] / aspect[1];
546 if (
options->only_selected_uvs) {
573 if (
options->pin_unselected && !pin) {
591 const int cd_weight_offset,
592 const int cd_weight_index)
621 if (cd_weight_offset >= 0 && cd_weight_index >= 0) {
646 if (
options->topology_from_uvs && !
options->topology_from_uvs_use_seams) {
651 if (offsets.
uv == -1) {
688 int *r_count_failed =
nullptr)
716 handle, scene,
bm, efa,
i,
options, offsets, cd_weight_offset, cd_weight_index);
723 handle,
options->fill_holes,
options->topology_from_uvs, r_count_failed);
751 for (
Object *obedit : objects) {
757 if (offsets.
uv == -1) {
786 offset +=
bm->totface;
790 handle,
options->fill_holes,
options->topology_from_uvs,
nullptr);
832 em->
bm,
nullptr,
static_cast<const Mesh *
>(object->
data));
841 if (settings.
level == 1) {
868 int *r_count_failed =
nullptr)
907 const int *origVertIndices =
static_cast<const int *
>(
909 const int *origEdgeIndices =
static_cast<const int *
>(
911 const int *origPolyIndices =
static_cast<const int *
>(
961 vkeys[0] = (
ParamKey)poly_corner_verts[0];
962 vkeys[1] = (
ParamKey)poly_corner_verts[1];
963 vkeys[2] = (
ParamKey)poly_corner_verts[2];
964 vkeys[3] = (
ParamKey)poly_corner_verts[3];
966 co[0] = subsurf_positions[poly_corner_verts[0]];
967 co[1] = subsurf_positions[poly_corner_verts[1]];
968 co[2] = subsurf_positions[poly_corner_verts[2]];
969 co[3] = subsurf_positions[poly_corner_verts[3]];
972 if (cd_weight_index >= 0) {
996 origVertIndices[poly_corner_verts[0]],
1004 origVertIndices[poly_corner_verts[1]],
1012 origVertIndices[poly_corner_verts[2]],
1020 origVertIndices[poly_corner_verts[3]],
1026 handle, key, 4, vkeys, co, uv, weight, pin,
select);
1041 handle,
options->fill_holes,
options->topology_from_uvs, r_count_failed);
1073 options.topology_from_uvs =
true;
1075 options.only_selected_faces =
true;
1076 options.only_selected_uvs =
true;
1077 options.correct_aspect =
true;
1086 MinStretch *ms = MEM_new<MinStretch>(__func__);
1096 if (ms->
blend != 0.0f) {
1194 for (
i = 0;
i < iterations;
i++) {
1223 switch (event->
type) {
1236 if (ms->
blend < 0.95f) {
1247 if (ms->
blend > 0.05f) {
1285 ot->name =
"Minimize Stretch";
1286 ot->idname =
"UV_OT_minimize_stretch";
1288 ot->description =
"Reduce UV stretching by relaxing angles";
1302 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
1303 "preserve symmetry");
1310 "Blend factor between stretch minimized and original",
1319 "Number of iterations to run, 0 is unlimited when run interactively",
1327 const float matrix[2][2],
1328 const float pre_translate[2]
1342 const int cd_loop_uv_offset = island->
offsets.
uv;
1343 const int faces_len = island->
faces_len;
1344 for (
int i = 0;
i < faces_len;
i++) {
1359 const float coords[2],
1360 float nearest_tile_co[2])
1365 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1366 add_v2_fl(nearest_tile_center_co, 0.5f);
1375 const float coords[2],
1376 float nearest_tile_co[2])
1378 const float coords_floor[2] = {
floorf(coords[0]),
floorf(coords[1])};
1380 if (coords[0] > udim_grid[0]) {
1381 nearest_tile_co[0] = udim_grid[0] - 1;
1383 else if (coords[0] < 0) {
1384 nearest_tile_co[0] = 0;
1387 nearest_tile_co[0] = coords_floor[0];
1390 if (coords[1] > udim_grid[1]) {
1391 nearest_tile_co[1] = udim_grid[1] - 1;
1393 else if (coords[1] < 0) {
1394 nearest_tile_co[1] = 0;
1397 nearest_tile_co[1] = coords_floor[1];
1401 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1402 add_v2_fl(nearest_tile_center_co, 0.5f);
1412 const bool pin_unselected =
params->pin_unselected;
1413 const bool only_selected_faces =
params->only_selected_faces;
1450 BMesh **bmesh_override,
1452 const bool original_selection,
1453 const bool notify_wm,
1454 const rctf *custom_region,
1460 for (
const int ob_index : objects.
index_range()) {
1461 Object *obedit = objects[ob_index];
1463 if (bmesh_override) {
1465 bm = bmesh_override[ob_index];
1474 if (offsets.
uv == -1) {
1480 bool only_selected_faces =
params->only_selected_faces;
1481 bool only_selected_uvs =
params->only_selected_uvs;
1483 if (ignore_pinned &&
params->pin_unselected) {
1484 only_selected_faces =
false;
1485 only_selected_uvs =
false;
1491 only_selected_faces,
1501 if (ignore_pinned && pinned) {
1506 island_vector.
append(island);
1507 pinned_vector.
append(pinned);
1516 float selection_min_co[2], selection_max_co[2];
1519 for (
int index = 0; index < island_vector.
size(); index++) {
1529 float selection_center[2];
1530 mid_v2_v2v2(selection_center, selection_min_co, selection_max_co);
1532 if (original_selection) {
1534 if ((selection_max_co[0] - selection_min_co[0]) * (selection_max_co[1] - selection_min_co[1]) >
1538 params->target_extent = selection_max_co[1] - selection_min_co[1];
1539 params->target_aspect_y = (selection_max_co[0] - selection_min_co[0]) /
1540 (selection_max_co[1] - selection_min_co[1]);
1543 else if (custom_region) {
1550 params->target_extent = custom_region_size.y;
1551 params->target_aspect_y = custom_region_size.x / custom_region_size.y;
1559 for (
int i = 0;
i < island_vector.
size();
i++) {
1564 pack_island->
pinned = pinned_vector[
i];
1565 pack_island_vector.
append(pack_island);
1590 const bool is_cancelled =
params->isCancelled();
1592 float base_offset[2] = {0.0f, 0.0f};
1595 if (udim_source_closest) {
1596 const Image *image = udim_source_closest->
image;
1600 if (is_valid_udim) {
1601 base_offset[0] =
floorf(selection_center[0]);
1602 base_offset[1] =
floorf(selection_center[1]);
1607 float nearest_image_tile_dist =
FLT_MAX, nearest_grid_tile_dist =
FLT_MAX;
1610 image, selection_center, nearest_image_tile_co);
1613 float nearest_grid_tile_co[2] = {0.0f, 0.0f};
1615 udim_grid, selection_center, nearest_grid_tile_co);
1617 base_offset[0] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1618 nearest_image_tile_co[0] :
1619 nearest_grid_tile_co[0];
1620 base_offset[1] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1621 nearest_image_tile_co[1] :
1622 nearest_grid_tile_co[1];
1627 float matrix_inverse[2][2];
1628 float pre_translate[2];
1635 const float island_scale = pack_island->
can_scale_(*
params) ? scale : 1.0f;
1641 mul_v2_m2v2(pre_translate, matrix_inverse, base_offset);
1655 pack_island_vector[
i] =
nullptr;
1659 if (notify_wm && !is_cancelled) {
1660 for (
Object *obedit : objects) {
1758 options.topology_from_uvs =
true;
1759 options.only_selected_faces =
true;
1760 options.only_selected_uvs =
true;
1762 options.correct_aspect =
true;
1784 pid->
objects = std::move(objects);
1806 pack_island_params = default_params;
1873 "Use scale of existing UVs to multiply margin"},
1879 "Specify a precise fraction of final UV output"},
1880 {0,
nullptr, 0,
nullptr,
nullptr},
1889 "Only 90 degree rotations are allowed"},
1892#define PACK_ROTATE_METHOD_AXIS_ALIGNED_OFFSET 3
1897 "Rotated to a minimal rectangle, either vertical or horizontal"},
1901 "Axis-aligned (Horizontal)",
1902 "Rotate islands to be aligned horizontally"},
1906 "Axis-aligned (Vertical)",
1907 "Rotate islands to be aligned vertically"},
1908 {0,
nullptr, 0,
nullptr,
nullptr},
1916 {0,
nullptr, 0,
nullptr,
nullptr},
1931 "Rotation and Scale",
1932 "Pinned islands will translate only"},
1934 {0,
nullptr, 0,
nullptr,
nullptr},
1979 "Pack islands to active UDIM image tile or UDIM grid tile where 2D cursor is located"},
1983 "Original bounding box",
1984 "Pack to starting bounding box of islands"},
1985 {
PACK_CUSTOM_REGION,
"CUSTOM_REGION", 0,
"Custom Region",
"Pack islands to custom region"},
1986 {0,
nullptr, 0,
nullptr,
nullptr},
1989 ot->name =
"Pack Islands";
1990 ot->idname =
"UV_OT_pack_islands";
1992 "Transform all islands so that they fill up the UV/UDIM space as much as possible";
1994#ifdef USE_INTERACTIVE_PACK
2004#ifdef USE_INTERACTIVE_PACK
2014 RNA_def_boolean(
ot->srna,
"rotate",
true,
"Rotate",
"Rotate islands to improve layout");
2021 RNA_def_boolean(
ot->srna,
"scale",
true,
"Scale",
"Scale islands to fill unit square");
2023 ot->srna,
"merge_overlap",
false,
"Merge Overlapping",
"Overlapping islands stick together");
2031 ot->srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
2035 "Lock Pinned Islands",
2036 "Constrain islands containing any pinned UV's");
2065 options.topology_from_uvs =
true;
2066 options.only_selected_faces =
true;
2067 options.only_selected_uvs =
true;
2069 options.correct_aspect =
true;
2087 for (
Object *obedit : objects) {
2103 ot->name =
"Average Islands Scale";
2104 ot->idname =
"UV_OT_average_islands_scale";
2105 ot->description =
"Average the size of separate UV islands, based on their area in 3D space";
2114 RNA_def_boolean(
ot->srna,
"scale_uv",
false,
"Non-Uniform",
"Scale U and V independently");
2115 RNA_def_boolean(
ot->srna,
"shear",
false,
"Shear",
"Reduce shear within islands");
2164 options.topology_from_uvs =
false;
2165 options.only_selected_faces =
false;
2166 options.only_selected_uvs =
false;
2177 options.slim.skip_init =
true;
2196 "uvedit_live_unwrap_liveHandles");
2263#define VIEW_ON_EQUATOR 0
2264#define VIEW_ON_POLES 1
2265#define ALIGN_TO_OBJECT 2
2291 uint center_accum_num = 0;
2298 center_accum_num += 1;
2301 mul_v3_fl(r_center, 1.0f /
float(center_accum_num));
2309 float r_bounds[2][3])
2317 bool is_minmax_set =
false;
2323 is_minmax_set =
true;
2353 if (!is_minmax_set) {
2367 const float offset[4])
2369 float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
2370 float sideangle = 0.0f, upangle = 0.0f;
2384 copy_m4_m4(rotobj, ob->object_to_world().ptr());
2389 rotobj[3][3] = 0.0f;
2397 sideangle =
float(
M_PI) * (sideangledeg + 180.0f) / 180.0f;
2398 rotside[0][0] =
cosf(sideangle);
2399 rotside[0][1] = -
sinf(sideangle);
2400 rotside[1][0] =
sinf(sideangle);
2401 rotside[1][1] =
cosf(sideangle);
2402 rotside[2][2] = 1.0f;
2404 upangle =
float(
M_PI) * upangledeg / 180.0f;
2405 rotup[1][1] =
cosf(upangle) / radius;
2406 rotup[1][2] = -
sinf(upangle) / radius;
2407 rotup[2][1] =
sinf(upangle) / radius;
2408 rotup[2][2] =
cosf(upangle) / radius;
2409 rotup[0][0] = 1.0f / radius;
2431 rotmat[0][0] = 0.0f;
2432 rotmat[0][1] = 1.0f;
2433 rotmat[1][0] = -1.0f;
2434 rotmat[1][1] = 0.0f;
2439 const float up_angle_deg = (direction ==
VIEW_ON_EQUATOR) ? 90.0f : 0.0f;
2442 const float offset[4] = {0};
2443 float rotmat4[4][4];
2451 {
VIEW_ON_EQUATOR,
"VIEW_ON_EQUATOR", 0,
"View on Equator",
"3D view is on the equator"},
2452 {
VIEW_ON_POLES,
"VIEW_ON_POLES", 0,
"View on Poles",
"3D view is on the poles"},
2457 "Align according to object transform"},
2458 {0,
nullptr, 0,
nullptr,
nullptr},
2461 {
POLAR_ZX,
"POLAR_ZX", 0,
"Polar ZX",
"Polar 0 is X"},
2462 {
POLAR_ZY,
"POLAR_ZY", 0,
"Polar ZY",
"Polar 0 is Y"},
2463 {0,
nullptr, 0,
nullptr,
nullptr},
2467 {
PINCH,
"PINCH", 0,
"Pinch",
"UVs are pinched at the poles"},
2468 {
FAN,
"FAN", 0,
"Fan",
"UVs are fanned at the poles"},
2469 {0,
nullptr, 0,
nullptr,
nullptr},
2477 "Direction of the sphere or cylinder");
2483 "How to determine rotation around the pole");
2484 RNA_def_enum(
ot->srna,
"pole", pole_items,
PINCH,
"Pole",
"How to handle faces at the poles");
2489 "Separate projections by islands isolated by seams");
2498 "Radius of the sphere or cylinder",
2505 const int cd_loop_uv_offset,
2506 const float aspect_y)
2515 if (aspect_y > 1.0f) {
2517 luv[0] = luv[0] / aspect_y + (0.5f - 0.5f / aspect_y);
2521 luv[1] = luv[1] * aspect_y + (0.5f - 0.5f * aspect_y);
2530 if (aspect_y == 1.0f) {
2545 const int materials_num = ob->
totcol;
2546 if (materials_num == 0) {
2563 const int material_index = efa->
mat_nr;
2564 if (
UNLIKELY(material_index < 0 || material_index >= materials_num)) {
2569 float aspect_y = material_aspect_y[material_index];
2570 if (aspect_y == -1.0f) {
2574 aspect_y = aspx / aspy;
2575 material_aspect_y[material_index] = aspect_y;
2578 if (aspect_y == 1.0f) {
2586#undef VIEW_ON_EQUATOR
2588#undef ALIGN_TO_OBJECT
2603 if (clip_to_bounds) {
2608 "Clip UV coordinates to bounds after unwrapping");
2614 "Scale UV coordinates to bounds after unwrapping");
2632 bool per_face_aspect,
2633 bool only_selected_uvs)
2638 float dx, dy,
min[2],
max[2];
2646 for (
Object *ob : objects) {
2651 if (correct_aspect) {
2652 if (per_face_aspect) {
2660 if (scale_to_bounds) {
2677 else if (clip_to_bounds) {
2696 if (scale_to_bounds) {
2708 if (dx == 1.0f && dy == 1.0f &&
min[0] == 0.0f &&
min[1] == 0.0f) {
2713 for (
Object *ob : objects) {
2729 luv[0] = (luv[0] -
min[0]) * dx;
2730 luv[1] = (luv[1] -
min[1]) * dy;
2747 int *r_count_changed,
2748 int *r_count_failed)
2785 int *r_count_changed =
nullptr,
2786 int *r_count_failed =
nullptr)
2788 for (
Object *obedit : objects) {
2799 options.topology_from_uvs =
false;
2800 options.only_selected_faces =
false;
2801 options.only_selected_uvs =
false;
2813 scene, objects,
nullptr,
nullptr,
false,
true,
nullptr, &pack_island_params);
2828 int reported_errors = 0;
2836 options.topology_from_uvs =
false;
2837 options.only_selected_faces =
true;
2838 options.only_selected_uvs =
false;
2842 bool subsurf_error =
options.use_subsurf;
2846 if (sync_selection) {
2850 options.only_selected_faces =
false;
2852 options.only_selected_uvs =
true;
2853 options.pin_unselected =
true;
2861 for (
Object *obedit : objects) {
2863 bool use_subsurf_final;
2869 if (subsurf_error) {
2873 if (use_subsurf_final) {
2874 subsurf_error =
false;
2883 if (!(
fabsf(obsize[0] - obsize[1]) < 1e-4f &&
fabsf(obsize[1] - obsize[2]) < 1e-4f)) {
2887 "Object has non-uniform scale, unwrap will operate on a non-scaled version of "
2897 "Object has negative scale, unwrap will operate on a non-flipped version of the mesh");
2903 if (subsurf_error) {
2906 "Subdivision Surface modifier needs to be first to work with unwrap");
2910 int count_changed = 0;
2911 int count_failed = 0;
2923 scene, objects,
nullptr,
nullptr,
false,
true,
nullptr, &pack_island_params);
2925 if (count_failed == 0 && count_changed == 0) {
2928 "Unwrap could not solve any island(s), edge seams may need to be added");
2930 else if (count_failed) {
2933 "Unwrap failed to solve %d of %d island(s), edge seams may need to be added",
2935 count_changed + count_failed);
2991 {0,
nullptr, 0,
nullptr,
nullptr},
2995 ot->name =
"Unwrap";
2996 ot->description =
"Unwrap the mesh of the object being edited";
2997 ot->idname =
"UV_OT_unwrap";
3014 "Unwrapping method (Angle Based usually gives better results than Conformal, while "
3015 "being somewhat slower)");
3020 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
3021 "preserve symmetry");
3029 "Use Subdivision Surface",
3030 "Map UVs taking vertex position after Subdivision Surface modifier has been applied");
3038 ot->srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
3045 "Prevent flipping UV's, "
3046 "flipping may lower distortion depending on the position of pins");
3054 "Number of iterations when \"Minimum Stretch\" method is used",
3061 "Importance Weights",
3062 "Whether to take into account per-vertex importance weights");
3068 "Vertex group name for importance weights (modulating the deform)");
3076 "How much influence the weightmap has for weighted parameterization, 0 being no influence",
3119 const uint thick_faces_len,
3121 const float project_angle_limit_half_cos,
3122 const float project_angle_limit_cos,
3123 const float area_weight)
3125 if (
UNLIKELY(thick_faces_len == 0)) {
3129 const float *project_normal = thick_faces[0].
efa->
no;
3137 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3142 if (
dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) {
3143 project_thick_faces.
append(&thick_faces[f_index]);
3148 float average_normal[3] = {0.0f, 0.0f, 0.0f};
3150 if (area_weight <= 0.0f) {
3151 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3152 const ThickFace *tf = project_thick_faces[f_proj_index];
3156 else if (area_weight >= 1.0f) {
3157 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3158 const ThickFace *tf = project_thick_faces[f_proj_index];
3163 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3164 const ThickFace *tf = project_thick_faces[f_proj_index];
3165 const float area_blend = (tf->
area * area_weight) + (1.0f - area_weight);
3172 project_normal_array.
append(average_normal);
3176 float anble_best = 1.0f;
3177 uint angle_best_index = 0;
3179 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3184 float angle_test = -1.0f;
3185 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3186 angle_test =
max_ff(angle_test,
3187 dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no));
3190 if (angle_test < anble_best) {
3191 anble_best = angle_test;
3192 angle_best_index = f_index;
3196 if (anble_best < project_angle_limit_cos) {
3197 project_normal = thick_faces[angle_best_index].
efa->
no;
3198 project_thick_faces.
clear();
3199 project_thick_faces.
append(&thick_faces[angle_best_index]);
3203 if (project_normal_array.
size() >= 1) {
3211 return project_normal_array;
3222 bool only_selected_uvs =
false;
3225 only_selected_uvs =
true;
3232 const float project_angle_limit_cos =
cosf(project_angle_limit);
3233 const float project_angle_limit_half_cos =
cosf(project_angle_limit / 2);
3239 scene, view_layer, v3d);
3246 for (
const int ob_index : objects.
index_range()) {
3247 Object *obedit = objects[ob_index];
3249 bool changed =
false;
3259 uint thick_faces_len = 0;
3265 if (only_selected_uvs) {
3273 thick_faces[thick_faces_len].
efa = efa;
3280 while ((thick_faces_len > 0) &&
3293 thick_faces_len -= 1;
3300 project_angle_limit_half_cos,
3301 project_angle_limit_cos,
3304 if (project_normal_array.
is_empty()) {
3311 MEM_callocN(
sizeof(*thickface_project_groups) * project_normal_array.
size(), __func__));
3315 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3316 const float *f_normal = thick_faces[f_index].
efa->
no;
3318 float angle_best =
dot_v3v3(f_normal, project_normal_array[0]);
3319 uint angle_best_index = 0;
3321 for (
int p_index = 1; p_index < project_normal_array.
size(); p_index++) {
3322 const float angle_test =
dot_v3v3(f_normal, project_normal_array[p_index]);
3323 if (angle_test > angle_best) {
3324 angle_best = angle_test;
3325 angle_best_index = p_index;
3330 &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena);
3333 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3334 if (thickface_project_groups[p_index] ==
nullptr) {
3338 float axis_mat[3][3];
3341 for (
LinkNode *list = thickface_project_groups[p_index]; list; list = list->
next) {
3359 objects_changed.
append(obedit);
3375 params.only_selected_uvs = only_selected_uvs;
3376 params.only_selected_faces =
true;
3377 params.correct_aspect = correct_aspect;
3383 scene, objects_changed,
nullptr,
nullptr,
false,
true,
nullptr, &
params);
3386 const bool per_face_aspect =
false;
3396 C, op, event,
IFACE_(
"Smart UV Project"),
IFACE_(
"Unwrap"));
3404 ot->name =
"Smart UV Project";
3405 ot->idname =
"UV_OT_smart_project";
3406 ot->description =
"Projection unwraps the selected faces of mesh objects";
3423 "Lower for more projection groups, higher for less distortion",
3448 "Margin to reduce bleed from adjacent islands",
3457 "Weight projection's vector by faces with larger areas",
3503 float objects_pos_offset[4];
3509 scene, view_layer, v3d);
3511 if (use_orthographic) {
3513 float objects_pos_avg[4] = {0};
3515 for (
Object *
object : objects) {
3516 add_v4_v4(objects_pos_avg, object->object_to_world().location());
3519 mul_v4_fl(objects_pos_avg, 1.0f / objects.size());
3525 for (
Object *obedit : objects) {
3527 bool changed =
false;
3536 if (use_orthographic) {
3555 obedit->object_to_world().ptr(),
3556 camera_bounds ? (scene->
r.
xsch * scene->
r.
xasp) : 1.0f,
3557 camera_bounds ? (scene->
r.
ysch * scene->
r.
yasp) : 1.0f);
3576 copy_m4_m4(rotmat, obedit->object_to_world().ptr());
3593 changed_objects.
append(obedit);
3603 const bool per_face_aspect =
true;
3604 const bool only_selected_uvs =
false;
3617 return (rv3d !=
nullptr);
3623 ot->name =
"Project from View";
3624 ot->idname =
"UV_OT_project_from_view";
3625 ot->description =
"Project the UV vertices of the mesh as seen in current 3D view";
3635 RNA_def_boolean(
ot->srna,
"orthographic",
false,
"Orthographic",
"Use orthographic projection");
3640 "Map UVs to the camera region taking resolution and aspect into account");
3657 scene, view_layer, v3d);
3658 for (
Object *obedit : objects) {
3684 ot->idname =
"UV_OT_reset";
3685 ot->description =
"Reset UV projection";
3701 const bool *regular,
3703 const int cd_loop_uv_offset)
3717 float right_u = -1.0e30f;
3725 if (luv[0] >= 1.0f) {
3728 right_u =
max_ff(right_u, luv[0]);
3731 float left_u = 1.0e30f;
3734 if (right_u <= luv[0] + 0.5f) {
3735 left_u =
min_ff(left_u, luv[0]);
3741 if (luv[0] + 0.5f < right_u) {
3742 if (2 * luv[0] + 1.0f < left_u + right_u) {
3756 float minmax_u[2] = {1.0e30f, -1.0e30f};
3758 for (
int i = 0;
i < efa->
len;
i++) {
3760 minmax_u[0] =
min_ff(minmax_u[0], uvs[
i][0]);
3761 minmax_u[1] =
max_ff(minmax_u[1], uvs[
i][0]);
3767 if (
ELEM(pole_count, 0, efa->
len)) {
3770 for (
int i = 0;
i < efa->
len;
i++) {
3776 const int i_plus = (
i + 1) % efa->
len;
3777 const int i_minus = (
i + efa->
len - 1) % efa->
len;
3778 if (regular[i_plus]) {
3779 u += uvs[i_plus][0];
3782 if (regular[i_minus]) {
3783 u += uvs[i_minus][0];
3787 u += minmax_u[0] + minmax_u[1];
3790 uvs[
i][0] = u /
sum;
3825 const float center[3],
3826 const float rotmat[3][3],
3829 const bool only_selected_uvs,
3830 const bool use_seams,
3831 const float branch_init)
3840 stack.
append({efa_init, branch_init});
3842 while (stack.
size()) {
3858 if (only_selected_uvs) {
3876 regular[
i] =
map_to_sphere(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
3882 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
3883 max_u =
max_ff(max_u, luv[0]);
3895 stack.
append({efa2, luv[0]});
3910 bool only_selected_uvs =
false;
3913 only_selected_uvs =
true;
3918 scene, view_layer, v3d);
3919 for (
Object *obedit : objects) {
3934 float center[3], rotmat[3][3];
3946 float island_offset = 0.0f;
3957 island_offset + 0.5f);
3958 island_offset =
ceilf(
max_ff(max_u, island_offset));
3961 const bool per_face_aspect =
true;
3974 ot->name =
"Sphere Projection";
3975 ot->idname =
"UV_OT_sphere_project";
3976 ot->description =
"Project the UV vertices of the mesh over the curved surface of a sphere";
3999 const float center[3],
4000 const float rotmat[3][3],
4003 const bool only_selected_uvs,
4004 const bool use_seams,
4005 const float branch_init)
4016 stack.
append({efa_init, branch_init});
4018 while (stack.
size()) {
4034 if (only_selected_uvs) {
4052 regular[
i] =
map_to_tube(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
4059 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
4060 max_u =
max_ff(max_u, luv[0]);
4072 stack.
append({efa2, luv[0]});
4088 bool only_selected_uvs =
false;
4091 only_selected_uvs =
true;
4096 scene, view_layer, v3d);
4097 for (
Object *obedit : objects) {
4112 float center[3], rotmat[3][3];
4124 float island_offset = 0.0f;
4145 island_offset + 0.5f);
4146 island_offset =
ceilf(
max_ff(max_u, island_offset));
4149 const bool per_face_aspect =
true;
4162 ot->name =
"Cylinder Projection";
4163 ot->idname =
"UV_OT_cylinder_project";
4164 ot->description =
"Project the UV vertices of the mesh over the curved wall of a cylinder";
4186 const bool use_select,
4187 const bool only_selected_uvs,
4188 const float center[3])
4225 luv[0] = 0.5f + ((
l->v->co[cox] - loc[cox]) / cube_size);
4226 luv[1] = 0.5f + ((
l->v->co[coy] - loc[coy]) / cube_size);
4236 bool only_selected_uvs =
false;
4239 only_selected_uvs =
true;
4247 scene, view_layer, v3d);
4248 for (
const int ob_index : objects.
index_range()) {
4249 Object *obedit = objects[ob_index];
4262 float (*bounds_buf)[3] =
nullptr;
4272 float cube_size = cube_size_init;
4277 if (ob_index == 0) {
4285 const bool per_face_aspect =
true;
4298 ot->name =
"Cube Projection";
4299 ot->idname =
"UV_OT_cube_project";
4300 ot->description =
"Project the UV vertices of the mesh over the six faces of a cube";
4315 "Size of the cube to project on",
4355 params.only_selected_uvs =
false;
4356 params.only_selected_faces =
false;
4357 params.correct_aspect =
false;
4369 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)
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)
@ REGION_DRAW_LOCK_RENDER
blender::bke::subdiv::Settings BKE_subsurf_modifier_settings_init(const SubsurfModifierData *smd, bool use_render_params)
void BKE_uvproject_from_view(float target[2], float source[3], float persmat[4][4], float rotmat[4][4], float winx, float winy)
void BKE_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4])
void BKE_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci)
void BKE_uvproject_camera_info_free(ProjCameraInfo *uci)
struct ProjCameraInfo * BKE_uvproject_camera_info(const struct Object *ob, const float rotmat[4][4], float winx, float winy)
#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
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void BLI_remlink(ListBase *listbase, void *vlink) 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])
#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])
void unit_m4(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])
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
bool BLI_rctf_is_empty(const struct rctf *rect)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
#define SNPRINTF_UTF8(dst, format,...)
#define STRNCPY_UTF8(dst, src)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define INIT_MINMAX2(min, max)
#define INIT_MINMAX(min, max)
#define ARRAY_SET_ITEMS(...)
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
struct wmOperator wmOperator
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_select_all(const ToolSettings *ts, BMesh *bm)
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)
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_live_unwrap_re_solve()
bool uvedit_uv_select_test(const Scene *scene, const BMesh *bm, const BMLoop *l, const BMUVOffsets &offsets)
void ED_uvedit_get_aspect(Object *obedit, float *r_aspx, float *r_aspy)
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, const 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)
void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa)
bool uvedit_face_select_test(const Scene *scene, const BMesh *bm, const BMFace *efa)
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
#define BM_ELEM_CD_GET_BOOL(ele, offset)
#define BM_ELEM_SELECT_UV_EDGE
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#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)
#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)
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_offsets_get(const BMesh *bm)
void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd_loop_uv_offset)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
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 angle, 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
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
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)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
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)
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)
std::string RNA_string_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_discrete(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)
bool uv_select_sync_valid
Vector< Object * > objects_edit
ObjectRuntimeHandle * runtime
struct ToolSettings * toolsettings
Vector< Object * > objects
blender::geometry::UVPackIsland_Params pack_island_params
char weight_group[MAX_VGROUP_NAME]
bool topology_from_uvs_use_seams
void use_property_decorate_set(bool is_sep)
uiLayout & column(bool align)
void active_set(bool active)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
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 void uv_map_transform_center(const Scene *scene, View3D *v3d, Object *ob, BMEditMesh *em, float r_center[3], float r_bounds[2][3])
static wmOperatorStatus uv_pack_islands_invoke(bContext *C, wmOperator *op, const wmEvent *event)
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 void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel)
static void pack_islands_freejob(void *pidv)
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 wmOperatorStatus cylinder_project_exec(bContext *C, wmOperator *op)
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 uv_map_operator_property_correct_aspect(wmOperatorType *ot)
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 bool uvedit_is_face_affected(const Scene *scene, const BMesh *bm, BMFace *efa, const UnwrapOptions *options, const BMUVOffsets &offsets)
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 wmOperatorStatus pack_islands_exec(bContext *C, wmOperator *op)
static void construct_param_handle_face_add(ParamHandle *handle, const Scene *scene, const BMesh *bm, BMFace *efa, blender::geometry::ParamKey face_index, const UnwrapOptions *options, const BMUVOffsets &offsets, const int cd_weight_offset, const int cd_weight_index)
static void uvedit_prepare_pinned_indices(ParamHandle *handle, const Scene *scene, const BMesh *bm, BMFace *efa, const UnwrapOptions *options, const BMUVOffsets &offsets)
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 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 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 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 struct @316145304201052102160124321267331173100057323212 g_live_unwrap
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 wmOperatorStatus sphere_project_exec(bContext *C, wmOperator *op)
static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_bounds)
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, const rctf *custom_region, blender::geometry::UVPackIsland_Params *params)
static ParamHandle * construct_param_handle_multi(const Scene *scene, const Span< Object * > objects, const UnwrapOptions *options)
static wmOperatorStatus smart_project_invoke(bContext *C, wmOperator *op, const wmEvent *event)
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 wmOperatorStatus uv_from_view_exec(bContext *C, wmOperator *op)
static bool island_has_pins(const Scene *scene, const BMesh *bm, FaceIsland *island, const blender::geometry::UVPackIsland_Params *params)
static float uv_nearest_image_tile_distance(const Image *image, const float coords[2], float nearest_tile_co[2])
static wmOperatorStatus unwrap_exec(bContext *C, wmOperator *op)
static bool rna_property_sync_float(PointerRNA *ptr, const char *prop_name, float *value_p)
static bool uvedit_ensure_uvs(Object *obedit)
static bool rna_property_sync_int(PointerRNA *ptr, const char *prop_name, int *value_p)
static wmOperatorStatus average_islands_scale_exec(bContext *C, wmOperator *op)
static wmOperatorStatus cube_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)
@ UNWRAP_ERROR_NONUNIFORM
static wmOperatorStatus uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *)
static wmOperatorStatus minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *)
#define PACK_ROTATE_METHOD_AXIS_ALIGNED_OFFSET
static bool minimize_stretch_init(bContext *C, wmOperator *op)
static wmOperatorStatus smart_project_exec(bContext *C, wmOperator *op)
static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3])
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 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 wmOperatorStatus minimize_stretch_exec(bContext *C, wmOperator *op)
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 const EnumPropertyItem pinned_islands_method_items[]
static void modifier_unwrap_state(Object *obedit, const UnwrapOptions *options, bool *r_use_subsurf)
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 void texface_from_original_index(const Scene *scene, const BMesh *bm, const BMUVOffsets &offsets, BMFace *efa, int index, float **r_uv, bool *r_pin, bool *r_select)
static bool uvedit_have_selection_multi(const Scene *scene, const Span< Object * > objects, const UnwrapOptions *options)
static wmOperatorStatus minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus reset_exec(bContext *C, wmOperator *)
void WM_cursor_wait(bool val)
void WM_locked_interface_set(wmWindowManager *wm, bool lock)
void WM_locked_interface_set_with_flags(wmWindowManager *wm, short lock_flags)
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_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))
wmOperatorStatus WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *)
wmOperatorStatus 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, std::optional< std::string > message)
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const wmEventType event_type, const double time_step)
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)