Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2012-02-22 04:06:15 +0400
committerAntony Riakiotakis <kalast@gmail.com>2012-02-22 04:06:15 +0400
commitc7185d26527ef1ef56e0fe54cdef0d54578ae1b1 (patch)
tree7405af4365ea9aebb8f70e0776cf857331af499c /source/blender/editors
parenta4e69673233e2506075ff43e3cdb09652fd66236 (diff)
Stitch tool fully functional again. Many thanks to Howard Trickey for proposing the loop winding criterion for normal disambiguation of edges. Unfortunately some extra memory has to be allocated for this to work correctly. If the tool had been initially written for bmesh I would have used the already present adjacency information to make it work, avoiding some extra allocations. Maybe a project for another day though, when I am more proficient with bmesh internals.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/mesh/bmesh_utils.c6
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c19
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h13
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c141
4 files changed, 84 insertions, 95 deletions
diff --git a/source/blender/editors/mesh/bmesh_utils.c b/source/blender/editors/mesh/bmesh_utils.c
index dc8073da8c1..c9ead44e34d 100644
--- a/source/blender/editors/mesh/bmesh_utils.c
+++ b/source/blender/editors/mesh/bmesh_utils.c
@@ -769,18 +769,17 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
island_number[j++] = INVALID_ISLAND;
if (!selected || ((!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) && BM_elem_flag_test(efa, BM_ELEM_SELECT))) {
- i = 0;
- BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+ BM_ITER_INDEX(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa, i) {
buf->l = l;
buf->face = efa;
buf->separate = 0;
buf->island = INVALID_ISLAND;
+ buf->tfindex = i;
buf->next = element_map->vert[BM_elem_index_get(l->v)];
element_map->vert[BM_elem_index_get(l->v)] = buf;
buf++;
- i++;
}
}
}
@@ -865,6 +864,7 @@ UvElementMap *EDBM_make_uv_element_map(BMEditMesh *em, int selected, int do_isla
islandbuf[islandbufsize].l = element->l;
islandbuf[islandbufsize].face = element->face;
islandbuf[islandbufsize].separate = element->separate;
+ islandbuf[islandbufsize].tfindex = element->tfindex;
islandbuf[islandbufsize].island = nislands;
islandbufsize++;
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 8de03f330d9..ef09ec3c3e8 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -877,6 +877,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
/* finally draw stitch preview */
if(stitch_preview) {
+ int i, index = 0;
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
@@ -887,13 +888,17 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris*3);
- glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_tris);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
- glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3);
+ glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
+ for(i = 0; i < stitch_preview->num_polys; i++){
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
+ glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
+
+ index += stitch_preview->uvs_per_polygon[i];
+ }
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
/*UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris*3);*/
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 55a7bf63410..4ac68ae5a18 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -89,17 +89,18 @@ void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, str
/* object that stores display data for previewing before accepting stitching */
typedef struct StitchPreviewer {
/* here we'll store the preview triangle indices of the mesh */
- unsigned int *preview_tris;
- /* here we store the actual uv vertices to display */
- float *preview_coords;
+ float *preview_polys;
+ /* uvs per polygon. */
+ unsigned int *uvs_per_polygon;
+ /*number of preview polygons */
+ unsigned int num_polys;
/* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */
float *preview_stitchable;
float *preview_unstitchable;
- /* here we'll store the number of triangles and quads to be drawn */
- unsigned int num_tris;
+ /* here we'll store the number of elements to be drawn */
unsigned int num_stitchable;
unsigned int num_unstitchable;
-
+ unsigned int preview_uvs;
/* ...and here we'll store the triangles*/
float *static_tris;
unsigned int num_static_tris;
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 4c7bb639d57..c3c19b683e1 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -143,7 +143,10 @@ typedef struct StitchState {
unsigned int *tris_per_island;
} StitchState;
-
+typedef struct PreviewPosition{
+ int data_position;
+ int polycount_position;
+}PreviewPosition;
/*
* defines for UvElement flags
*/
@@ -162,12 +165,13 @@ static StitchPreviewer *_stitch_preview;
static StitchPreviewer * stitch_preview_init(void)
{
_stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
- _stitch_preview->preview_tris = NULL;
- _stitch_preview->preview_coords = NULL;
+ _stitch_preview->preview_polys = NULL;
_stitch_preview->preview_stitchable = NULL;
_stitch_preview->preview_unstitchable = NULL;
+ _stitch_preview->uvs_per_polygon = NULL;
- _stitch_preview->num_tris = 0;
+ _stitch_preview->preview_uvs = 0;
+ _stitch_preview->num_polys = 0;
_stitch_preview->num_stitchable = 0;
_stitch_preview->num_unstitchable = 0;
@@ -183,9 +187,13 @@ static void stitch_preview_delete(void)
{
if(_stitch_preview)
{
- if(_stitch_preview->preview_tris){
- MEM_freeN(_stitch_preview->preview_tris);
- _stitch_preview->preview_tris = NULL;
+ if(_stitch_preview->preview_polys){
+ MEM_freeN(_stitch_preview->preview_polys);
+ _stitch_preview->preview_polys = NULL;
+ }
+ if(_stitch_preview->uvs_per_polygon){
+ MEM_freeN(_stitch_preview->uvs_per_polygon);
+ _stitch_preview->uvs_per_polygon = NULL;
}
if(_stitch_preview->preview_stitchable){
MEM_freeN(_stitch_preview->preview_stitchable);
@@ -199,10 +207,6 @@ static void stitch_preview_delete(void)
MEM_freeN(_stitch_preview->static_tris);
_stitch_preview->static_tris = NULL;
}
- if(_stitch_preview->preview_coords){
- MEM_freeN(_stitch_preview->preview_coords);
- _stitch_preview->preview_coords = NULL;
- }
MEM_freeN(_stitch_preview);
_stitch_preview = NULL;
@@ -299,7 +303,7 @@ static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *elem
/* calculate snapping for islands */
-static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
+static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
int i;
UvElement *element;
@@ -330,18 +334,17 @@ static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer
stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv);
- luv->uv[0] += island_stitch_data[i].translation[0];
- luv->uv[1] += island_stitch_data[i].translation[1];
+ add_v2_v2(luv->uv, island_stitch_data[i].translation);
}
- else {//if(preview_position[BM_elem_index_get(efa)] != STITCH_NO_PREVIEW){
- /* BMESH_TODO preview
- stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_tris[efa->tmp.l + 2*element->tfindex]);
+ else {
+ int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position;
+
+ stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint,
+ preview->preview_polys + face_preview_pos + 2*element->tfindex);
- preview->preview_tris[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0];
- preview->preview_tris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
- */
- (void)preview;
+ add_v2_v2(preview->preview_polys + face_preview_pos + 2*element->tfindex,
+ island_stitch_data[i].translation);
}
}
/* cleanup */
@@ -494,24 +497,22 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, I
/* set preview buffer position of UV face in editface->tmp.l */
-static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, unsigned int *preview_position)
+static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
{
int index = BM_elem_index_get(efa);
- if(preview_position[index] == STITCH_NO_PREVIEW)
+ if(preview_position[index].data_position == STITCH_NO_PREVIEW)
{
- //int num_of_tris = (efa->len > 2)? efa->len-2 : 0;
- //preview->num_tris*3;
-
- /* BMESH_TODO, count per face triangles */
- //preview->num_tris += num_of_tris;
+ preview_position[index].data_position = preview->preview_uvs*2;
+ preview_position[index].polycount_position = preview->num_polys++;
+ preview->preview_uvs += efa->len;
}
}
/* setup face preview for all coincident uvs and their faces */
static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- unsigned int *preview_position){
+ PreviewPosition *preview_position){
StitchPreviewer *preview = uv_get_stitch_previewer();
/* static island does not change so returning immediately */
@@ -531,7 +532,7 @@ static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchSta
/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
static void stitch_validate_stichability (UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- unsigned int *preview_position){
+ PreviewPosition *preview_position){
UvElement *element_iter;
StitchPreviewer *preview;
int vert_index;
@@ -579,7 +580,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* used to map uv indices to uvaverage indices for selection */
unsigned int *uvfinal_map;
/* per face preview position in preview buffer */
- unsigned int *preview_position;
+ PreviewPosition *preview_position;
/* cleanup previous preview */
stitch_preview_delete();
@@ -590,7 +591,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
preview_position = MEM_mallocN(state->em->bm->totface*sizeof(*preview_position), "stitch_face_preview_position");
/* each face holds its position in the preview buffer in tmp. -1 is uninitialized */
for(i = 0; i < state->em->bm->totface; i++){
- preview_position[i] = STITCH_NO_PREVIEW;
+ preview_position[i].data_position = STITCH_NO_PREVIEW;
}
island_stitch_data = MEM_callocN(sizeof(*island_stitch_data)*state->element_map->totalIslands, "stitch_island_data");
@@ -658,9 +659,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
unsigned int buffer_index = 0;
int stitchBufferIndex = 0, unstitchBufferIndex = 0;
/* initialize the preview buffers */
- preview->preview_tris = (unsigned int *)MEM_mallocN(preview->num_tris*sizeof(unsigned int)*3, "tri_uv_stitch_prev");
- preview->preview_coords = (float *)MEM_mallocN(state->total_separate_uvs*sizeof(float)*2, "co_uv_stitch_prev");
-
+ preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs*sizeof(float)*2, "tri_uv_stitch_prev");
+ preview->uvs_per_polygon = MEM_mallocN(preview->num_polys*sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable*sizeof(float)*2, "stitch_preview_stichable_data");
preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable*sizeof(float)*2, "stitch_preview_unstichable_data");
@@ -668,7 +668,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
preview->num_static_tris = state->tris_per_island[state->static_island];
/* will cause cancel and freeing of all data structures so OK */
- if(!preview->preview_tris || !preview->preview_stitchable || !preview->preview_unstitchable || !preview->preview_coords){
+ if(!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable){
return 0;
}
@@ -678,20 +678,23 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvElement *element = ED_get_uv_element(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
if(element){
+ int numoftris = efa->len - 2;
int index = BM_elem_index_get(efa);
-
- if(preview_position[index] != STITCH_NO_PREVIEW){
- /* BMESH_TODO preview */
- //memcpy(preview->preview_tris+efa->tmp.l, &mt->uv[0][0], 6*sizeof(float));
+ int face_preview_pos = preview_position[index].data_position;
+ if(face_preview_pos != STITCH_NO_PREVIEW){
+ preview->uvs_per_polygon[preview_position[index].polycount_position] = efa->len;
+ BM_ITER_INDEX(l, &liter, state->em->bm, BM_LOOPS_OF_FACE, efa, i) {
+ luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(preview->preview_polys + face_preview_pos + i*2, luv->uv);
+ }
}
if(element->island == state->static_island){
- int numoftris = efa->len - 2;
BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
MLoopUV *fuv = CustomData_bmesh_get(&state->em->bm->ldata, fl->head.data, CD_MLOOPUV);
- i = 0;
- BM_ITER(l, &liter, state->em->bm, BM_LOOPS_OF_FACE, efa) {
- if(i++ < numoftris){
+
+ BM_ITER_INDEX(l, &liter, state->em->bm, BM_LOOPS_OF_FACE, efa, i) {
+ if(i < numoftris){
/* using next since the first uv is already accounted for */
BMLoop *lnext = l->next;
MLoopUV *luvnext = CustomData_bmesh_get(&state->em->bm->ldata, lnext->next->head.data, CD_MLOOPUV);;
@@ -841,11 +844,12 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
copy_v2_v2(luv->uv, final_position[i].uv);
uvedit_uv_select(state->em, scene, l);
- }else if(preview_position[BM_elem_index_get(element_iter->face)] != STITCH_NO_PREVIEW){
- /* BMESH_TODO: preview for stitch
- *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2) = final_position[i].uv[0];
- *(preview->preview_tris+efa->tmp.l + element_iter->tfindex*2 + 1) = final_position[i].uv[1];
- */
+ }else {
+ int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position;
+ if(face_preview_pos != STITCH_NO_PREVIEW){
+ copy_v2_v2(preview->preview_polys + face_preview_pos + 2*element_iter->tfindex,
+ final_position[i].uv);
+ }
}
/* end of calculations, keep only the selection flag */
@@ -860,7 +864,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* final pass, calculate Island translation/rotation if needed */
if(state->snap_islands){
- stitch_calculate_island_snapping(state, preview, island_stitch_data, final);
+ stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final);
}
MEM_freeN(final_position);
@@ -927,33 +931,20 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal)
{
- /* BMESH_TODO need a way to disambiguate between normals for bmesh. */
-#if 0
- UvElement *element = edge->element;
- BMFace *efa = element->face;
- MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+ BMLoop *l1 = edge->element->l;
+ BMLoop *l2 = l1->next;
+ MLoopUV *luv1, *luv2;
+ float tangent[2];
- int nverts = efa->v4?4 : 3;
- int index = (element->tfindex + 2)%nverts;
- float tangent[2], internal[2];
+ luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&em->bm->ldata, l2->head.data, CD_MLOOPUV);
- sub_v2_v2v2(tangent, mt->uv[(element->tfindex + 1)%nverts], mt->uv[element->tfindex]);
- sub_v2_v2v2(internal, mt->uv[index], mt->uv[element->tfindex]);
+ sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
normal[0] = tangent[1];
normal[1] = -tangent[0];
- if(dot_v2v2(normal, internal) > 0){
- normal[0] = -tangent[1];
- normal[1] = tangent[0];
- }
-
normalize_v2(normal);
-#else
- (void)em;
- (void)edge;
- (void)normal;
-#endif
}
static int stitch_init(bContext *C, wmOperator *op)
@@ -1237,21 +1228,13 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
/* Store selection for re-execution of stitch */
for(i = 0; i < stitch_state->selection_size; i++){
PointerRNA itemptr;
- int j = 0;
- BMIter liter;
- BMLoop *l;
UvElement *element = stitch_state->selection_stack[i];
RNA_collection_add(op->ptr, "selection", &itemptr);
RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face));
- /* iterate to get the loop index. Better have this once here than everywhere else */
- BM_ITER(l, &liter, stitch_state->em->bm, BM_LOOPS_OF_FACE, element->face) {
- if(element->l == l)
- RNA_int_set(&itemptr, "element_index", j);
- j++;
- }
+ RNA_int_set(&itemptr, "element_index", element->tfindex);
}