Cleanup: refactoring uvislands to prepare for python api
See also: D15598
This commit is contained in:
parent
8b51bd61fd
commit
e441e21d74
|
@ -52,17 +52,24 @@ typedef struct UvElement {
|
|||
unsigned int island;
|
||||
} UvElement;
|
||||
|
||||
/* UvElementMap is a container for UvElements of a mesh. It stores some UvElements belonging to the
|
||||
* same uv island in sequence and the number of uvs per island so it is possible to access all uvs
|
||||
* belonging to an island directly by iterating through the buffer.
|
||||
/** UvElementMap is a container for UvElements of a BMesh.
|
||||
*
|
||||
* It simplifies access to UV information and ensures the
|
||||
* different UV selection modes are respected.
|
||||
*
|
||||
* If islands are calculated, it also stores UvElements
|
||||
* belonging to the same uv island in sequence and
|
||||
* the number of uvs per island.
|
||||
*/
|
||||
typedef struct UvElementMap {
|
||||
/* address UvElements by their vertex */
|
||||
struct UvElement **vert;
|
||||
/* UvElement Store */
|
||||
struct UvElement *buf;
|
||||
/* Total number of UVs in the layer. Useful to know */
|
||||
int totalUVs;
|
||||
/** Total number of UVs. */
|
||||
int total_uvs;
|
||||
/** Total number of unique UVs. */
|
||||
int total_unique_uvs;
|
||||
/* Number of Islands in the mesh */
|
||||
int totalIslands;
|
||||
/* Stores the starting index in buf where each island begins */
|
||||
|
|
|
@ -620,11 +620,11 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
|
|||
bool uv_selected,
|
||||
int cd_loop_uv_offset)
|
||||
{
|
||||
int totuv = element_map->totalUVs;
|
||||
int total_uvs = element_map->total_uvs;
|
||||
|
||||
/* For each UvElement, locate the "separate" UvElement that precedes it in the linked list. */
|
||||
UvElement **head_table = MEM_mallocN(sizeof(*head_table) * totuv, "uv_island_head_table");
|
||||
for (int i = 0; i < totuv; i++) {
|
||||
UvElement **head_table = MEM_mallocN(sizeof(*head_table) * total_uvs, "uv_island_head_table");
|
||||
for (int i = 0; i < total_uvs; i++) {
|
||||
UvElement *head = element_map->buf + i;
|
||||
if (head->separate) {
|
||||
UvElement *element = head;
|
||||
|
@ -641,11 +641,11 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
|
|||
/* Depth first search the graph, building islands as we go. */
|
||||
int nislands = 0;
|
||||
int islandbufsize = 0;
|
||||
int stack_upper_bound = totuv;
|
||||
int stack_upper_bound = total_uvs;
|
||||
UvElement **stack_uv = MEM_mallocN(sizeof(*stack_uv) * stack_upper_bound,
|
||||
"uv_island_element_stack");
|
||||
int stacksize_uv = 0;
|
||||
for (int i = 0; i < totuv; i++) {
|
||||
for (int i = 0; i < total_uvs; i++) {
|
||||
UvElement *element = element_map->buf + i;
|
||||
if (element->island != INVALID_ISLAND) {
|
||||
/* Unique UV (element and all it's children) are already part of an island. */
|
||||
|
@ -713,7 +713,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
|
|||
}
|
||||
nislands++;
|
||||
}
|
||||
BLI_assert(islandbufsize == totuv);
|
||||
BLI_assert(islandbufsize == total_uvs);
|
||||
|
||||
MEM_SAFE_FREE(stack_uv);
|
||||
MEM_SAFE_FREE(head_table);
|
||||
|
@ -778,7 +778,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
|
|||
}
|
||||
|
||||
element_map = (UvElementMap *)MEM_callocN(sizeof(*element_map), "UvElementMap");
|
||||
element_map->totalUVs = totuv;
|
||||
element_map->total_uvs = totuv;
|
||||
element_map->vert = (UvElement **)MEM_callocN(sizeof(*element_map->vert) * totverts,
|
||||
"UvElementVerts");
|
||||
buf = element_map->buf = (UvElement *)MEM_callocN(sizeof(*element_map->buf) * totuv,
|
||||
|
@ -1006,6 +1006,13 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
|
|||
|
||||
BLI_buffer_free(&tf_uv_buf);
|
||||
|
||||
element_map->total_unique_uvs = 0;
|
||||
for (int i = 0; i < element_map->total_uvs; i++) {
|
||||
if (element_map->buf[i].separate) {
|
||||
element_map->total_unique_uvs++;
|
||||
}
|
||||
}
|
||||
|
||||
return element_map;
|
||||
}
|
||||
|
||||
|
|
|
@ -414,9 +414,8 @@ static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op)
|
|||
if (data->timer) {
|
||||
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer);
|
||||
}
|
||||
if (data->elementMap) {
|
||||
BM_uv_element_map_free(data->elementMap);
|
||||
}
|
||||
BM_uv_element_map_free(data->elementMap);
|
||||
data->elementMap = NULL;
|
||||
MEM_SAFE_FREE(data->uv);
|
||||
MEM_SAFE_FREE(data->uvedges);
|
||||
if (data->initial_stroke) {
|
||||
|
@ -469,7 +468,6 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
BKE_curvemapping_init(ts->uvsculpt->paint.brush->curve);
|
||||
|
||||
if (data) {
|
||||
int counter = 0, i;
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
float co[2];
|
||||
BMFace *efa;
|
||||
|
@ -518,20 +516,24 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
|
||||
/* Count 'unique' UV's */
|
||||
for (i = 0; i < data->elementMap->totalUVs; i++) {
|
||||
if (data->elementMap->buf[i].separate &&
|
||||
(!do_island_optimization || data->elementMap->buf[i].island == island_index)) {
|
||||
counter++;
|
||||
int unique_uvs = data->elementMap->total_unique_uvs;
|
||||
if (do_island_optimization) {
|
||||
unique_uvs = 0;
|
||||
for (int i = 0; i < data->elementMap->total_uvs; i++) {
|
||||
if (data->elementMap->buf[i].separate &&
|
||||
(data->elementMap->buf[i].island == island_index)) {
|
||||
unique_uvs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate the unique uv buffers */
|
||||
data->uv = MEM_mallocN(sizeof(*data->uv) * counter, "uv_brush_unique_uvs");
|
||||
uniqueUv = MEM_mallocN(sizeof(*uniqueUv) * data->elementMap->totalUVs,
|
||||
data->uv = MEM_mallocN(sizeof(*data->uv) * unique_uvs, "uv_brush_unique_uvs");
|
||||
uniqueUv = MEM_mallocN(sizeof(*uniqueUv) * data->elementMap->total_uvs,
|
||||
"uv_brush_unique_uv_map");
|
||||
edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
|
||||
/* we have at most totalUVs edges */
|
||||
edges = MEM_mallocN(sizeof(*edges) * data->elementMap->totalUVs, "uv_brush_all_edges");
|
||||
edges = MEM_mallocN(sizeof(*edges) * data->elementMap->total_uvs, "uv_brush_all_edges");
|
||||
if (!data->uv || !uniqueUv || !edgeHash || !edges) {
|
||||
MEM_SAFE_FREE(edges);
|
||||
MEM_SAFE_FREE(uniqueUv);
|
||||
|
@ -542,11 +544,11 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
return NULL;
|
||||
}
|
||||
|
||||
data->totalUniqueUvs = counter;
|
||||
/* So that we can use this as index for the UvElements */
|
||||
counter = -1;
|
||||
data->totalUniqueUvs = unique_uvs;
|
||||
/* Index for the UvElements. */
|
||||
int counter = -1;
|
||||
/* initialize the unique UVs */
|
||||
for (i = 0; i < bm->totvert; i++) {
|
||||
for (int i = 0; i < bm->totvert; i++) {
|
||||
UvElement *element = data->elementMap->vert[i];
|
||||
for (; element; element = element->next) {
|
||||
if (element->separate) {
|
||||
|
@ -627,7 +629,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
}
|
||||
|
||||
/* fill the edges with data */
|
||||
i = 0;
|
||||
int i = 0;
|
||||
GHASH_ITER (gh_iter, edgeHash) {
|
||||
data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
|
||||
}
|
||||
|
@ -639,7 +641,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
|
||||
/* transfer boundary edge property to UV's */
|
||||
if (ts->uv_sculpt_settings & UV_SCULPT_LOCK_BORDERS) {
|
||||
for (i = 0; i < data->totalUvEdges; i++) {
|
||||
for (int i = 0; i < data->totalUvEdges; i++) {
|
||||
if (!data->uvedges[i].flag) {
|
||||
data->uv[data->uvedges[i].uv1].flag |= MARK_BOUNDARY;
|
||||
data->uv[data->uvedges[i].uv2].flag |= MARK_BOUNDARY;
|
||||
|
@ -686,7 +688,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
|
||||
counter = 0;
|
||||
|
||||
for (i = 0; i < data->totalUniqueUvs; i++) {
|
||||
for (int i = 0; i < data->totalUniqueUvs; i++) {
|
||||
float dist, diff[2];
|
||||
if (data->uv[i].flag & MARK_BOUNDARY) {
|
||||
continue;
|
||||
|
|
|
@ -543,7 +543,7 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
|
|||
bool changed = false;
|
||||
|
||||
/* Loop backwards to simplify logic. */
|
||||
int j1 = element_map->totalUVs;
|
||||
int j1 = element_map->total_uvs;
|
||||
for (int i = element_map->totalIslands - 1; i >= 0; --i) {
|
||||
int j0 = element_map->islandIndices[i];
|
||||
changed |= uvedit_uv_straighten_elements(
|
||||
|
|
|
@ -290,7 +290,7 @@ static void stitch_update_header(StitchStateContainer *ssc, bContext *C)
|
|||
static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
|
||||
{
|
||||
if (island == elementMap->totalIslands - 1) {
|
||||
return elementMap->totalUVs - elementMap->islandIndices[island];
|
||||
return elementMap->total_uvs - elementMap->islandIndices[island];
|
||||
}
|
||||
return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
|
||||
}
|
||||
|
@ -653,9 +653,8 @@ static void state_delete(StitchState *state)
|
|||
if (state->edges) {
|
||||
MEM_freeN(state->edges);
|
||||
}
|
||||
if (state->stitch_preview) {
|
||||
stitch_preview_delete(state->stitch_preview);
|
||||
}
|
||||
stitch_preview_delete(state->stitch_preview);
|
||||
state->stitch_preview = NULL;
|
||||
if (state->edge_hash) {
|
||||
BLI_ghash_free(state->edge_hash, NULL, NULL);
|
||||
}
|
||||
|
@ -1263,7 +1262,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
|
|||
if (ssc->mode == STITCH_VERT) {
|
||||
final_position = MEM_callocN(state->selection_size * sizeof(*final_position),
|
||||
"stitch_uv_average");
|
||||
uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map),
|
||||
uvfinal_map = MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map),
|
||||
"stitch_uv_final_map");
|
||||
}
|
||||
else {
|
||||
|
@ -1878,7 +1877,6 @@ static StitchState *stitch_init(bContext *C,
|
|||
int total_edges;
|
||||
/* maps uvelements to their first coincident uv */
|
||||
int *map;
|
||||
int counter = 0, i;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
|
@ -1913,37 +1911,31 @@ static StitchState *stitch_init(bContext *C,
|
|||
ED_uvedit_get_aspect(obedit, &aspx, &aspy);
|
||||
state->aspect = aspx / aspy;
|
||||
|
||||
/* Count 'unique' uvs */
|
||||
for (i = 0; i < state->element_map->totalUVs; i++) {
|
||||
if (state->element_map->buf[i].separate) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
int unique_uvs = state->element_map->total_unique_uvs;
|
||||
state->total_separate_uvs = unique_uvs;
|
||||
|
||||
/* explicitly set preview to NULL,
|
||||
* to avoid deleting an invalid pointer on stitch_process_data */
|
||||
state->stitch_preview = NULL;
|
||||
/* Allocate the unique uv buffers */
|
||||
state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs");
|
||||
state->uvs = MEM_mallocN(sizeof(*state->uvs) * unique_uvs, "uv_stitch_unique_uvs");
|
||||
/* internal uvs need no normals but it is hard and slow to keep a map of
|
||||
* normals only for boundary uvs, so allocating for all uvs */
|
||||
state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals");
|
||||
state->total_separate_uvs = counter;
|
||||
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs,
|
||||
* normals only for boundary uvs, so allocating for all uvs.
|
||||
* Times 2 because each `float[2]` is stored as `{n[2 * i], n[2*i + 1]}`. */
|
||||
state->normals = MEM_callocN(sizeof(*state->normals) * 2 * unique_uvs, "uv_stitch_normals");
|
||||
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->total_uvs,
|
||||
"uv_stitch_unique_map");
|
||||
/* Allocate the edge stack */
|
||||
edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
|
||||
all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "ssc_edges");
|
||||
all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->total_uvs, "ssc_edges");
|
||||
|
||||
BLI_assert(!state->stitch_preview); /* Paranoia. */
|
||||
if (!state->uvs || !map || !edge_hash || !all_edges) {
|
||||
state_delete(state);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* So that we can use this as index for the UvElements */
|
||||
counter = -1;
|
||||
/* Index for the UvElements. */
|
||||
int counter = -1;
|
||||
/* initialize the unique UVs and map */
|
||||
for (i = 0; i < em->bm->totvert; i++) {
|
||||
for (int i = 0; i < em->bm->totvert; i++) {
|
||||
UvElement *element = state->element_map->vert[i];
|
||||
for (; element; element = element->next) {
|
||||
if (element->separate) {
|
||||
|
@ -2012,7 +2004,7 @@ static StitchState *stitch_init(bContext *C,
|
|||
state->total_separate_edges = total_edges;
|
||||
|
||||
/* fill the edges with data */
|
||||
i = 0;
|
||||
int i = 0;
|
||||
GHASH_ITER (gh_iter, edge_hash) {
|
||||
edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue