Try to fix normals for open edges

Probably still not correct, depending on the complexity
of the object.
This commit is contained in:
hasufell 2014-05-15 18:52:28 +02:00
parent 3687646974
commit aaa485f072
No known key found for this signature in database
GPG Key ID: 220CD1C5BDEED020
2 changed files with 39 additions and 6 deletions

View File

@ -99,7 +99,7 @@ static bool get_all_emanating_edges(HE_vert const * const vert,
rc++; rc++;
} }
} while (edge != vert->edge); } while (edge && edge != vert->edge);
/* set out-pointers */ /* set out-pointers */
*edge_array_out = edge_array; *edge_array_out = edge_array;
@ -370,7 +370,8 @@ HE_obj *parse_obj(char const * const obj_string)
faces = (HE_face*) malloc(sizeof(HE_face) * fc); faces = (HE_face*) malloc(sizeof(HE_face) * fc);
CHECK_PTR_VAL(faces); CHECK_PTR_VAL(faces);
edges = (HE_edge*) malloc(sizeof(HE_edge) * ec); /* hold enough space for possible dummy edges */
edges = (HE_edge*) malloc(sizeof(HE_edge) * ec * 2);
CHECK_PTR_VAL(edges); CHECK_PTR_VAL(edges);
ec = 0; ec = 0;
@ -429,6 +430,7 @@ HE_obj *parse_obj(char const * const obj_string)
/* find pairs */ /* find pairs */
for (uint32_t i = 0; i < ec; i++) { /* for all edges */ for (uint32_t i = 0; i < ec; i++) { /* for all edges */
uint32_t eac = edges[i].vert->eac; uint32_t eac = edges[i].vert->eac;
bool pair_found = false;
for (uint32_t j = 0; j < eac; j++) { /* for all potential pairs */ for (uint32_t j = 0; j < eac; j++) { /* for all potential pairs */
if (edges[i].vert->edge_array[j] && if (edges[i].vert->edge_array[j] &&
@ -436,11 +438,36 @@ HE_obj *parse_obj(char const * const obj_string)
edges[i].vert->edge_array[j]->vert)) { edges[i].vert->edge_array[j]->vert)) {
edges[i].pair = edges[i].vert->edge_array[j]; edges[i].pair = edges[i].vert->edge_array[j];
edges[i].vert->edge_array[j] = NULL; edges[i].vert->edge_array[j] = NULL;
/* this is a trick to make sure the
* edge member of HE_vert is never
* a border-edge (unless there are only
* border edges), otherwise
* get_all_emanating_edges() would break
* for vertices that are at the edge
* of an open object */
edges[i].vert->edge = &(edges[i]);
pair_found = true;
break; break;
} }
} }
if (!pair_found) { /* we have a border edge */
/* add dummy edge, so get_all_emanating_edges()
* does not break */
edges[ec + i].face = NULL;
edges[ec + i].next = NULL;
edges[ec + i].pair = &(edges[i]);
edges[ec + i].vert = edges[i].next->vert;
edges[i].pair = &(edges[ec + i]);
}
} }
/* don't need the edge array anymore */
for (uint32_t i = 0; i < vc; i++)
free(vertices[i].edge_array);
obj = (HE_obj*) malloc(sizeof(HE_obj)); obj = (HE_obj*) malloc(sizeof(HE_obj));
CHECK_PTR_VAL(obj); CHECK_PTR_VAL(obj);
@ -472,7 +499,6 @@ void delete_object(HE_obj *obj)
for (uint32_t i = 0; i < obj->vc; i++) { for (uint32_t i = 0; i < obj->vc; i++) {
free(obj->vertices[i].vec); free(obj->vertices[i].vec);
free(obj->vertices[i].col); free(obj->vertices[i].col);
free(obj->vertices[i].edge_array);
} }
free(obj->edges); free(obj->edges);
free(obj->vertices); free(obj->vertices);

View File

@ -118,6 +118,8 @@ struct HE_edge {
HE_vert *vert; HE_vert *vert;
/** /**
* Oppositely oriented adjacent half-edge. * Oppositely oriented adjacent half-edge.
* Border edges have a dummy pair which have "face"
* and "next" set to NULL.
*/ */
HE_edge *pair; HE_edge *pair;
/** /**
@ -143,14 +145,19 @@ struct HE_vert {
/** /**
* One of the half-edges emanating from the vertex. * One of the half-edges emanating from the vertex.
* It is made sure that this is never a border edge,
* unless there are only border edges.
*/ */
HE_edge *edge; HE_edge *edge;
/** /**
* Acceleration structure which saves all * Acceleration structure which saves all potential
* edges that point TO this vertex. It is used * pair edges that point TO this vertex. It is used
* for finding the pairs when assembling * for finding the pairs when assembling
* the HE_edge struct. * the HE_edge struct. Note that this does not reliably
* save all border edges (which is a non-issue for the
* specific purpose of this struct since border-edges
* don't qualify for pairs anyway).
*/ */
HE_edge **edge_array; HE_edge **edge_array;