Cleanup: Move UV parameterizer header to C++ and proper namespace #105357
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -152,7 +152,7 @@ static float pack_islands_margin_fraction(const Span<PackIsland *> &island_vecto
|
|||
static float calc_margin_from_aabb_length_sum(const Span<PackIsland *> &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;
|
||||
|
|
|
@ -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<int, 32> permute;
|
||||
Vector<int, 32> 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<ParamKey> vkeys_sub(pm);
|
||||
blender::Array<const float *> co_sub(pm);
|
||||
blender::Array<float *> uv_sub(pm);
|
||||
blender::Array<bool> pin_sub(pm);
|
||||
blender::Array<bool> select_sub(pm);
|
||||
Array<ParamKey> vkeys_sub(pm);
|
||||
Array<const float *> co_sub(pm);
|
||||
Array<float *> uv_sub(pm);
|
||||
Array<bool> pin_sub(pm);
|
||||
Array<bool> 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<blender::geometry::PackIsland *> pack_island_vector;
|
||||
Vector<PackIsland *> 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
|
||||
|
|
|
@ -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<float3> 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<ParamKey, 16> mp_vkeys(poly.totloop);
|
||||
Array<geometry::ParamKey, 16> mp_vkeys(poly.totloop);
|
||||
Array<bool, 16> mp_pin(poly.totloop);
|
||||
Array<bool, 16> mp_select(poly.totloop);
|
||||
Array<const float *, 16> mp_co(poly.totloop);
|
||||
|
@ -72,20 +72,20 @@ static VArray<float3> 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<float3>(
|
||||
VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);
|
||||
|
|
|
@ -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<float3> construct_uv_gvarray(const Mesh &mesh,
|
|||
|
||||
Array<float3> 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<ParamKey, 16> mp_vkeys(poly.totloop);
|
||||
Array<geometry::ParamKey, 16> mp_vkeys(poly.totloop);
|
||||
Array<bool, 16> mp_pin(poly.totloop);
|
||||
Array<bool, 16> mp_select(poly.totloop);
|
||||
Array<const float *, 16> mp_co(poly.totloop);
|
||||
|
@ -100,31 +100,32 @@ static VArray<float3> 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<float3>(
|
||||
VArray<float3>::ForContainer(std::move(uv)), ATTR_DOMAIN_CORNER, domain);
|
||||
|
|
Loading…
Reference in New Issue