diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index eaf812e3b2f..aae65284d8c 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -5,7 +5,7 @@ * * Utilities for manipulating UV islands. * - * \note This is similar to `GEO_uv_parametrizer.h`, + * \note This is similar to `GEO_uv_parametrizer.hh`, * however the data structures there don't support arbitrary topology * such as an edge with 3 or more faces using it. * This API uses #BMesh data structures and doesn't have limitations for manifold meshes. @@ -466,7 +466,7 @@ static bool island_has_pins(const Scene *scene, /* -------------------------------------------------------------------- */ /** \name Public UV Island Packing * - * \note This behavior loosely follows #GEO_uv_parametrizer_pack. + * \note This behavior loosely follows #geometry::uv_parametrizer_pack. * \{ */ void ED_uvedit_pack_islands_multi(const Scene *scene, diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 9f354b75bbe..33916526c3d 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -48,7 +48,7 @@ #include "DEG_depsgraph.h" #include "GEO_uv_pack.hh" -#include "GEO_uv_parametrizer.h" +#include "GEO_uv_parametrizer.hh" #include "PIL_time.h" @@ -69,6 +69,9 @@ #include "uvedit_intern.h" +using blender::geometry::ParamHandle; +using blender::geometry::ParamKey; + /* -------------------------------------------------------------------- */ /** \name Utility Functions * \{ */ @@ -335,7 +338,7 @@ static void uvedit_prepare_pinned_indices(ParamHandle *handle, if (pin) { int bmvertindex = BM_elem_index_get(l->v); const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); - GEO_uv_prepare_pin_index(handle, bmvertindex, luv); + blender::geometry::uv_prepare_pin_index(handle, bmvertindex, luv); } } } @@ -343,7 +346,7 @@ static void uvedit_prepare_pinned_indices(ParamHandle *handle, static void construct_param_handle_face_add(ParamHandle *handle, const Scene *scene, BMFace *efa, - ParamKey face_index, + blender::geometry::ParamKey face_index, const UnwrapOptions *options, const BMUVOffsets offsets) { @@ -362,7 +365,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); - vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); + vkeys[i] = blender::geometry::uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); co[i] = l->v->co; uv[i] = luv; pin[i] = BM_ELEM_CD_GET_BOOL(l, offsets.pin); @@ -372,7 +375,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, } } - GEO_uv_parametrizer_face_add( + blender::geometry::uv_parametrizer_face_add( handle, face_index, i, vkeys.data(), co.data(), uv.data(), pin.data(), select.data()); } @@ -406,11 +409,12 @@ static void construct_param_edge_set_seams(ParamHandle *handle, float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, offsets.uv); ParamKey vkeys[2]; - vkeys[0] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); - vkeys[1] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->next->v), luv_next); + vkeys[0] = blender::geometry::uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); + vkeys[1] = blender::geometry::uv_find_pin_index( + handle, BM_elem_index_get(l->next->v), luv_next); /* Set the seam. */ - GEO_uv_parametrizer_edge_set_seam(handle, vkeys); + blender::geometry::uv_parametrizer_edge_set_seam(handle, vkeys); } } } @@ -428,7 +432,7 @@ static ParamHandle *construct_param_handle(const Scene *scene, BMIter iter; int i; - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); + ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); if (options->correct_aspect) { float aspx, aspy; @@ -436,7 +440,7 @@ static ParamHandle *construct_param_handle(const Scene *scene, ED_uvedit_get_aspect(ob, &aspx, &aspy); if (aspx != aspy) { - GEO_uv_parametrizer_aspect_ratio(handle, aspx, aspy); + blender::geometry::uv_parametrizer_aspect_ratio(handle, aspx, aspy); } } @@ -458,10 +462,11 @@ static ParamHandle *construct_param_handle(const Scene *scene, construct_param_edge_set_seams(handle, bm, options); - GEO_uv_parametrizer_construct_end(handle, - options->fill_holes, - options->topology_from_uvs, - result_info ? &result_info->count_failed : nullptr); + blender::geometry::uv_parametrizer_construct_end(handle, + options->fill_holes, + options->topology_from_uvs, + result_info ? &result_info->count_failed : + nullptr); return handle; } @@ -478,7 +483,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, BMIter iter; int i; - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); + ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); if (options->correct_aspect) { Object *ob = objects[0]; @@ -486,7 +491,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, ED_uvedit_get_aspect(ob, &aspx, &aspy); if (aspx != aspy) { - GEO_uv_parametrizer_aspect_ratio(handle, aspx, aspy); + blender::geometry::uv_parametrizer_aspect_ratio(handle, aspx, aspy); } } @@ -523,7 +528,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, offset += bm->totface; } - GEO_uv_parametrizer_construct_end( + blender::geometry::uv_parametrizer_construct_end( handle, options->fill_holes, options->topology_from_uvs, nullptr); return handle; @@ -607,7 +612,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); + ParamHandle *handle = blender::geometry::uv_parametrizer_construct_begin(); if (options->correct_aspect) { float aspx, aspy; @@ -615,7 +620,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, ED_uvedit_get_aspect(ob, &aspx, &aspy); if (aspx != aspy) { - GEO_uv_parametrizer_aspect_ratio(handle, aspx, aspy); + blender::geometry::uv_parametrizer_aspect_ratio(handle, aspx, aspy); } } @@ -712,7 +717,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, texface_from_original_index( scene, offsets, origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3]); - GEO_uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select); + blender::geometry::uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select); } /* these are calculated from original mesh too */ @@ -722,14 +727,15 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, ParamKey vkeys[2]; vkeys[0] = (ParamKey)edge->v1; vkeys[1] = (ParamKey)edge->v2; - GEO_uv_parametrizer_edge_set_seam(handle, vkeys); + blender::geometry::uv_parametrizer_edge_set_seam(handle, vkeys); } } - GEO_uv_parametrizer_construct_end(handle, - options->fill_holes, - options->topology_from_uvs, - result_info ? &result_info->count_failed : nullptr); + blender::geometry::uv_parametrizer_construct_end(handle, + options->fill_holes, + options->topology_from_uvs, + result_info ? &result_info->count_failed : + nullptr); /* cleanup */ MEM_freeN(faceMap); @@ -787,9 +793,9 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) ms->handle = construct_param_handle_multi(scene, objects, objects_len, &options); ms->lasttime = PIL_check_seconds_timer(); - GEO_uv_parametrizer_stretch_begin(ms->handle); + blender::geometry::uv_parametrizer_stretch_begin(ms->handle); if (ms->blend != 0.0f) { - GEO_uv_parametrizer_stretch_blend(ms->handle, ms->blend); + blender::geometry::uv_parametrizer_stretch_blend(ms->handle, ms->blend); } op->customdata = ms; @@ -805,8 +811,8 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interac ToolSettings *ts = scene->toolsettings; const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0; - GEO_uv_parametrizer_stretch_blend(ms->handle, ms->blend); - GEO_uv_parametrizer_stretch_iter(ms->handle); + blender::geometry::uv_parametrizer_stretch_blend(ms->handle, ms->blend); + blender::geometry::uv_parametrizer_stretch_iter(ms->handle); ms->i++; RNA_int_set(op->ptr, "iterations", ms->i); @@ -814,7 +820,7 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interac if (interactive && (PIL_check_seconds_timer() - ms->lasttime > 0.5)) { char str[UI_MAX_DRAW_STR]; - GEO_uv_parametrizer_flush(ms->handle); + blender::geometry::uv_parametrizer_flush(ms->handle); if (area) { BLI_snprintf(str, sizeof(str), TIP_("Minimize Stretch. Blend %.2f"), ms->blend); @@ -854,14 +860,14 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel) } if (cancel) { - GEO_uv_parametrizer_flush_restore(ms->handle); + blender::geometry::uv_parametrizer_flush_restore(ms->handle); } else { - GEO_uv_parametrizer_flush(ms->handle); + blender::geometry::uv_parametrizer_flush(ms->handle); } - GEO_uv_parametrizer_stretch_end(ms->handle); - GEO_uv_parametrizer_delete(ms->handle); + blender::geometry::uv_parametrizer_stretch_end(ms->handle); + blender::geometry::uv_parametrizer_delete(ms->handle); for (uint ob_index = 0; ob_index < ms->objects_len; ob_index++) { Object *obedit = ms->objects_edit[ob_index]; @@ -1175,9 +1181,9 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) const bool shear = RNA_boolean_get(op->ptr, "shear"); ParamHandle *handle = construct_param_handle_multi(scene, objects, objects_len, &options); - GEO_uv_parametrizer_average(handle, false, scale_uv, shear); - GEO_uv_parametrizer_flush(handle); - GEO_uv_parametrizer_delete(handle); + blender::geometry::uv_parametrizer_average(handle, false, scale_uv, shear); + blender::geometry::uv_parametrizer_flush(handle); + blender::geometry::uv_parametrizer_delete(handle); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; @@ -1250,7 +1256,7 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) handle = construct_param_handle(scene, obedit, em->bm, &options, nullptr); } - GEO_uv_parametrizer_lscm_begin(handle, true, abf); + blender::geometry::uv_parametrizer_lscm_begin(handle, true, abf); /* Create or increase size of g_live_unwrap.handles array */ if (g_live_unwrap.handles == nullptr) { @@ -1272,8 +1278,8 @@ void ED_uvedit_live_unwrap_re_solve(void) { if (g_live_unwrap.handles) { for (int i = 0; i < g_live_unwrap.len; i++) { - GEO_uv_parametrizer_lscm_solve(g_live_unwrap.handles[i], nullptr, nullptr); - GEO_uv_parametrizer_flush(g_live_unwrap.handles[i]); + blender::geometry::uv_parametrizer_lscm_solve(g_live_unwrap.handles[i], nullptr, nullptr); + blender::geometry::uv_parametrizer_flush(g_live_unwrap.handles[i]); } } } @@ -1282,11 +1288,11 @@ void ED_uvedit_live_unwrap_end(short cancel) { if (g_live_unwrap.handles) { for (int i = 0; i < g_live_unwrap.len; i++) { - GEO_uv_parametrizer_lscm_end(g_live_unwrap.handles[i]); + blender::geometry::uv_parametrizer_lscm_end(g_live_unwrap.handles[i]); if (cancel) { - GEO_uv_parametrizer_flush_restore(g_live_unwrap.handles[i]); + blender::geometry::uv_parametrizer_flush_restore(g_live_unwrap.handles[i]); } - GEO_uv_parametrizer_delete(g_live_unwrap.handles[i]); + blender::geometry::uv_parametrizer_delete(g_live_unwrap.handles[i]); } MEM_freeN(g_live_unwrap.handles); g_live_unwrap.handles = nullptr; @@ -1807,17 +1813,19 @@ static void uvedit_unwrap(const Scene *scene, handle = construct_param_handle(scene, obedit, em->bm, options, result_info); } - GEO_uv_parametrizer_lscm_begin(handle, false, scene->toolsettings->unwrapper == 0); - GEO_uv_parametrizer_lscm_solve(handle, - result_info ? &result_info->count_changed : nullptr, - result_info ? &result_info->count_failed : nullptr); - GEO_uv_parametrizer_lscm_end(handle); + blender::geometry::uv_parametrizer_lscm_begin( + handle, false, scene->toolsettings->unwrapper == 0); + blender::geometry::uv_parametrizer_lscm_solve( + handle, + result_info ? &result_info->count_changed : nullptr, + result_info ? &result_info->count_failed : nullptr); + blender::geometry::uv_parametrizer_lscm_end(handle); - GEO_uv_parametrizer_average(handle, true, false, false); + blender::geometry::uv_parametrizer_average(handle, true, false, false); - GEO_uv_parametrizer_flush(handle); + blender::geometry::uv_parametrizer_flush(handle); - GEO_uv_parametrizer_delete(handle); + blender::geometry::uv_parametrizer_delete(handle); } static void uvedit_unwrap_multi(const Scene *scene, diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt index c0bb0f04f10..9b8d66232eb 100644 --- a/source/blender/geometry/CMakeLists.txt +++ b/source/blender/geometry/CMakeLists.txt @@ -49,7 +49,7 @@ set(SRC GEO_subdivide_curves.hh GEO_trim_curves.hh GEO_uv_pack.hh - GEO_uv_parametrizer.h + GEO_uv_parametrizer.hh ) set(LIB diff --git a/source/blender/geometry/GEO_uv_parametrizer.h b/source/blender/geometry/GEO_uv_parametrizer.h deleted file mode 100644 index ff110f18ffb..00000000000 --- a/source/blender/geometry/GEO_uv_parametrizer.h +++ /dev/null @@ -1,132 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include "BLI_sys_types.h" /* for intptr_t support */ - -/** \file - * \ingroup geo - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ParamHandle ParamHandle; /* Handle to an array of charts. */ -typedef uintptr_t ParamKey; /* Key (hash) for identifying verts and faces. */ -#define PARAM_KEY_MAX UINTPTR_MAX - -/* -------------------------------------------------------------------- */ -/** \name Chart Construction: - * - * Faces and seams may only be added between #GEO_uv_parametrizer_construct_begin and - * #GEO_uv_parametrizer_construct_end. - * - * The pointers to `co` and `uv` are stored, rather than being copied. Vertices are implicitly - * created. - * - * In #GEO_uv_parametrizer_construct_end the mesh will be split up according to the seams. The - * resulting charts must be manifold, connected and open (at least one boundary loop). The output - * will be written to the `uv` pointers. - * - * \{ */ - -ParamHandle *GEO_uv_parametrizer_construct_begin(void); - -void GEO_uv_parametrizer_aspect_ratio(ParamHandle *handle, float aspx, float aspy); - -void GEO_uv_prepare_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]); - -ParamKey GEO_uv_find_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]); - -void GEO_uv_parametrizer_face_add(ParamHandle *handle, - const ParamKey key, - const int nverts, - const ParamKey *vkeys, - const float **co, - float **uv, /* Output will eventually be written to `uv`. */ - const bool *pin, - const bool *select); - -void GEO_uv_parametrizer_edge_set_seam(ParamHandle *handle, ParamKey *vkeys); - -void GEO_uv_parametrizer_construct_end(ParamHandle *handle, - bool fill, - bool topology_from_uvs, - int *count_fail); -void GEO_uv_parametrizer_delete(ParamHandle *handle); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Least Squares Conformal Maps: - * - * Charts with less than two pinned vertices are assigned two pins. LSCM is divided to three steps: - * - * 1. Begin: compute matrix and its factorization (expensive). - * 2. Solve using pinned coordinates (cheap). - * 3. End: clean up. - * - * UV coordinates are allowed to change within begin/end, for quick re-solving. - * - * \{ */ - -void GEO_uv_parametrizer_lscm_begin(ParamHandle *handle, bool live, bool abf); -void GEO_uv_parametrizer_lscm_solve(ParamHandle *handle, int *count_changed, int *count_failed); -void GEO_uv_parametrizer_lscm_end(ParamHandle *handle); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Stretch - * \{ */ - -void GEO_uv_parametrizer_stretch_begin(ParamHandle *handle); -void GEO_uv_parametrizer_stretch_blend(ParamHandle *handle, float blend); -void GEO_uv_parametrizer_stretch_iter(ParamHandle *handle); -void GEO_uv_parametrizer_stretch_end(ParamHandle *handle); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Packing - * \{ */ - -void GEO_uv_parametrizer_pack(ParamHandle *handle, - float margin, - bool do_rotate, - bool ignore_pinned); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Average area for all charts - * \{ */ - -void GEO_uv_parametrizer_average(ParamHandle *handle, - bool ignore_pinned, - bool scale_uv, - bool shear); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Simple x,y scale - * \{ */ - -void GEO_uv_parametrizer_scale(ParamHandle *handle, float x, float y); - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Flushing - * \{ */ - -void GEO_uv_parametrizer_flush(ParamHandle *handle); -void GEO_uv_parametrizer_flush_restore(ParamHandle *handle); - -/** \} */ - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/geometry/GEO_uv_parametrizer.hh b/source/blender/geometry/GEO_uv_parametrizer.hh new file mode 100644 index 00000000000..58345f427cb --- /dev/null +++ b/source/blender/geometry/GEO_uv_parametrizer.hh @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_sys_types.h" /* for intptr_t support */ + +/** \file + * \ingroup geo + */ + +namespace blender::geometry { + +struct ParamHandle; /* Handle to an array of charts. */ +using ParamKey = uintptr_t; /* Key (hash) for identifying verts and faces. */ +#define PARAM_KEY_MAX UINTPTR_MAX + +/* -------------------------------------------------------------------- */ +/** \name Chart Construction: + * + * Faces and seams may only be added between #geometry::uv_parametrizer_construct_begin and + * #geometry::uv_parametrizer_construct_end. + * + * The pointers to `co` and `uv` are stored, rather than being copied. Vertices are implicitly + * created. + * + * In #geometry::uv_parametrizer_construct_end the mesh will be split up according to the seams. + * The resulting charts must be manifold, connected and open (at least one boundary loop). The + * output will be written to the `uv` pointers. + * + * \{ */ + +ParamHandle *uv_parametrizer_construct_begin(); + +void uv_parametrizer_aspect_ratio(ParamHandle *handle, float aspx, float aspy); + +void uv_prepare_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]); + +ParamKey uv_find_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]); + +void uv_parametrizer_face_add(ParamHandle *handle, + const ParamKey key, + const int nverts, + const ParamKey *vkeys, + const float **co, + float **uv, /* Output will eventually be written to `uv`. */ + const bool *pin, + const bool *select); + +void uv_parametrizer_edge_set_seam(ParamHandle *handle, ParamKey *vkeys); + +void uv_parametrizer_construct_end(ParamHandle *handle, + bool fill, + bool topology_from_uvs, + int *count_fail); +void uv_parametrizer_delete(ParamHandle *handle); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Least Squares Conformal Maps: + * + * Charts with less than two pinned vertices are assigned two pins. LSCM is divided to three steps: + * + * 1. Begin: compute matrix and its factorization (expensive). + * 2. Solve using pinned coordinates (cheap). + * 3. End: clean up. + * + * UV coordinates are allowed to change within begin/end, for quick re-solving. + * + * \{ */ + +void uv_parametrizer_lscm_begin(ParamHandle *handle, bool live, bool abf); +void uv_parametrizer_lscm_solve(ParamHandle *handle, int *count_changed, int *count_failed); +void uv_parametrizer_lscm_end(ParamHandle *handle); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Stretch + * \{ */ + +void uv_parametrizer_stretch_begin(ParamHandle *handle); +void uv_parametrizer_stretch_blend(ParamHandle *handle, float blend); +void uv_parametrizer_stretch_iter(ParamHandle *handle); +void uv_parametrizer_stretch_end(ParamHandle *handle); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Packing + * \{ */ + +void uv_parametrizer_pack(ParamHandle *handle, float margin, bool do_rotate, bool ignore_pinned); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Average area for all charts + * \{ */ + +void uv_parametrizer_average(ParamHandle *handle, bool ignore_pinned, bool scale_uv, bool shear); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Simple x,y scale + * \{ */ + +void uv_parametrizer_scale(ParamHandle *handle, float x, float y); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Flushing + * \{ */ + +void uv_parametrizer_flush(ParamHandle *handle); +void uv_parametrizer_flush_restore(ParamHandle *handle); + +/** \} */ + +} // namespace blender::geometry diff --git a/source/blender/geometry/intern/uv_pack.cc b/source/blender/geometry/intern/uv_pack.cc index b8434b7b224..725e9dc8440 100644 --- a/source/blender/geometry/intern/uv_pack.cc +++ b/source/blender/geometry/intern/uv_pack.cc @@ -152,7 +152,7 @@ static float pack_islands_margin_fraction(const Span &island_vecto static float calc_margin_from_aabb_length_sum(const Span &island_vector, const UVPackIsland_Params ¶ms) { - /* Logic matches behavior from #GEO_uv_parametrizer_pack. + /* Logic matches behavior from #geometry::uv_parametrizer_pack. * Attempt to give predictable results not dependent on current UV scale by using * `aabb_length_sum` (was "`area`") to multiply the margin by the length (was "area"). */ double aabb_length_sum = 0.0f; diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index ee87df645c5..cf39fe1f422 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -4,7 +4,7 @@ * \ingroup eduv */ -#include "GEO_uv_parametrizer.h" +#include "GEO_uv_parametrizer.hh" #include "BLI_array.hh" #include "BLI_convexhull_2d.h" @@ -22,6 +22,8 @@ /* Utils */ +namespace blender::geometry { + #define param_assert(condition) \ if (!(condition)) { /* `printf("Assertion %s:%d\n", __FILE__, __LINE__); abort();` */ \ } \ @@ -31,18 +33,18 @@ /* Special Purpose Hash */ -typedef uintptr_t PHashKey; +using PHashKey = uintptr_t; -typedef struct PHashLink { +struct PHashLink { struct PHashLink *next; PHashKey key; -} PHashLink; +}; -typedef struct PHash { +struct PHash { PHashLink **list; PHashLink **buckets; int size, cursize, cursize_id; -} PHash; +}; /* Simplices */ @@ -170,7 +172,7 @@ struct ParamHandle { PHash *hash_edges; PHash *hash_faces; - struct GHash *pin_hash; + GHash *pin_hash; int unique_pin_count; PChart **charts; @@ -1188,7 +1190,7 @@ static void p_chart_fill_boundary(ParamHandle *handle, PChart *chart, PEdge *be, PEdge *e, *e1, *e2; PFace *f; - struct Heap *heap = BLI_heap_new(); + Heap *heap = BLI_heap_new(); float angle; e = be; @@ -2263,7 +2265,7 @@ static void p_chart_simplify(PChart *chart) #define ABF_MAX_ITER 20 -using PAbfSystem = struct PAbfSystem { +struct PAbfSystem { int ninterior, nfaces, nangles; float *alpha, *beta, *sine, *cosine, *weight; float *bAlpha, *bTriangle, *bInterior; @@ -3654,7 +3656,7 @@ static void p_chart_rotate_fit_aabb(PChart *chart) /* Exported */ -ParamHandle *GEO_uv_parametrizer_construct_begin() +ParamHandle *uv_parametrizer_construct_begin() { ParamHandle *handle = new ParamHandle(); handle->construction_chart = (PChart *)MEM_callocN(sizeof(PChart), "PChart"); @@ -3672,13 +3674,13 @@ ParamHandle *GEO_uv_parametrizer_construct_begin() return handle; } -void GEO_uv_parametrizer_aspect_ratio(ParamHandle *phandle, float aspx, float aspy) +void uv_parametrizer_aspect_ratio(ParamHandle *phandle, float aspx, float aspy) { phandle->aspx = aspx; phandle->aspy = aspy; } -void GEO_uv_parametrizer_delete(ParamHandle *phandle) +void uv_parametrizer_delete(ParamHandle *phandle) { if (!phandle) { return; @@ -3714,7 +3716,7 @@ void GEO_uv_parametrizer_delete(ParamHandle *phandle) delete phandle; } -using GeoUVPinIndex = struct GeoUVPinIndex { +struct GeoUVPinIndex { struct GeoUVPinIndex *next; float uv[2]; ParamKey reindex; @@ -3729,7 +3731,7 @@ using GeoUVPinIndex = struct GeoUVPinIndex { * For everything else, just return the #BMVert index. * Note that #ParamKeys will eventually be hashed, so they don't need to be contiguous. */ -ParamKey GEO_uv_find_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]) +ParamKey uv_find_pin_index(ParamHandle *handle, const int bmvertindex, const float uv[2]) { if (!handle->pin_hash) { return bmvertindex; /* No verts pinned. */ @@ -3765,7 +3767,7 @@ static GeoUVPinIndex *new_geo_uv_pinindex(ParamHandle *handle, const float uv[2] return pinuv; } -void GEO_uv_prepare_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]) { if (!handle->pin_hash) { handle->pin_hash = BLI_ghash_int_new("uv pin reindex"); @@ -3848,20 +3850,20 @@ static void p_add_ngon(ParamHandle *handle, bool tri_pin[3] = {pin[v0], pin[v1], pin[v2]}; bool tri_select[3] = {select[v0], select[v1], select[v2]}; - GEO_uv_parametrizer_face_add(handle, key, 3, tri_vkeys, tri_co, tri_uv, tri_pin, tri_select); + uv_parametrizer_face_add(handle, key, 3, tri_vkeys, tri_co, tri_uv, tri_pin, tri_select); } BLI_memarena_clear(arena); } -void GEO_uv_parametrizer_face_add(ParamHandle *phandle, - const ParamKey key, - const int nverts, - const ParamKey *vkeys, - const float **co, - float **uv, - const bool *pin, - const bool *select) +void uv_parametrizer_face_add(ParamHandle *phandle, + const ParamKey key, + const int nverts, + const ParamKey *vkeys, + const float **co, + float **uv, + const bool *pin, + const bool *select) { BLI_assert(nverts >= 3); param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); @@ -3870,7 +3872,7 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, /* Protect against (manifold) geometry which has a non-manifold triangulation. * See #102543. */ - blender::Vector permute; + Vector permute; permute.reserve(nverts); for (int i = 0; i < nverts; i++) { permute.append_unchecked(i); @@ -3894,7 +3896,7 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, /* An existing triangle has already been inserted. * As a heuristic, attempt to add the *previous* triangle. - * NOTE: Should probably call `GEO_uv_parametrizer_face_add` + * NOTE: Should probably call `uv_parametrizer_face_add` * instead of `p_face_add_construct`. */ int iprev = permute[(i + pm - 1) % pm]; p_face_add_construct(phandle, key, vkeys, co, uv, iprev, i0, i1, pin, select); @@ -3907,11 +3909,11 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, if (permute.size() != nverts) { int pm = permute.size(); /* Add the remaining pm-gon. */ - blender::Array vkeys_sub(pm); - blender::Array co_sub(pm); - blender::Array uv_sub(pm); - blender::Array pin_sub(pm); - blender::Array select_sub(pm); + Array vkeys_sub(pm); + Array co_sub(pm); + Array uv_sub(pm); + Array pin_sub(pm); + Array select_sub(pm); for (int i = 0; i < pm; i++) { int j = permute[i]; vkeys_sub[i] = vkeys[j]; @@ -3942,7 +3944,7 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, } } -void GEO_uv_parametrizer_edge_set_seam(ParamHandle *phandle, ParamKey *vkeys) +void uv_parametrizer_edge_set_seam(ParamHandle *phandle, ParamKey *vkeys) { PEdge *e; @@ -3954,10 +3956,10 @@ void GEO_uv_parametrizer_edge_set_seam(ParamHandle *phandle, ParamKey *vkeys) } } -void GEO_uv_parametrizer_construct_end(ParamHandle *phandle, - bool fill, - bool topology_from_uvs, - int *count_fail) +void uv_parametrizer_construct_end(ParamHandle *phandle, + bool fill, + bool topology_from_uvs, + int *count_fail) { PChart *chart = phandle->construction_chart; int i, j; @@ -4007,7 +4009,7 @@ void GEO_uv_parametrizer_construct_end(ParamHandle *phandle, phandle->state = PHANDLE_STATE_CONSTRUCTED; } -void GEO_uv_parametrizer_lscm_begin(ParamHandle *phandle, bool live, bool abf) +void uv_parametrizer_lscm_begin(ParamHandle *phandle, bool live, bool abf) { param_assert(phandle->state == PHANDLE_STATE_CONSTRUCTED); phandle->state = PHANDLE_STATE_LSCM; @@ -4020,7 +4022,7 @@ void GEO_uv_parametrizer_lscm_begin(ParamHandle *phandle, bool live, bool abf) } } -void GEO_uv_parametrizer_lscm_solve(ParamHandle *phandle, int *count_changed, int *count_failed) +void uv_parametrizer_lscm_solve(ParamHandle *phandle, int *count_changed, int *count_failed) { param_assert(phandle->state == PHANDLE_STATE_LSCM); @@ -4056,7 +4058,7 @@ void GEO_uv_parametrizer_lscm_solve(ParamHandle *phandle, int *count_changed, in } } -void GEO_uv_parametrizer_lscm_end(ParamHandle *phandle) +void uv_parametrizer_lscm_end(ParamHandle *phandle) { BLI_assert(phandle->state == PHANDLE_STATE_LSCM); @@ -4070,7 +4072,7 @@ void GEO_uv_parametrizer_lscm_end(ParamHandle *phandle) phandle->state = PHANDLE_STATE_CONSTRUCTED; } -void GEO_uv_parametrizer_stretch_begin(ParamHandle *phandle) +void uv_parametrizer_stretch_begin(ParamHandle *phandle) { PChart *chart; PVert *v; @@ -4099,13 +4101,13 @@ void GEO_uv_parametrizer_stretch_begin(ParamHandle *phandle) } } -void GEO_uv_parametrizer_stretch_blend(ParamHandle *phandle, float blend) +void uv_parametrizer_stretch_blend(ParamHandle *phandle, float blend) { param_assert(phandle->state == PHANDLE_STATE_STRETCH); phandle->blend = blend; } -void GEO_uv_parametrizer_stretch_iter(ParamHandle *phandle) +void uv_parametrizer_stretch_iter(ParamHandle *phandle) { PChart *chart; int i; @@ -4118,7 +4120,7 @@ void GEO_uv_parametrizer_stretch_iter(ParamHandle *phandle) } } -void GEO_uv_parametrizer_stretch_end(ParamHandle *phandle) +void uv_parametrizer_stretch_end(ParamHandle *phandle) { param_assert(phandle->state == PHANDLE_STATE_STRETCH); phandle->state = PHANDLE_STATE_CONSTRUCTED; @@ -4141,10 +4143,7 @@ static void GEO_uv_parametrizer_pack_rotate(ParamHandle *phandle, bool ignore_pi } } -void GEO_uv_parametrizer_pack(ParamHandle *handle, - float margin, - bool do_rotate, - bool ignore_pinned) +void uv_parametrizer_pack(ParamHandle *handle, float margin, bool do_rotate, bool ignore_pinned) { if (handle->ncharts == 0) { return; @@ -4156,9 +4155,9 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle, } if (handle->aspx != handle->aspy) { - GEO_uv_parametrizer_scale(handle, 1.0f / handle->aspx, 1.0f / handle->aspy); + uv_parametrizer_scale(handle, 1.0f / handle->aspx, 1.0f / handle->aspy); } - blender::Vector pack_island_vector; + Vector pack_island_vector; int unpacked = 0; for (int i = 0; i < handle->ncharts; i++) { PChart *chart = handle->charts[i]; @@ -4168,7 +4167,7 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle, continue; } - blender::geometry::PackIsland *pack_island = new blender::geometry::PackIsland(); + geometry::PackIsland *pack_island = new geometry::PackIsland(); pack_island_vector.append(pack_island); float minv[2]; @@ -4198,7 +4197,7 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle, for (int64_t i : pack_island_vector.index_range()) { BoxPack *box = box_array + i; - blender::geometry::PackIsland *pack_island = pack_island_vector[box->index]; + PackIsland *pack_island = pack_island_vector[box->index]; pack_island->bounds_rect.xmin = box->x; pack_island->bounds_rect.ymin = box->y; pack_island->bounds_rect.xmax = box->x + box->w; @@ -4213,7 +4212,7 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle, unpacked++; continue; } - blender::geometry::PackIsland *pack_island = pack_island_vector[i - unpacked]; + PackIsland *pack_island = pack_island_vector[i - unpacked]; float minv[2]; float maxv[2]; @@ -4237,14 +4236,11 @@ void GEO_uv_parametrizer_pack(ParamHandle *handle, } MEM_freeN(box_array); if (handle->aspx != handle->aspy) { - GEO_uv_parametrizer_scale(handle, handle->aspx, handle->aspy); + uv_parametrizer_scale(handle, handle->aspx, handle->aspy); } } -void GEO_uv_parametrizer_average(ParamHandle *phandle, - bool ignore_pinned, - bool scale_uv, - bool shear) +void uv_parametrizer_average(ParamHandle *phandle, bool ignore_pinned, bool scale_uv, bool shear) { int i; float tot_area_3d = 0.0f; @@ -4384,7 +4380,7 @@ void GEO_uv_parametrizer_average(ParamHandle *phandle, } } -void GEO_uv_parametrizer_scale(ParamHandle *phandle, float x, float y) +void uv_parametrizer_scale(ParamHandle *phandle, float x, float y) { PChart *chart; int i; @@ -4395,7 +4391,7 @@ void GEO_uv_parametrizer_scale(ParamHandle *phandle, float x, float y) } } -void GEO_uv_parametrizer_flush(ParamHandle *phandle) +void uv_parametrizer_flush(ParamHandle *phandle) { PChart *chart; int i; @@ -4411,7 +4407,7 @@ void GEO_uv_parametrizer_flush(ParamHandle *phandle) } } -void GEO_uv_parametrizer_flush_restore(ParamHandle *phandle) +void uv_parametrizer_flush_restore(ParamHandle *phandle) { PChart *chart; PFace *f; @@ -4425,3 +4421,5 @@ void GEO_uv_parametrizer_flush_restore(ParamHandle *phandle) } } } + +} // namespace blender::geometry 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 bff3c5761ea..6b6b0209e82 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 @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "GEO_uv_parametrizer.h" +#include "GEO_uv_parametrizer.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -56,10 +56,10 @@ static VArray construct_uv_gvarray(const Mesh &mesh, evaluator.add_with_destination(uv_field, uv.as_mutable_span()); evaluator.evaluate(); - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); + geometry::ParamHandle *handle = geometry::uv_parametrizer_construct_begin(); for (const int poly_index : selection) { const MPoly &poly = polys[poly_index]; - Array mp_vkeys(poly.totloop); + Array mp_vkeys(poly.totloop); Array mp_pin(poly.totloop); Array mp_select(poly.totloop); Array mp_co(poly.totloop); @@ -72,20 +72,20 @@ static VArray construct_uv_gvarray(const Mesh &mesh, mp_pin[i] = false; mp_select[i] = false; } - GEO_uv_parametrizer_face_add(handle, - poly_index, - poly.totloop, - mp_vkeys.data(), - mp_co.data(), - mp_uv.data(), - mp_pin.data(), - mp_select.data()); + geometry::uv_parametrizer_face_add(handle, + poly_index, + poly.totloop, + mp_vkeys.data(), + mp_co.data(), + mp_uv.data(), + mp_pin.data(), + mp_select.data()); } - GEO_uv_parametrizer_construct_end(handle, true, true, nullptr); + geometry::uv_parametrizer_construct_end(handle, true, true, nullptr); - GEO_uv_parametrizer_pack(handle, margin, rotate, true); - GEO_uv_parametrizer_flush(handle); - GEO_uv_parametrizer_delete(handle); + geometry::uv_parametrizer_pack(handle, margin, rotate, true); + geometry::uv_parametrizer_flush(handle); + geometry::uv_parametrizer_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 ae289979b77..4e27ce15f47 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "GEO_uv_parametrizer.h" +#include "GEO_uv_parametrizer.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -84,10 +84,10 @@ static VArray construct_uv_gvarray(const Mesh &mesh, Array uv(loops.size(), float3(0)); - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); + geometry::ParamHandle *handle = geometry::uv_parametrizer_construct_begin(); for (const int poly_index : selection) { const MPoly &poly = polys[poly_index]; - Array mp_vkeys(poly.totloop); + Array mp_vkeys(poly.totloop); Array mp_pin(poly.totloop); Array mp_select(poly.totloop); Array mp_co(poly.totloop); @@ -100,31 +100,32 @@ static VArray construct_uv_gvarray(const Mesh &mesh, mp_pin[i] = false; mp_select[i] = false; } - GEO_uv_parametrizer_face_add(handle, - poly_index, - poly.totloop, - mp_vkeys.data(), - mp_co.data(), - mp_uv.data(), - mp_pin.data(), - mp_select.data()); + geometry::uv_parametrizer_face_add(handle, + poly_index, + poly.totloop, + mp_vkeys.data(), + mp_co.data(), + mp_uv.data(), + mp_pin.data(), + mp_select.data()); } for (const int i : seam) { const MEdge &edge = edges[i]; - ParamKey vkeys[2]{edge.v1, edge.v2}; - GEO_uv_parametrizer_edge_set_seam(handle, vkeys); + geometry::ParamKey vkeys[2]{edge.v1, edge.v2}; + geometry::uv_parametrizer_edge_set_seam(handle, vkeys); } /* TODO: once field input nodes are able to emit warnings (#94039), emit a * warning if we fail to solve an island. */ - GEO_uv_parametrizer_construct_end(handle, fill_holes, false, nullptr); + geometry::uv_parametrizer_construct_end(handle, fill_holes, false, nullptr); - GEO_uv_parametrizer_lscm_begin(handle, false, method == GEO_NODE_UV_UNWRAP_METHOD_ANGLE_BASED); - GEO_uv_parametrizer_lscm_solve(handle, nullptr, nullptr); - GEO_uv_parametrizer_lscm_end(handle); - GEO_uv_parametrizer_average(handle, true, false, false); - GEO_uv_parametrizer_pack(handle, margin, true, true); - GEO_uv_parametrizer_flush(handle); - GEO_uv_parametrizer_delete(handle); + geometry::uv_parametrizer_lscm_begin( + handle, false, method == GEO_NODE_UV_UNWRAP_METHOD_ANGLE_BASED); + geometry::uv_parametrizer_lscm_solve(handle, nullptr, nullptr); + geometry::uv_parametrizer_lscm_end(handle); + 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); return mesh.attributes().adapt_domain( VArray::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);