Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/uvedit/uvedit_islands.cc
| Show All 34 Lines | |||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UV Face Utilities | /** \name UV Face Utilities | ||||
| * \{ */ | * \{ */ | ||||
| static void bm_face_uv_scale_y(BMFace *f, const float scale_y, const int cd_loop_uv_offset) | |||||
| { | |||||
| BMLoop *l_iter; | |||||
| BMLoop *l_first; | |||||
| l_iter = l_first = BM_FACE_FIRST_LOOP(f); | |||||
| do { | |||||
| MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset)); | |||||
| luv->uv[1] *= scale_y; | |||||
| } while ((l_iter = l_iter->next) != l_first); | |||||
| } | |||||
| static void bm_face_uv_translate_and_scale_around_pivot(BMFace *f, | static void bm_face_uv_translate_and_scale_around_pivot(BMFace *f, | ||||
| const float offset[2], | const float offset[2], | ||||
| const float scale[2], | const float scale[2], | ||||
| const float pivot[2], | const float pivot[2], | ||||
| const int cd_loop_uv_offset) | const int cd_loop_uv_offset) | ||||
| { | { | ||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| BMLoop *l_first; | BMLoop *l_first; | ||||
| l_iter = l_first = BM_FACE_FIRST_LOOP(f); | l_iter = l_first = BM_FACE_FIRST_LOOP(f); | ||||
| do { | do { | ||||
| MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset)); | MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset)); | ||||
| for (int i = 0; i < 2; i++) { | for (int i = 0; i < 2; i++) { | ||||
| luv->uv[i] = offset[i] + (((luv->uv[i] - pivot[i]) * scale[i]) + pivot[i]); | luv->uv[i] = offset[i] + (((luv->uv[i] - pivot[i]) * scale[i]) + pivot[i]); | ||||
| } | } | ||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UV Face Array Utilities | /** \name UV Face Array Utilities | ||||
| * \{ */ | * \{ */ | ||||
| static void bm_face_array_calc_bounds(BMFace **faces, | static void bm_face_array_calc_bounds(BMFace **faces, | ||||
| int faces_len, | const int faces_len, | ||||
| const int cd_loop_uv_offset, | const int cd_loop_uv_offset, | ||||
| rctf *r_bounds_rect) | rctf *r_bounds_rect) | ||||
| { | { | ||||
| BLI_assert(cd_loop_uv_offset >= 0); | BLI_assert(cd_loop_uv_offset >= 0); | ||||
| float bounds_min[2], bounds_max[2]; | float bounds_min[2], bounds_max[2]; | ||||
| INIT_MINMAX2(bounds_min, bounds_max); | INIT_MINMAX2(bounds_min, bounds_max); | ||||
| for (int i = 0; i < faces_len; i++) { | for (int i = 0; i < faces_len; i++) { | ||||
| BMFace *f = faces[i]; | BMFace *f = faces[i]; | ||||
| ▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | do { | ||||
| } | } | ||||
| } while ((e = BM_DISK_EDGE_NEXT(e, v_pivot)) != e_first); | } while ((e = BM_DISK_EDGE_NEXT(e, v_pivot)) != e_first); | ||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| } | } | ||||
| *r_coords_len = coords_len; | *r_coords_len = coords_len; | ||||
| return coords; | return coords; | ||||
| } | } | ||||
| /** | static void face_island_uv_rotate_fit_aabb(FaceIsland *island) | ||||
| * \param align_to_axis: | |||||
| * - -1: don't align to an axis. | |||||
| * - 0: align horizontally. | |||||
| * - 1: align vertically. | |||||
| */ | |||||
| static void bm_face_array_uv_rotate_fit_aabb(BMFace **faces, | |||||
| int faces_len, | |||||
| int align_to_axis, | |||||
| const int cd_loop_uv_offset) | |||||
| { | { | ||||
| BMFace **faces = island->faces; | |||||
| const int faces_len = island->faces_len; | |||||
| const float aspect_y = island->aspect_y; | |||||
| const int cd_loop_uv_offset = island->cd_loop_uv_offset; | |||||
| /* Calculate unique coordinates since calculating a convex hull can be an expensive operation. */ | /* Calculate unique coordinates since calculating a convex hull can be an expensive operation. */ | ||||
| int coords_len; | int coords_len; | ||||
| float(*coords)[2] = bm_face_array_calc_unique_uv_coords( | float(*coords)[2] = bm_face_array_calc_unique_uv_coords( | ||||
| faces, faces_len, cd_loop_uv_offset, &coords_len); | faces, faces_len, cd_loop_uv_offset, &coords_len); | ||||
| /* Correct aspect ratio. */ | |||||
| if (aspect_y != 1.0f) { | |||||
| for (int i = 0; i < coords_len; i++) { | |||||
| coords[i][1] /= aspect_y; | |||||
| } | |||||
| } | |||||
| float angle = BLI_convexhull_aabb_fit_points_2d(coords, coords_len); | float angle = BLI_convexhull_aabb_fit_points_2d(coords, coords_len); | ||||
| if (align_to_axis != -1) { | /* Rotate coords by `angle` before computing bounding box. */ | ||||
| if (angle != 0.0f) { | if (angle != 0.0f) { | ||||
| float matrix[2][2]; | float matrix[2][2]; | ||||
| angle_to_mat2(matrix, angle); | angle_to_mat2(matrix, angle); | ||||
| matrix[0][1] *= aspect_y; | |||||
| matrix[1][1] *= aspect_y; | |||||
| for (int i = 0; i < coords_len; i++) { | for (int i = 0; i < coords_len; i++) { | ||||
| mul_m2_v2(matrix, coords[i]); | mul_m2_v2(matrix, coords[i]); | ||||
| } | } | ||||
| } | } | ||||
| /* Compute new AABB. */ | |||||
| float bounds_min[2], bounds_max[2]; | float bounds_min[2], bounds_max[2]; | ||||
| INIT_MINMAX2(bounds_min, bounds_max); | INIT_MINMAX2(bounds_min, bounds_max); | ||||
| for (int i = 0; i < coords_len; i++) { | for (int i = 0; i < coords_len; i++) { | ||||
| minmax_v2v2_v2(bounds_min, bounds_max, coords[i]); | minmax_v2v2_v2(bounds_min, bounds_max, coords[i]); | ||||
| } | } | ||||
| float size[2]; | float size[2]; | ||||
| sub_v2_v2v2(size, bounds_max, bounds_min); | sub_v2_v2v2(size, bounds_max, bounds_min); | ||||
| if (align_to_axis ? (size[1] < size[0]) : (size[0] < size[1])) { | if (size[1] < size[0]) { | ||||
| angle += DEG2RAD(90.0); | angle += DEG2RADF(90.0f); | ||||
| } | |||||
| } | } | ||||
| MEM_freeN(coords); | MEM_freeN(coords); | ||||
| /* Apply rotation back to BMesh. */ | |||||
| if (angle != 0.0f) { | if (angle != 0.0f) { | ||||
| float matrix[2][2]; | float matrix[2][2]; | ||||
| angle_to_mat2(matrix, angle); | angle_to_mat2(matrix, angle); | ||||
| matrix[1][0] *= 1.0f / aspect_y; | |||||
| /* matrix[1][1] *= aspect_y / aspect_y; */ | |||||
| matrix[0][1] *= aspect_y; | |||||
| for (int i = 0; i < faces_len; i++) { | for (int i = 0; i < faces_len; i++) { | ||||
| BM_face_uv_transform(faces[i], matrix, cd_loop_uv_offset); | BM_face_uv_transform(faces[i], matrix, cd_loop_uv_offset); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void bm_face_array_uv_scale_y(BMFace **faces, | |||||
| int faces_len, | |||||
| const float scale_y, | |||||
| const int cd_loop_uv_offset) | |||||
| { | |||||
| for (int i = 0; i < faces_len; i++) { | |||||
| BMFace *f = faces[i]; | |||||
| bm_face_uv_scale_y(f, scale_y, cd_loop_uv_offset); | |||||
| } | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name UDIM packing helper functions | /** \name UDIM packing helper functions | ||||
| * \{ */ | * \{ */ | ||||
| bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2]) | bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2]) | ||||
| { | { | ||||
| Show All 39 Lines | static float uv_nearest_image_tile_distance(const Image *image, | ||||
| return len_squared_v2v2(coords, nearest_tile_center_co); | return len_squared_v2v2(coords, nearest_tile_center_co); | ||||
| } | } | ||||
| /** | /** | ||||
| * Calculates distance to nearest UDIM grid tile in UV space and its UDIM tile number. | * Calculates distance to nearest UDIM grid tile in UV space and its UDIM tile number. | ||||
| */ | */ | ||||
| static float uv_nearest_grid_tile_distance(const int udim_grid[2], | static float uv_nearest_grid_tile_distance(const int udim_grid[2], | ||||
| float coords[2], | const float coords[2], | ||||
| float nearest_tile_co[2]) | float nearest_tile_co[2]) | ||||
| { | { | ||||
| const float coords_floor[2] = {floorf(coords[0]), floorf(coords[1])}; | const float coords_floor[2] = {floorf(coords[0]), floorf(coords[1])}; | ||||
| if (coords[0] > udim_grid[0]) { | if (coords[0] > udim_grid[0]) { | ||||
| nearest_tile_co[0] = udim_grid[0] - 1; | nearest_tile_co[0] = udim_grid[0] - 1; | ||||
| } | } | ||||
| else if (coords[0] < 0) { | else if (coords[0] < 0) { | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | int bm_mesh_calc_uv_islands(const Scene *scene, | ||||
| return island_added; | return island_added; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Public UV Island Packing | /** \name Public UV Island Packing | ||||
| * | * | ||||
| * \note This behavior follows #param_pack. | * \note This behavior loosely follows #GEO_uv_parametrizer_pack. | ||||
| * \{ */ | * \{ */ | ||||
| void ED_uvedit_pack_islands_multi(const Scene *scene, | void ED_uvedit_pack_islands_multi(const Scene *scene, | ||||
| Object **objects, | Object **objects, | ||||
| const uint objects_len, | const uint objects_len, | ||||
| const struct UVMapUDIM_Params *udim_params, | const struct UVMapUDIM_Params *udim_params, | ||||
| const struct UVPackIsland_Params *params) | const struct UVPackIsland_Params *params) | ||||
| { | { | ||||
| /* Align to the Y axis, could make this configurable. */ | blender::Vector<FaceIsland *> island_vector; | ||||
| const int rotate_align_axis = 1; | |||||
| ListBase island_list = {NULL}; | |||||
| int island_list_len = 0; | |||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | ||||
| Object *obedit = objects[ob_index]; | Object *obedit = objects[ob_index]; | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | |||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); | ||||
| if (cd_loop_uv_offset == -1) { | if (cd_loop_uv_offset == -1) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| float aspect_y = 1.0f; | float aspect_y = 1.0f; | ||||
| if (params->correct_aspect) { | if (params->correct_aspect) { | ||||
| float aspx, aspy; | float aspx, aspy; | ||||
| ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ||||
| if (aspx != aspy) { | if (aspx != aspy) { | ||||
| aspect_y = aspx / aspy; | aspect_y = aspx / aspy; | ||||
| } | } | ||||
| } | } | ||||
| island_list_len += bm_mesh_calc_uv_islands(scene, | ListBase island_list = {NULL}; | ||||
| bm, | bm_mesh_calc_uv_islands(scene, | ||||
| em->bm, | |||||
| &island_list, | &island_list, | ||||
| params->only_selected_faces, | params->only_selected_faces, | ||||
| params->only_selected_uvs, | params->only_selected_uvs, | ||||
| params->use_seams, | params->use_seams, | ||||
| aspect_y, | aspect_y, | ||||
| cd_loop_uv_offset); | cd_loop_uv_offset); | ||||
| int index; | |||||
| LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list, index) { | |||||
| island_vector.append(island); | |||||
| } | |||||
| } | } | ||||
| if (island_list_len == 0) { | if (island_vector.size() == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| float margin = scene->toolsettings->uvcalc_margin; | float margin = scene->toolsettings->uvcalc_margin; | ||||
| double area = 0.0f; | double area = 0.0f; | ||||
| struct FaceIsland **island_array = static_cast<struct FaceIsland **>( | |||||
| MEM_mallocN(sizeof(*island_array) * island_list_len, __func__)); | |||||
| BoxPack *boxarray = static_cast<BoxPack *>( | BoxPack *boxarray = static_cast<BoxPack *>( | ||||
| MEM_mallocN(sizeof(*boxarray) * island_list_len, __func__)); | MEM_mallocN(sizeof(*boxarray) * island_vector.size(), __func__)); | ||||
| int index; | |||||
| /* Coordinates of bounding box containing all selected UVs. */ | /* Coordinates of bounding box containing all selected UVs. */ | ||||
| float selection_min_co[2], selection_max_co[2]; | float selection_min_co[2], selection_max_co[2]; | ||||
| INIT_MINMAX2(selection_min_co, selection_max_co); | INIT_MINMAX2(selection_min_co, selection_max_co); | ||||
| LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list, index) { | for (int index = 0; index < island_vector.size(); index++) { | ||||
| FaceIsland *island = island_vector[index]; | |||||
| /* Skip calculation if using specified UDIM option. */ | /* Skip calculation if using specified UDIM option. */ | ||||
| if (udim_params && (udim_params->use_target_udim == false)) { | if (udim_params && (udim_params->use_target_udim == false)) { | ||||
| float bounds_min[2], bounds_max[2]; | float bounds_min[2], bounds_max[2]; | ||||
| INIT_MINMAX2(bounds_min, bounds_max); | INIT_MINMAX2(bounds_min, bounds_max); | ||||
| for (int i = 0; i < island->faces_len; i++) { | for (int i = 0; i < island->faces_len; i++) { | ||||
| BMFace *f = island->faces[i]; | BMFace *f = island->faces[i]; | ||||
| BM_face_uv_minmax(f, bounds_min, bounds_max, island->cd_loop_uv_offset); | BM_face_uv_minmax(f, bounds_min, bounds_max, island->cd_loop_uv_offset); | ||||
| } | } | ||||
| selection_min_co[0] = MIN2(bounds_min[0], selection_min_co[0]); | selection_min_co[0] = MIN2(bounds_min[0], selection_min_co[0]); | ||||
| selection_min_co[1] = MIN2(bounds_min[1], selection_min_co[1]); | selection_min_co[1] = MIN2(bounds_min[1], selection_min_co[1]); | ||||
| selection_max_co[0] = MAX2(bounds_max[0], selection_max_co[0]); | selection_max_co[0] = MAX2(bounds_max[0], selection_max_co[0]); | ||||
| selection_max_co[1] = MAX2(bounds_max[1], selection_max_co[1]); | selection_max_co[1] = MAX2(bounds_max[1], selection_max_co[1]); | ||||
| } | } | ||||
| if (params->rotate) { | if (params->rotate) { | ||||
| if (island->aspect_y != 1.0f) { | face_island_uv_rotate_fit_aabb(island); | ||||
| bm_face_array_uv_scale_y( | |||||
| island->faces, island->faces_len, 1.0f / island->aspect_y, island->cd_loop_uv_offset); | |||||
| } | |||||
| bm_face_array_uv_rotate_fit_aabb( | |||||
| island->faces, island->faces_len, rotate_align_axis, island->cd_loop_uv_offset); | |||||
| if (island->aspect_y != 1.0f) { | |||||
| bm_face_array_uv_scale_y( | |||||
| island->faces, island->faces_len, island->aspect_y, island->cd_loop_uv_offset); | |||||
| } | |||||
| } | } | ||||
| bm_face_array_calc_bounds( | bm_face_array_calc_bounds( | ||||
| island->faces, island->faces_len, island->cd_loop_uv_offset, &island->bounds_rect); | island->faces, island->faces_len, island->cd_loop_uv_offset, &island->bounds_rect); | ||||
| BoxPack *box = &boxarray[index]; | BoxPack *box = &boxarray[index]; | ||||
| box->index = index; | box->index = index; | ||||
| box->x = 0.0f; | box->x = 0.0f; | ||||
| box->y = 0.0f; | box->y = 0.0f; | ||||
| box->w = BLI_rctf_size_x(&island->bounds_rect); | box->w = BLI_rctf_size_x(&island->bounds_rect); | ||||
| box->h = BLI_rctf_size_y(&island->bounds_rect); | box->h = BLI_rctf_size_y(&island->bounds_rect); | ||||
| island_array[index] = island; | |||||
| if (margin > 0.0f) { | if (margin > 0.0f) { | ||||
| area += double(sqrtf(box->w * box->h)); | area += double(sqrtf(box->w * box->h)); | ||||
| } | } | ||||
| } | } | ||||
| /* Center of bounding box containing all selected UVs. */ | /* Center of bounding box containing all selected UVs. */ | ||||
| float selection_center[2]; | float selection_center[2]; | ||||
| if (udim_params && (udim_params->use_target_udim == false)) { | if (udim_params && (udim_params->use_target_udim == false)) { | ||||
| selection_center[0] = (selection_min_co[0] + selection_max_co[0]) / 2.0f; | selection_center[0] = (selection_min_co[0] + selection_max_co[0]) / 2.0f; | ||||
| selection_center[1] = (selection_min_co[1] + selection_max_co[1]) / 2.0f; | selection_center[1] = (selection_min_co[1] + selection_max_co[1]) / 2.0f; | ||||
| } | } | ||||
| if (margin > 0.0f) { | if (margin > 0.0f) { | ||||
| /* Logic matches behavior from #param_pack, | /* Logic matches behavior from #GEO_uv_parametrizer_pack, | ||||
| * use area so multiply the margin by the area to give | * use area so multiply the margin by the area to give | ||||
| * predictable results not dependent on UV scale. */ | * predictable results not dependent on UV scale. */ | ||||
| margin = (margin * float(area)) * 0.1f; | margin = (margin * float(area)) * 0.1f; | ||||
| for (int i = 0; i < island_list_len; i++) { | for (int i = 0; i < island_vector.size(); i++) { | ||||
| struct FaceIsland *island = island_array[i]; | FaceIsland *island = island_vector[i]; | ||||
| BoxPack *box = &boxarray[i]; | BoxPack *box = &boxarray[i]; | ||||
| BLI_rctf_pad(&island->bounds_rect, margin, margin); | BLI_rctf_pad(&island->bounds_rect, margin, margin); | ||||
| box->w = BLI_rctf_size_x(&island->bounds_rect); | box->w = BLI_rctf_size_x(&island->bounds_rect); | ||||
| box->h = BLI_rctf_size_y(&island->bounds_rect); | box->h = BLI_rctf_size_y(&island->bounds_rect); | ||||
| } | } | ||||
| } | } | ||||
| float boxarray_size[2]; | float boxarray_size[2]; | ||||
| BLI_box_pack_2d(boxarray, island_list_len, &boxarray_size[0], &boxarray_size[1]); | BLI_box_pack_2d(boxarray, island_vector.size(), &boxarray_size[0], &boxarray_size[1]); | ||||
| /* Don't change the aspect when scaling. */ | /* Don't change the aspect when scaling. */ | ||||
| boxarray_size[0] = boxarray_size[1] = max_ff(boxarray_size[0], boxarray_size[1]); | boxarray_size[0] = boxarray_size[1] = max_ff(boxarray_size[0], boxarray_size[1]); | ||||
| const float scale[2] = {1.0f / boxarray_size[0], 1.0f / boxarray_size[1]}; | const float scale[2] = {1.0f / boxarray_size[0], 1.0f / boxarray_size[1]}; | ||||
| /* Tile offset. */ | /* Tile offset. */ | ||||
| float base_offset[2] = {0.0f, 0.0f}; | float base_offset[2] = {0.0f, 0.0f}; | ||||
| Show All 37 Lines | else { | ||||
| nearest_image_tile_co[0] : | nearest_image_tile_co[0] : | ||||
| nearest_grid_tile_co[0]; | nearest_grid_tile_co[0]; | ||||
| base_offset[1] = (nearest_image_tile_dist < nearest_grid_tile_dist) ? | base_offset[1] = (nearest_image_tile_dist < nearest_grid_tile_dist) ? | ||||
| nearest_image_tile_co[1] : | nearest_image_tile_co[1] : | ||||
| nearest_grid_tile_co[1]; | nearest_grid_tile_co[1]; | ||||
| } | } | ||||
| } | } | ||||
| for (int i = 0; i < island_list_len; i++) { | for (int i = 0; i < island_vector.size(); i++) { | ||||
| struct FaceIsland *island = island_array[boxarray[i].index]; | FaceIsland *island = island_vector[boxarray[i].index]; | ||||
| const float pivot[2] = { | const float pivot[2] = { | ||||
| island->bounds_rect.xmin, | island->bounds_rect.xmin, | ||||
| island->bounds_rect.ymin, | island->bounds_rect.ymin, | ||||
| }; | }; | ||||
| const float offset[2] = { | const float offset[2] = { | ||||
| ((boxarray[i].x * scale[0]) - island->bounds_rect.xmin) + base_offset[0], | ((boxarray[i].x * scale[0]) - island->bounds_rect.xmin) + base_offset[0], | ||||
| ((boxarray[i].y * scale[1]) - island->bounds_rect.ymin) + base_offset[1], | ((boxarray[i].y * scale[1]) - island->bounds_rect.ymin) + base_offset[1], | ||||
| }; | }; | ||||
| for (int j = 0; j < island->faces_len; j++) { | for (int j = 0; j < island->faces_len; j++) { | ||||
| BMFace *efa = island->faces[j]; | BMFace *efa = island->faces[j]; | ||||
| bm_face_uv_translate_and_scale_around_pivot( | bm_face_uv_translate_and_scale_around_pivot( | ||||
| efa, offset, scale, pivot, island->cd_loop_uv_offset); | efa, offset, scale, pivot, island->cd_loop_uv_offset); | ||||
| } | } | ||||
| } | } | ||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | ||||
| Object *obedit = objects[ob_index]; | Object *obedit = objects[ob_index]; | ||||
| DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY); | DEG_id_tag_update(static_cast<ID *>(obedit->data), ID_RECALC_GEOMETRY); | ||||
| WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); | WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); | ||||
| } | } | ||||
| for (int i = 0; i < island_list_len; i++) { | for (FaceIsland *island : island_vector) { | ||||
| MEM_freeN(island_array[i]->faces); | MEM_freeN(island->faces); | ||||
| MEM_freeN(island_array[i]); | MEM_freeN(island); | ||||
| } | } | ||||
| MEM_freeN(island_array); | |||||
| MEM_freeN(boxarray); | MEM_freeN(boxarray); | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||