diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 69da2fe7072..3c3e12e64c2 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -449,7 +449,7 @@ static ParamHandle *construct_param_handle(const Scene *scene, BMIter iter; int i; - ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); + ParamHandle *handle = new blender::geometry::ParamHandle(); if (options->correct_aspect) { blender::geometry::uv_parametrizer_aspect_ratio(handle, ED_uvedit_get_aspect_y(ob)); @@ -491,7 +491,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, BMIter iter; int i; - ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); + ParamHandle *handle = new blender::geometry::ParamHandle(); if (options->correct_aspect) { Object *ob = objects[0]; @@ -615,7 +615,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); - ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); + ParamHandle *handle = new blender::geometry::ParamHandle(); if (options->correct_aspect) { blender::geometry::uv_parametrizer_aspect_ratio(handle, ED_uvedit_get_aspect_y(ob)); @@ -881,7 +881,7 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel) } blender::geometry::uv_parametrizer_stretch_end(ms->handle); - blender::geometry::uv_parametrizer_delete(ms->handle); + delete (ms->handle); for (uint ob_index = 0; ob_index < ms->objects_len; ob_index++) { Object *obedit = ms->objects_edit[ob_index]; @@ -1759,7 +1759,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) ParamHandle *handle = construct_param_handle_multi(scene, objects, objects_len, &options); blender::geometry::uv_parametrizer_average(handle, false, scale_uv, shear); blender::geometry::uv_parametrizer_flush(handle); - blender::geometry::uv_parametrizer_delete(handle); + delete (handle); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; @@ -1868,7 +1868,7 @@ void ED_uvedit_live_unwrap_end(short cancel) if (cancel) { blender::geometry::uv_parametrizer_flush_restore(g_live_unwrap.handles[i]); } - blender::geometry::uv_parametrizer_delete(g_live_unwrap.handles[i]); + delete (g_live_unwrap.handles[i]); } MEM_freeN(g_live_unwrap.handles); g_live_unwrap.handles = nullptr; @@ -2404,7 +2404,7 @@ static void uvedit_unwrap(const Scene *scene, blender::geometry::uv_parametrizer_flush(handle); - blender::geometry::uv_parametrizer_delete(handle); + delete (handle); } static void uvedit_unwrap_multi(const Scene *scene, diff --git a/source/blender/geometry/GEO_uv_parametrizer.hh b/source/blender/geometry/GEO_uv_parametrizer.hh index b3a47845b8e..61988200646 100644 --- a/source/blender/geometry/GEO_uv_parametrizer.hh +++ b/source/blender/geometry/GEO_uv_parametrizer.hh @@ -10,16 +10,57 @@ * \ingroup geo */ +struct GHash; +struct Heap; +struct MemArena; +struct RNG; + namespace blender::geometry { -class ParamHandle; /* A collection of charts. */ +struct PChart; +class PHash; + using ParamKey = uintptr_t; /* Key (hash) for identifying verts and faces. */ #define PARAM_KEY_MAX UINTPTR_MAX +enum PHandleState { + PHANDLE_STATE_ALLOCATED, + PHANDLE_STATE_CONSTRUCTED, + PHANDLE_STATE_LSCM, + PHANDLE_STATE_STRETCH, +}; + +class ParamHandle { + public: + ParamHandle(); + ~ParamHandle(); + + PHandleState state; + MemArena *arena; + MemArena *polyfill_arena; + Heap *polyfill_heap; + + PChart *construction_chart; + PHash *hash_verts; + PHash *hash_edges; + PHash *hash_faces; + + GHash *pin_hash; + int unique_pin_count; + + PChart **charts; + int ncharts; + + float aspect_y; + + RNG *rng; + float blend; +}; + /* -------------------------------------------------------------------- */ /** \name Chart Construction: * - * Faces and seams may only be added between #geometry::uv_parametrizer_construct_begin and + * Faces and seams may only be added between #ParamHandle::ParamHandle() and * #geometry::uv_parametrizer_construct_end. * * The pointers to `co` and `uv` are stored, rather than being copied. Vertices are implicitly @@ -31,8 +72,6 @@ using ParamKey = uintptr_t; /* Key (hash) for identifying verts and faces. */ * * \{ */ -ParamHandle *uv_parametrizer_construct_begin(); - void uv_parametrizer_aspect_ratio(ParamHandle *handle, float aspect_y); void uv_prepare_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]); @@ -54,7 +93,6 @@ void uv_parametrizer_construct_end(ParamHandle *handle, bool fill_holes, bool topology_from_uvs, int *r_count_failed = nullptr); -void uv_parametrizer_delete(ParamHandle *handle); /** \} */ diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index a16af0a6dc1..8a01b51971a 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -11,12 +11,9 @@ #include "BLI_array.hh" #include "BLI_convexhull_2d.h" #include "BLI_ghash.h" -#include "BLI_heap.h" -#include "BLI_memarena.h" #include "BLI_polyfill_2d.h" #include "BLI_polyfill_2d_beautify.h" #include "BLI_rand.h" -#include "BLI_vector.hh" #include "GEO_uv_pack.hh" @@ -153,37 +150,6 @@ struct PChart { bool has_pins; }; -enum PHandleState { - PHANDLE_STATE_ALLOCATED, - PHANDLE_STATE_CONSTRUCTED, - PHANDLE_STATE_LSCM, - PHANDLE_STATE_STRETCH, -}; - -class ParamHandle { - public: - enum PHandleState state; - MemArena *arena; - MemArena *polyfill_arena; - Heap *polyfill_heap; - - PChart *construction_chart; - PHash *hash_verts; - PHash *hash_edges; - PHash *hash_faces; - - GHash *pin_hash; - int unique_pin_count; - - PChart **charts; - int ncharts; - - float aspect_y; - - RNG *rng; - float blend; -}; - /* PHash * - special purpose hash that keeps all its elements in a single linked list. * - after construction, this hash is thrown away, and the list remains. @@ -216,12 +182,14 @@ static PHash *phash_new(PHashLink **list, int sizehint) return ph; } -static void phash_delete(PHash *ph) +static void phash_safe_delete(PHash **pph) { - if (ph) { - MEM_SAFE_FREE(ph->buckets); - MEM_freeN(ph); + if (!*pph) { + return; } + MEM_SAFE_FREE((*pph)->buckets); + MEM_freeN(*pph); + *pph = nullptr; } static int phash_size(PHash *ph) @@ -3643,23 +3611,58 @@ static void p_chart_rotate_fit_aabb(PChart *chart) } } -/* Exported */ - -ParamHandle *uv_parametrizer_construct_begin() +ParamHandle::ParamHandle() { - ParamHandle *handle = new ParamHandle(); - handle->construction_chart = (PChart *)MEM_callocN(sizeof(PChart), "PChart"); - handle->state = PHANDLE_STATE_ALLOCATED; - handle->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param construct arena"); - handle->polyfill_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "param polyfill arena"); - handle->polyfill_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); - handle->aspect_y = 1.0f; + state = PHANDLE_STATE_ALLOCATED; + arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), "param construct arena"); + polyfill_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "param polyfill arena"); + polyfill_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); - handle->hash_verts = phash_new((PHashLink **)&handle->construction_chart->verts, 1); - handle->hash_edges = phash_new((PHashLink **)&handle->construction_chart->edges, 1); - handle->hash_faces = phash_new((PHashLink **)&handle->construction_chart->faces, 1); + construction_chart = (PChart *)MEM_callocN(sizeof(PChart), "PChart"); - return handle; + hash_verts = phash_new((PHashLink **)&construction_chart->verts, 1); + hash_edges = phash_new((PHashLink **)&construction_chart->edges, 1); + hash_faces = phash_new((PHashLink **)&construction_chart->faces, 1); + + pin_hash = nullptr; + unique_pin_count = 0; + + charts = nullptr; + ncharts = 0; + + aspect_y = 1.0f; + + rng = nullptr; + blend = 0.0f; +} + +ParamHandle::~ParamHandle() +{ + BLI_memarena_free(arena); + arena = nullptr; + BLI_memarena_free(polyfill_arena); + polyfill_arena = nullptr; + BLI_heap_free(polyfill_heap, nullptr); + polyfill_heap = nullptr; + + MEM_SAFE_FREE(construction_chart); + + phash_safe_delete(&hash_verts); + phash_safe_delete(&hash_edges); + phash_safe_delete(&hash_faces); + + if (pin_hash) { + BLI_ghash_free(pin_hash, nullptr, nullptr); + pin_hash = nullptr; + } + + for (int i = 0; i < ncharts; i++) { + MEM_SAFE_FREE(charts[i]); + } + MEM_SAFE_FREE(charts); + + BLI_rng_free(rng); + rng = nullptr; } void uv_parametrizer_aspect_ratio(ParamHandle *phandle, const float aspect_y) @@ -3668,42 +3671,6 @@ void uv_parametrizer_aspect_ratio(ParamHandle *phandle, const float aspect_y) phandle->aspect_y = aspect_y; } -void uv_parametrizer_delete(ParamHandle *phandle) -{ - if (!phandle) { - return; - } - param_assert(ELEM(phandle->state, PHANDLE_STATE_ALLOCATED, PHANDLE_STATE_CONSTRUCTED)); - - for (int i = 0; i < phandle->ncharts; i++) { - MEM_SAFE_FREE(phandle->charts[i]); - } - - MEM_SAFE_FREE(phandle->charts); - - if (phandle->pin_hash) { - BLI_ghash_free(phandle->pin_hash, nullptr, nullptr); - phandle->pin_hash = nullptr; - } - - MEM_SAFE_FREE(phandle->construction_chart); - - phash_delete(phandle->hash_verts); - phash_delete(phandle->hash_edges); - phash_delete(phandle->hash_faces); - - BLI_memarena_free(phandle->arena); - BLI_memarena_free(phandle->polyfill_arena); - BLI_heap_free(phandle->polyfill_heap, nullptr); - - if (phandle->rng) { - BLI_rng_free(phandle->rng); - phandle->rng = nullptr; - } - - delete phandle; -} - struct GeoUVPinIndex { GeoUVPinIndex *next; float uv[2]; @@ -3950,12 +3917,9 @@ void uv_parametrizer_construct_end(ParamHandle *phandle, MEM_freeN(phandle->construction_chart); phandle->construction_chart = nullptr; - phash_delete(phandle->hash_verts); - phandle->hash_verts = nullptr; - phash_delete(phandle->hash_edges); - phandle->hash_edges = nullptr; - phash_delete(phandle->hash_faces); - phandle->hash_faces = nullptr; + phash_safe_delete(&phandle->hash_verts); + phash_safe_delete(&phandle->hash_edges); + phash_safe_delete(&phandle->hash_faces); for (i = j = 0; i < phandle->ncharts; i++) { PChart *chart = phandle->charts[i]; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index 5f21ff75e6e..86411f61a3b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -53,7 +53,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, evaluator.add_with_destination(uv_field, uv.as_mutable_span()); evaluator.evaluate(); - geometry::ParamHandle *handle = geometry::uv_parametrizer_construct_begin(); + geometry::ParamHandle *handle = new geometry::ParamHandle(); selection.foreach_index([&](const int poly_index) { const IndexRange poly = polys[poly_index]; Array mp_vkeys(poly.size()); @@ -83,7 +83,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, geometry::uv_parametrizer_pack(handle, margin, rotate, true); geometry::uv_parametrizer_flush(handle); - geometry::uv_parametrizer_delete(handle); + delete (handle); return mesh.attributes().adapt_domain( VArray::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain); diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 1b84d3915f5..c93c9a30ed4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -82,7 +82,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, Array uv(corner_verts.size(), float3(0)); - geometry::ParamHandle *handle = geometry::uv_parametrizer_construct_begin(); + geometry::ParamHandle *handle = new geometry::ParamHandle(); selection.foreach_index([&](const int poly_index) { const IndexRange poly = polys[poly_index]; Array mp_vkeys(poly.size()); @@ -125,7 +125,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, geometry::uv_parametrizer_average(handle, true, false, false); geometry::uv_parametrizer_pack(handle, margin, true, true); geometry::uv_parametrizer_flush(handle); - geometry::uv_parametrizer_delete(handle); + delete (handle); return mesh.attributes().adapt_domain( VArray::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);