139 "Map UVs taking aspect ratio of the image associated with the material into account");
232 bool subsurf =
options->use_subsurf;
255 *r_use_subsurf = subsurf;
263 options.topology_from_uvs =
false;
264 options.topology_from_uvs_use_seams =
false;
265 options.only_selected_faces =
false;
266 options.only_selected_uvs =
false;
267 options.pin_unselected =
false;
269 options.slim.skip_init =
false;
307 if (
options.weight_group[0] ==
'\0' ||
options.use_weights ==
false) {
308 options.slim.weight_influence = 0.0f;
320 bool use_subsurf_final;
322 options.use_subsurf = use_subsurf_final;
369 int value_i = *value_p;
450 if (offsets.
uv == -1) {
472 if (
options->only_selected_uvs && !
l) {
486 bool have_select =
false;
487 for (
Object *obedit : objects) {
498 const int material_index,
502 if (
UNLIKELY(material_index < 0 || material_index >= ob->
totcol)) {
517 bool selected =
false;
532 return aspect[0] / aspect[1];
548 if (
options->only_selected_uvs) {
574 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, 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) {
773 handle, scene, efa,
i + offset,
options, offsets, cd_weight_offset, cd_weight_index);
779 offset +=
bm->totface;
783 handle,
options->fill_holes,
options->topology_from_uvs,
nullptr);
824 em->
bm,
nullptr,
static_cast<const Mesh *
>(object->
data));
833 if (settings.
level == 1) {
860 int *r_count_failed =
nullptr)
899 const int *origVertIndices =
static_cast<const int *
>(
901 const int *origEdgeIndices =
static_cast<const int *
>(
903 const int *origPolyIndices =
static_cast<const int *
>(
953 vkeys[0] = (
ParamKey)poly_corner_verts[0];
954 vkeys[1] = (
ParamKey)poly_corner_verts[1];
955 vkeys[2] = (
ParamKey)poly_corner_verts[2];
956 vkeys[3] = (
ParamKey)poly_corner_verts[3];
958 co[0] = subsurf_positions[poly_corner_verts[0]];
959 co[1] = subsurf_positions[poly_corner_verts[1]];
960 co[2] = subsurf_positions[poly_corner_verts[2]];
961 co[3] = subsurf_positions[poly_corner_verts[3]];
964 if (cd_weight_index >= 0) {
987 origVertIndices[poly_corner_verts[0]],
994 origVertIndices[poly_corner_verts[1]],
1001 origVertIndices[poly_corner_verts[2]],
1008 origVertIndices[poly_corner_verts[3]],
1014 handle, key, 4, vkeys, co, uv, weight, pin,
select);
1029 handle,
options->fill_holes,
options->topology_from_uvs, r_count_failed);
1061 options.topology_from_uvs =
true;
1063 options.only_selected_faces =
true;
1064 options.only_selected_uvs =
true;
1065 options.correct_aspect =
true;
1074 MinStretch *ms = MEM_new<MinStretch>(__func__);
1084 if (ms->
blend != 0.0f) {
1182 for (
i = 0;
i < iterations;
i++) {
1211 switch (event->
type) {
1224 if (ms->
blend < 0.95f) {
1235 if (ms->
blend > 0.05f) {
1273 ot->name =
"Minimize Stretch";
1274 ot->idname =
"UV_OT_minimize_stretch";
1276 ot->description =
"Reduce UV stretching by relaxing angles";
1290 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
1291 "preserve symmetry");
1298 "Blend factor between stretch minimized and original",
1307 "Number of iterations to run, 0 is unlimited when run interactively",
1315 const float matrix[2][2],
1316 const float pre_translate[2]
1330 const int cd_loop_uv_offset = island->
offsets.
uv;
1331 const int faces_len = island->
faces_len;
1332 for (
int i = 0;
i < faces_len;
i++) {
1347 const float coords[2],
1348 float nearest_tile_co[2])
1353 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1354 add_v2_fl(nearest_tile_center_co, 0.5f);
1363 const float coords[2],
1364 float nearest_tile_co[2])
1366 const float coords_floor[2] = {
floorf(coords[0]),
floorf(coords[1])};
1368 if (coords[0] > udim_grid[0]) {
1369 nearest_tile_co[0] = udim_grid[0] - 1;
1371 else if (coords[0] < 0) {
1372 nearest_tile_co[0] = 0;
1375 nearest_tile_co[0] = coords_floor[0];
1378 if (coords[1] > udim_grid[1]) {
1379 nearest_tile_co[1] = udim_grid[1] - 1;
1381 else if (coords[1] < 0) {
1382 nearest_tile_co[1] = 0;
1385 nearest_tile_co[1] = coords_floor[1];
1389 float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]};
1390 add_v2_fl(nearest_tile_center_co, 0.5f);
1399 const bool pin_unselected =
params->pin_unselected;
1400 const bool only_selected_faces =
params->only_selected_faces;
1437 BMesh **bmesh_override,
1439 const bool original_selection,
1440 const bool notify_wm,
1446 for (
const int ob_index : objects.
index_range()) {
1447 Object *obedit = objects[ob_index];
1449 if (bmesh_override) {
1451 bm = bmesh_override[ob_index];
1460 if (offsets.
uv == -1) {
1466 bool only_selected_faces =
params->only_selected_faces;
1467 bool only_selected_uvs =
params->only_selected_uvs;
1469 if (ignore_pinned &&
params->pin_unselected) {
1470 only_selected_faces =
false;
1471 only_selected_uvs =
false;
1477 only_selected_faces,
1487 if (ignore_pinned && pinned) {
1492 island_vector.
append(island);
1493 pinned_vector.
append(pinned);
1502 float selection_min_co[2], selection_max_co[2];
1505 for (
int index = 0; index < island_vector.
size(); index++) {
1515 float selection_center[2];
1516 mid_v2_v2v2(selection_center, selection_min_co, selection_max_co);
1518 if (original_selection) {
1520 if ((selection_max_co[0] - selection_min_co[0]) * (selection_max_co[1] - selection_min_co[1]) >
1524 params->target_extent = selection_max_co[1] - selection_min_co[1];
1525 params->target_aspect_y = (selection_max_co[0] - selection_min_co[0]) /
1526 (selection_max_co[1] - selection_min_co[1]);
1534 for (
int i = 0;
i < island_vector.
size();
i++) {
1539 pack_island->
pinned = pinned_vector[
i];
1540 pack_island_vector.
append(pack_island);
1565 const bool is_cancelled =
params->isCancelled();
1567 float base_offset[2] = {0.0f, 0.0f};
1570 if (udim_source_closest) {
1571 const Image *image = udim_source_closest->
image;
1575 if (is_valid_udim) {
1576 base_offset[0] =
floorf(selection_center[0]);
1577 base_offset[1] =
floorf(selection_center[1]);
1582 float nearest_image_tile_dist =
FLT_MAX, nearest_grid_tile_dist =
FLT_MAX;
1585 image, selection_center, nearest_image_tile_co);
1588 float nearest_grid_tile_co[2] = {0.0f, 0.0f};
1590 udim_grid, selection_center, nearest_grid_tile_co);
1592 base_offset[0] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1593 nearest_image_tile_co[0] :
1594 nearest_grid_tile_co[0];
1595 base_offset[1] = (nearest_image_tile_dist < nearest_grid_tile_dist) ?
1596 nearest_image_tile_co[1] :
1597 nearest_grid_tile_co[1];
1602 float matrix_inverse[2][2];
1603 float pre_translate[2];
1610 const float island_scale = pack_island->
can_scale_(*
params) ? scale : 1.0f;
1616 mul_v2_m2v2(pre_translate, matrix_inverse, base_offset);
1630 pack_island_vector[
i] =
nullptr;
1634 if (notify_wm && !is_cancelled) {
1635 for (
Object *obedit : objects) {
1679 worker_status->progress = 0.02f;
1695 worker_status->progress = 0.99f;
1696 worker_status->do_update =
true;
1728 options.topology_from_uvs =
true;
1729 options.only_selected_faces =
true;
1730 options.only_selected_uvs =
true;
1732 options.correct_aspect =
true;
1754 pid->
objects = std::move(objects);
1763 pack_island_params = default_params;
1815 wmJobWorkerStatus worker_status = {};
1828 "Use scale of existing UVs to multiply margin"},
1834 "Specify a precise fraction of final UV output"},
1835 {0,
nullptr, 0,
nullptr,
nullptr},
1844 "Only 90 degree rotations are allowed"},
1847#define PACK_ROTATE_METHOD_AXIS_ALIGNED_OFFSET 3
1852 "Rotated to a minimal rectangle, either vertical or horizontal"},
1856 "Axis-aligned (Horizontal)",
1857 "Rotate islands to be aligned horizontally"},
1861 "Axis-aligned (Vertical)",
1862 "Rotate islands to be aligned vertically"},
1863 {0,
nullptr, 0,
nullptr,
nullptr},
1871 {0,
nullptr, 0,
nullptr,
nullptr},
1886 "Rotation and Scale",
1887 "Pinned islands will translate only"},
1889 {0,
nullptr, 0,
nullptr,
nullptr},
1934 "Pack islands to active UDIM image tile or UDIM grid tile where 2D cursor is located"},
1938 "Original bounding box",
1939 "Pack to starting bounding box of islands"},
1940 {0,
nullptr, 0,
nullptr,
nullptr},
1943 ot->name =
"Pack Islands";
1944 ot->idname =
"UV_OT_pack_islands";
1946 "Transform all islands so that they fill up the UV/UDIM space as much as possible";
1948#ifdef USE_INTERACTIVE_PACK
1958#ifdef USE_INTERACTIVE_PACK
1968 RNA_def_boolean(
ot->srna,
"rotate",
true,
"Rotate",
"Rotate islands to improve layout");
1975 RNA_def_boolean(
ot->srna,
"scale",
true,
"Scale",
"Scale islands to fill unit square");
1977 ot->srna,
"merge_overlap",
false,
"Merge Overlapping",
"Overlapping islands stick together");
1985 ot->srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
1989 "Lock Pinned Islands",
1990 "Constrain islands containing any pinned UV's");
2019 options.topology_from_uvs =
true;
2020 options.only_selected_faces =
true;
2021 options.only_selected_uvs =
true;
2023 options.correct_aspect =
true;
2041 for (
Object *obedit : objects) {
2057 ot->name =
"Average Islands Scale";
2058 ot->idname =
"UV_OT_average_islands_scale";
2059 ot->description =
"Average the size of separate UV islands, based on their area in 3D space";
2068 RNA_def_boolean(
ot->srna,
"scale_uv",
false,
"Non-Uniform",
"Scale U and V independently");
2069 RNA_def_boolean(
ot->srna,
"shear",
false,
"Shear",
"Reduce shear within islands");
2118 options.topology_from_uvs =
false;
2119 options.only_selected_faces =
false;
2120 options.only_selected_uvs =
false;
2131 options.slim.skip_init =
true;
2150 "uvedit_live_unwrap_liveHandles");
2217#define VIEW_ON_EQUATOR 0
2218#define VIEW_ON_POLES 1
2219#define ALIGN_TO_OBJECT 2
2245 uint center_accum_num = 0;
2252 center_accum_num += 1;
2255 mul_v3_fl(r_center, 1.0f /
float(center_accum_num));
2263 float r_bounds[2][3])
2271 bool is_minmax_set =
false;
2277 is_minmax_set =
true;
2307 if (!is_minmax_set) {
2321 const float offset[4])
2323 float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4];
2324 float sideangle = 0.0f, upangle = 0.0f;
2338 copy_m4_m4(rotobj, ob->object_to_world().ptr());
2343 rotobj[3][3] = 0.0f;
2351 sideangle = float(
M_PI) * (sideangledeg + 180.0f) / 180.0f;
2352 rotside[0][0] =
cosf(sideangle);
2353 rotside[0][1] = -
sinf(sideangle);
2354 rotside[1][0] =
sinf(sideangle);
2355 rotside[1][1] =
cosf(sideangle);
2356 rotside[2][2] = 1.0f;
2358 upangle = float(
M_PI) * upangledeg / 180.0f;
2359 rotup[1][1] =
cosf(upangle) / radius;
2360 rotup[1][2] = -
sinf(upangle) / radius;
2361 rotup[2][1] =
sinf(upangle) / radius;
2362 rotup[2][2] =
cosf(upangle) / radius;
2363 rotup[0][0] = 1.0f / radius;
2385 rotmat[0][0] = 0.0f;
2386 rotmat[0][1] = 1.0f;
2387 rotmat[1][0] = -1.0f;
2388 rotmat[1][1] = 0.0f;
2393 const float up_angle_deg = (direction ==
VIEW_ON_EQUATOR) ? 90.0f : 0.0f;
2396 const float offset[4] = {0};
2397 float rotmat4[4][4];
2405 {
VIEW_ON_EQUATOR,
"VIEW_ON_EQUATOR", 0,
"View on Equator",
"3D view is on the equator"},
2406 {
VIEW_ON_POLES,
"VIEW_ON_POLES", 0,
"View on Poles",
"3D view is on the poles"},
2411 "Align according to object transform"},
2412 {0,
nullptr, 0,
nullptr,
nullptr},
2415 {
POLAR_ZX,
"POLAR_ZX", 0,
"Polar ZX",
"Polar 0 is X"},
2416 {
POLAR_ZY,
"POLAR_ZY", 0,
"Polar ZY",
"Polar 0 is Y"},
2417 {0,
nullptr, 0,
nullptr,
nullptr},
2421 {
PINCH,
"PINCH", 0,
"Pinch",
"UVs are pinched at the poles"},
2422 {
FAN,
"FAN", 0,
"Fan",
"UVs are fanned at the poles"},
2423 {0,
nullptr, 0,
nullptr,
nullptr},
2431 "Direction of the sphere or cylinder");
2437 "How to determine rotation around the pole");
2438 RNA_def_enum(
ot->srna,
"pole", pole_items,
PINCH,
"Pole",
"How to handle faces at the poles");
2443 "Separate projections by islands isolated by seams");
2452 "Radius of the sphere or cylinder",
2459 const int cd_loop_uv_offset,
2460 const float aspect_y)
2469 if (aspect_y > 1.0f) {
2471 luv[0] = luv[0] / aspect_y + (0.5f - 0.5f / aspect_y);
2475 luv[1] = luv[1] * aspect_y + (0.5f - 0.5f * aspect_y);
2484 if (aspect_y == 1.0f) {
2499 const int materials_num = ob->
totcol;
2500 if (materials_num == 0) {
2517 const int material_index = efa->
mat_nr;
2518 if (
UNLIKELY(material_index < 0 || material_index >= materials_num)) {
2523 float aspect_y = material_aspect_y[material_index];
2524 if (aspect_y == -1.0f) {
2528 aspect_y = aspx / aspy;
2529 material_aspect_y[material_index] = aspect_y;
2532 if (aspect_y == 1.0f) {
2540#undef VIEW_ON_EQUATOR
2542#undef ALIGN_TO_OBJECT
2557 if (clip_to_bounds) {
2562 "Clip UV coordinates to bounds after unwrapping");
2568 "Scale UV coordinates to bounds after unwrapping");
2586 bool per_face_aspect,
2587 bool only_selected_uvs)
2592 float dx, dy,
min[2],
max[2];
2600 for (
Object *ob : objects) {
2605 if (correct_aspect) {
2606 if (per_face_aspect) {
2614 if (scale_to_bounds) {
2631 else if (clip_to_bounds) {
2650 if (scale_to_bounds) {
2662 if (dx == 1.0f && dy == 1.0f &&
min[0] == 0.0f &&
min[1] == 0.0f) {
2667 for (
Object *ob : objects) {
2683 luv[0] = (luv[0] -
min[0]) * dx;
2684 luv[1] = (luv[1] -
min[1]) * dy;
2701 int *r_count_changed,
2702 int *r_count_failed)
2739 int *r_count_changed =
nullptr,
2740 int *r_count_failed =
nullptr)
2742 for (
Object *obedit : objects) {
2753 options.topology_from_uvs =
false;
2754 options.only_selected_faces =
false;
2755 options.only_selected_uvs =
false;
2779 int reported_errors = 0;
2787 options.topology_from_uvs =
false;
2788 options.only_selected_faces =
true;
2789 options.only_selected_uvs =
false;
2793 bool subsurf_error =
options.use_subsurf;
2797 options.only_selected_uvs =
true;
2798 options.pin_unselected =
true;
2806 for (
Object *obedit : objects) {
2808 bool use_subsurf_final;
2814 if (subsurf_error) {
2818 if (use_subsurf_final) {
2819 subsurf_error =
false;
2828 if (!(
fabsf(obsize[0] - obsize[1]) < 1e-4f &&
fabsf(obsize[1] - obsize[2]) < 1e-4f)) {
2832 "Object has non-uniform scale, unwrap will operate on a non-scaled version of "
2842 "Object has negative scale, unwrap will operate on a non-flipped version of the mesh");
2848 if (subsurf_error) {
2851 "Subdivision Surface modifier needs to be first to work with unwrap");
2855 int count_changed = 0;
2856 int count_failed = 0;
2869 if (count_failed == 0 && count_changed == 0) {
2872 "Unwrap could not solve any island(s), edge seams may need to be added");
2874 else if (count_failed) {
2877 "Unwrap failed to solve %d of %d island(s), edge seams may need to be added",
2879 count_changed + count_failed);
2935 {0,
nullptr, 0,
nullptr,
nullptr},
2939 ot->name =
"Unwrap";
2940 ot->description =
"Unwrap the mesh of the object being edited";
2941 ot->idname =
"UV_OT_unwrap";
2958 "Unwrapping method (Angle Based usually gives better results than Conformal, while "
2959 "being somewhat slower)");
2964 "Virtually fill holes in mesh before unwrapping, to better avoid overlaps and "
2965 "preserve symmetry");
2973 "Use Subdivision Surface",
2974 "Map UVs taking vertex position after Subdivision Surface modifier has been applied");
2982 ot->srna,
"margin", 0.001f, 0.0f, 1.0f,
"Margin",
"Space between islands", 0.0f, 1.0f);
2989 "Prevent flipping UV's, "
2990 "flipping may lower distortion depending on the position of pins");
2998 "Number of iterations when \"Minimum Stretch\" method is used",
3005 "Importance Weights",
3006 "Whether to take into account per-vertex importance weights");
3012 "Vertex group name for importance weights (modulating the deform)");
3020 "How much influence the weightmap has for weighted parameterization, 0 being no influence",
3063 const uint thick_faces_len,
3065 const float project_angle_limit_half_cos,
3066 const float project_angle_limit_cos,
3067 const float area_weight)
3069 if (
UNLIKELY(thick_faces_len == 0)) {
3073 const float *project_normal = thick_faces[0].
efa->
no;
3081 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3086 if (
dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) {
3087 project_thick_faces.
append(&thick_faces[f_index]);
3092 float average_normal[3] = {0.0f, 0.0f, 0.0f};
3094 if (area_weight <= 0.0f) {
3095 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3096 const ThickFace *tf = project_thick_faces[f_proj_index];
3100 else if (area_weight >= 1.0f) {
3101 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3102 const ThickFace *tf = project_thick_faces[f_proj_index];
3107 for (
int f_proj_index = 0; f_proj_index < project_thick_faces.
size(); f_proj_index++) {
3108 const ThickFace *tf = project_thick_faces[f_proj_index];
3109 const float area_blend = (tf->
area * area_weight) + (1.0f - area_weight);
3116 project_normal_array.
append(average_normal);
3120 float anble_best = 1.0f;
3121 uint angle_best_index = 0;
3123 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3128 float angle_test = -1.0f;
3129 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3130 angle_test =
max_ff(angle_test,
3131 dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no));
3134 if (angle_test < anble_best) {
3135 anble_best = angle_test;
3136 angle_best_index = f_index;
3140 if (anble_best < project_angle_limit_cos) {
3141 project_normal = thick_faces[angle_best_index].
efa->
no;
3142 project_thick_faces.
clear();
3143 project_thick_faces.
append(&thick_faces[angle_best_index]);
3147 if (project_normal_array.
size() >= 1) {
3155 return project_normal_array;
3166 bool only_selected_uvs =
false;
3169 only_selected_uvs =
true;
3176 const float project_angle_limit_cos =
cosf(project_angle_limit);
3177 const float project_angle_limit_half_cos =
cosf(project_angle_limit / 2);
3183 scene, view_layer, v3d);
3190 for (
const int ob_index : objects.
index_range()) {
3191 Object *obedit = objects[ob_index];
3193 bool changed =
false;
3203 uint thick_faces_len = 0;
3209 if (only_selected_uvs) {
3217 thick_faces[thick_faces_len].
efa = efa;
3224 while ((thick_faces_len > 0) &&
3237 thick_faces_len -= 1;
3244 project_angle_limit_half_cos,
3245 project_angle_limit_cos,
3248 if (project_normal_array.
is_empty()) {
3255 MEM_callocN(
sizeof(*thickface_project_groups) * project_normal_array.
size(), __func__));
3259 for (
int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
3260 const float *f_normal = thick_faces[f_index].
efa->
no;
3262 float angle_best =
dot_v3v3(f_normal, project_normal_array[0]);
3263 uint angle_best_index = 0;
3265 for (
int p_index = 1; p_index < project_normal_array.
size(); p_index++) {
3266 const float angle_test =
dot_v3v3(f_normal, project_normal_array[p_index]);
3267 if (angle_test > angle_best) {
3268 angle_best = angle_test;
3269 angle_best_index = p_index;
3274 &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena);
3277 for (
int p_index = 0; p_index < project_normal_array.
size(); p_index++) {
3278 if (thickface_project_groups[p_index] ==
nullptr) {
3282 float axis_mat[3][3];
3285 for (
LinkNode *list = thickface_project_groups[p_index]; list; list = list->
next) {
3303 objects_changed.
append(obedit);
3319 params.only_selected_uvs = only_selected_uvs;
3320 params.only_selected_faces =
true;
3321 params.correct_aspect = correct_aspect;
3329 const bool per_face_aspect =
false;
3339 C, op, event,
IFACE_(
"Smart UV Project"),
IFACE_(
"Unwrap"));
3347 ot->name =
"Smart UV Project";
3348 ot->idname =
"UV_OT_smart_project";
3349 ot->description =
"Projection unwraps the selected faces of mesh objects";
3366 "Lower for more projection groups, higher for less distortion",
3391 "Margin to reduce bleed from adjacent islands",
3400 "Weight projection's vector by faces with larger areas",
3446 float objects_pos_offset[4];
3452 scene, view_layer, v3d);
3454 if (use_orthographic) {
3456 float objects_pos_avg[4] = {0};
3458 for (
Object *
object : objects) {
3459 add_v4_v4(objects_pos_avg, object->object_to_world().location());
3462 mul_v4_fl(objects_pos_avg, 1.0f / objects.size());
3468 for (
Object *obedit : objects) {
3470 bool changed =
false;
3479 if (use_orthographic) {
3498 obedit->object_to_world().ptr(),
3499 camera_bounds ? (scene->
r.
xsch * scene->
r.
xasp) : 1.0f,
3500 camera_bounds ? (scene->
r.
ysch * scene->
r.
yasp) : 1.0f);
3519 copy_m4_m4(rotmat, obedit->object_to_world().ptr());
3536 changed_objects.
append(obedit);
3546 const bool per_face_aspect =
true;
3547 const bool only_selected_uvs =
false;
3560 return (rv3d !=
nullptr);
3566 ot->name =
"Project from View";
3567 ot->idname =
"UV_OT_project_from_view";
3568 ot->description =
"Project the UV vertices of the mesh as seen in current 3D view";
3578 RNA_def_boolean(
ot->srna,
"orthographic",
false,
"Orthographic",
"Use orthographic projection");
3583 "Map UVs to the camera region taking resolution and aspect into account");
3600 scene, view_layer, v3d);
3601 for (
Object *obedit : objects) {
3627 ot->idname =
"UV_OT_reset";
3628 ot->description =
"Reset UV projection";
3644 const bool *regular,
3646 const int cd_loop_uv_offset)
3660 float right_u = -1.0e30f;
3668 if (luv[0] >= 1.0f) {
3671 right_u =
max_ff(right_u, luv[0]);
3674 float left_u = 1.0e30f;
3677 if (right_u <= luv[0] + 0.5f) {
3678 left_u =
min_ff(left_u, luv[0]);
3684 if (luv[0] + 0.5f < right_u) {
3685 if (2 * luv[0] + 1.0f < left_u + right_u) {
3699 float minmax_u[2] = {1.0e30f, -1.0e30f};
3701 for (
int i = 0;
i < efa->
len;
i++) {
3703 minmax_u[0] =
min_ff(minmax_u[0], uvs[
i][0]);
3704 minmax_u[1] =
max_ff(minmax_u[1], uvs[
i][0]);
3710 if (
ELEM(pole_count, 0, efa->
len)) {
3713 for (
int i = 0;
i < efa->
len;
i++) {
3719 const int i_plus = (
i + 1) % efa->
len;
3720 const int i_minus = (
i + efa->
len - 1) % efa->
len;
3721 if (regular[i_plus]) {
3722 u += uvs[i_plus][0];
3725 if (regular[i_minus]) {
3726 u += uvs[i_minus][0];
3730 u += minmax_u[0] + minmax_u[1];
3733 uvs[
i][0] = u /
sum;
3768 const float center[3],
3769 const float rotmat[3][3],
3772 const bool only_selected_uvs,
3773 const bool use_seams,
3774 const float branch_init)
3783 stack.
append({efa_init, branch_init});
3785 while (stack.
size()) {
3801 if (only_selected_uvs) {
3819 regular[
i] =
map_to_sphere(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
3825 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
3826 max_u =
max_ff(max_u, luv[0]);
3838 stack.
append({efa2, luv[0]});
3853 bool only_selected_uvs =
false;
3856 only_selected_uvs =
true;
3861 scene, view_layer, v3d);
3862 for (
Object *obedit : objects) {
3877 float center[3], rotmat[3][3];
3889 float island_offset = 0.0f;
3900 island_offset + 0.5f);
3901 island_offset =
ceilf(
max_ff(max_u, island_offset));
3904 const bool per_face_aspect =
true;
3917 ot->name =
"Sphere Projection";
3918 ot->idname =
"UV_OT_sphere_project";
3919 ot->description =
"Project the UV vertices of the mesh over the curved surface of a sphere";
3942 const float center[3],
3943 const float rotmat[3][3],
3946 const bool only_selected_uvs,
3947 const bool use_seams,
3948 const float branch_init)
3959 stack.
append({efa_init, branch_init});
3961 while (stack.
size()) {
3977 if (only_selected_uvs) {
3995 regular[
i] =
map_to_tube(&luv[0], &luv[1], pv[0], pv[1], pv[2]);
4002 luv[0] = luv[0] +
ceilf(face_branch.
branch - 0.5f - luv[0]);
4003 max_u =
max_ff(max_u, luv[0]);
4015 stack.
append({efa2, luv[0]});
4031 bool only_selected_uvs =
false;
4034 only_selected_uvs =
true;
4039 scene, view_layer, v3d);
4040 for (
Object *obedit : objects) {
4055 float center[3], rotmat[3][3];
4067 float island_offset = 0.0f;
4088 island_offset + 0.5f);
4089 island_offset =
ceilf(
max_ff(max_u, island_offset));
4092 const bool per_face_aspect =
true;
4105 ot->name =
"Cylinder Projection";
4106 ot->idname =
"UV_OT_cylinder_project";
4107 ot->description =
"Project the UV vertices of the mesh over the curved wall of a cylinder";
4129 const bool use_select,
4130 const bool only_selected_uvs,
4131 const float center[3])
4168 luv[0] = 0.5f + ((
l->v->co[cox] - loc[cox]) / cube_size);
4169 luv[1] = 0.5f + ((
l->v->co[coy] - loc[coy]) / cube_size);
4179 bool only_selected_uvs =
false;
4182 only_selected_uvs =
true;
4190 scene, view_layer, v3d);
4191 for (
const int ob_index : objects.
index_range()) {
4192 Object *obedit = objects[ob_index];
4205 float(*bounds_buf)[3] =
nullptr;
4215 float cube_size = cube_size_init;
4220 if (ob_index == 0) {
4228 const bool per_face_aspect =
true;
4241 ot->name =
"Cube Projection";
4242 ot->idname =
"UV_OT_cube_project";
4243 ot->description =
"Project the UV vertices of the mesh over the six faces of a cube";
4258 "Size of the cube to project on",
4298 params.only_selected_uvs =
false;
4299 params.only_selected_faces =
false;
4300 params.correct_aspect =
false;
4312 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)
@ 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)
#define SNPRINTF(dst, format,...)
char * STRNCPY(char(&dst)[N], const char *src)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define INIT_MINMAX2(min, max)
#define INIT_MINMAX(min, max)
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)
bool uvedit_face_select_test(const Scene *scene, const BMFace *efa, const BMUVOffsets &offsets)
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 uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa, const BMUVOffsets &offsets)
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()
bool uvedit_uv_select_test(const Scene *scene, 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)
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 RNA_ENUM_ITEM_SEPR
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
#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_attr_edge_select_ensure(BMesh *bm, const StringRef uv_map_name)
void BM_uv_map_attr_vert_select_ensure(BMesh *bm, const StringRef 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)
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
#define MEM_reallocN(vmemh, len)
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
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_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)
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
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
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_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 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 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 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 uvedit_unwrap(const Scene *scene, Object *obedit, const UnwrapOptions *options, int *r_count_changed, int *r_count_failed)
@ UNWRAP_ERROR_NONUNIFORM
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 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 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 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 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 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 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 uvedit_ensure_uvs(Object *obedit)
static bool rna_property_sync_int(PointerRNA *ptr, const char *prop_name, int *value_p)
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 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)
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 struct @156300107036162110351213232142201364151003230060 g_live_unwrap
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 bool uvedit_is_face_affected(const Scene *scene, BMFace *efa, const UnwrapOptions *options, const BMUVOffsets &offsets)
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_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_set_locked_interface_with_flags(wmWindowManager *wm, short lock_flags)
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))
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)
wmOperatorStatus WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *)
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)