/* glu_fastuidraw_gl_meshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ GLUhalfEdge *glu_fastuidraw_gl_meshMakeEdge( GLUmesh *mesh ) { GLUvertex *newVertex1= allocVertex(); GLUvertex *newVertex2= allocVertex(); GLUface *newFace= allocFace(); GLUhalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == nullptr || newVertex2 == nullptr || newFace == nullptr) { if (newVertex1 != nullptr) memFree(newVertex1); if (newVertex2 != nullptr) memFree(newVertex2); if (newFace != nullptr) memFree(newFace); return nullptr; } e = MakeEdge( &mesh->eHead ); if (e == nullptr) { memFree(newVertex1); memFree(newVertex2); memFree(newFace); return nullptr; } MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex. * eOrg and eNew will have the same left face. */ GLUhalfEdge* __gl_meshAddEdgeVertex(GLUhalfEdge* eOrg) { GLUhalfEdge* eNewSym; GLUhalfEdge* eNew=MakeEdge(eOrg); if (eNew==NULL) { return NULL; } eNewSym=eNew->Sym; /* Connect the new edge appropriately */ Splice(eNew, eOrg->Lnext); /* Set the vertex and face information */ eNew->Org=eOrg->Dst; { GLUvertex* newVertex=allocVertex(); if (newVertex==NULL) { return NULL; } MakeVertex(newVertex, eNewSym, eNew->Org); } eNew->Lface=eNewSym->Lface=eOrg->Lface; return eNew; }
/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the * mesh connectivity and topology. It changes the mesh so that * eOrg->Onext <- OLD(eDst->Onext) * eDst->Onext <- OLD(eOrg->Onext) * where OLD(...) means the value before the meshSplice operation. * * This can have two effects on the vertex structure: * - if eOrg->Org != eDst->Org, the two vertices are merged together * - if eOrg->Org == eDst->Org, the origin is split into two vertices * In both cases, eDst->Org is changed and eOrg->Org is untouched. * * Similarly (and independently) for the face structure, * - if eOrg->Lface == eDst->Lface, one loop is split into two * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected. * * Some special cases: * If eDst == eOrg, the operation has no effect. * If eDst == eOrg->Lnext, the new face will have a single edge. * If eDst == eOrg->Lprev, the old face will have a single edge. * If eDst == eOrg->Onext, the new vertex will have a single edge. * If eDst == eOrg->Oprev, the old vertex will have a single edge. */ int __gl_meshSplice(GLUhalfEdge* eOrg, GLUhalfEdge* eDst) { int joiningLoops=FALSE; int joiningVertices=FALSE; if (eOrg==eDst) { return 1; } if (eDst->Org!=eOrg->Org) { /* We are merging two disjoint vertices -- destroy eDst->Org */ joiningVertices=TRUE; KillVertex(eDst->Org, eOrg->Org); } if (eDst->Lface!=eOrg->Lface) { /* We are connecting two disjoint loops -- destroy eDst->Lface */ joiningLoops=TRUE; KillFace(eDst->Lface, eOrg->Lface); } /* Change the edge structure */ Splice(eDst, eOrg); if (!joiningVertices) { GLUvertex* newVertex=allocVertex(); if (newVertex==NULL) { return 0; } /* We split one vertex into two -- the new vertex is eDst->Org. * Make sure the old vertex points to a valid half-edge. */ MakeVertex(newVertex, eDst, eOrg->Org); eOrg->Org->anEdge=eOrg; } if (!joiningLoops) { GLUface* newFace=allocFace(); if (newFace==NULL) { return 0; } /* We split one loop into two -- the new loop is eDst->Lface. * Make sure the old face points to a valid half-edge. */ MakeFace(newFace, eDst, eOrg->Lface); eOrg->Lface->anEdge=eOrg; } return 1; }
void SMwriter_smc_old::write_vertex(const float* v_pos_f) { if (v_count + f_count == 0) write_header(); SMvertex* vertex = allocVertex(); vertex->index = v_count; VecCopy3fv(vertex->v, v_pos_f); vertex_hash->insert(my_vertex_hash::value_type(v_count, vertex)); v_count++; }
/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face). * The loop consists of the two new half-edges. */ GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh ) { GLUvertex *newVertex1= allocVertex(); GLUvertex *newVertex2= allocVertex(); GLUface *newFace= allocFace(); GLUhalfEdge *e; /* if any one is null then all get freed */ if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) { if (newVertex1 != NULL) memFree(newVertex1); if (newVertex2 != NULL) memFree(newVertex2); if (newFace != NULL) memFree(newFace); return NULL; } e = MakeEdge( &mesh->eHead ); if (e == NULL) return NULL; MakeVertex( newVertex1, e, &mesh->vHead ); MakeVertex( newVertex2, e->Sym, &mesh->vHead ); MakeFace( newFace, e, &mesh->fHead ); return e; }
int SMreadPostAsCompactPre::read_postorder_input() { int i; SMvertex* vertex; SMtriangle* triangle; my_hash::iterator hash_element; SMevent event = smreader->read_element(); if (event == SM_TRIANGLE) { // create triangle triangle = allocTriangle(); // insert triangle into waiting area waiting_area->addElement(triangle); // process the triangle's vertices for (i = 0; i < 3; i++) { // look for vertex in the hash hash_element = vertex_hash->find(smreader->t_idx[i]); // did we find the vertex in the hash if (hash_element == vertex_hash->end()) { // create vertex vertex = allocVertex(); // insert vertex into hash vertex_hash->insert(my_hash::value_type(smreader->t_idx[i], vertex)); } else { // use vertex found in hash vertex = (*hash_element).second; } // add vertex to triangle triangle->vertices[i] = vertex; // add triangle to vertex if (vertex->list_size == vertex->list_alloc) { vertex->list_alloc += 4; vertex->list = (SMtriangle**)realloc(vertex->list,vertex->list_alloc*sizeof(SMtriangle*)); } vertex->list[vertex->list_size++] = triangle; } } else if (event == SM_VERTEX) { // look for vertex in the vertex hash hash_element = vertex_hash->find(smreader->v_idx); // we inform the user if a vertex was not in the hash if (hash_element == vertex_hash->end()) { fprintf(stderr, "WARNING: post-order vertex not used by any triangle. skipping ...\n"); return 1; } // use vertex found in hash vertex = vertex = (*hash_element).second; // copy coordinates VecCopy3fv(vertex->v, smreader->v_pos_f); // finalizing vertex may make some triangles eligible for output for (i = 0; i < vertex->list_size; i++) { triangle = vertex->list[i]; triangle->ready++; if (triangle->ready == 3) { if (preserve_order) // we have to preserve the triangle order { if (triangle == waiting_area->getFirstElement()) { waiting_area->removeFirstElement(); output_triangles->addElement(triangle); // behind this triangle additional ready triangles may be waiting while (waiting_area->size()) { triangle = (SMtriangle*)waiting_area->getFirstElement(); if (triangle->ready == 3) { waiting_area->removeFirstElement(); output_triangles->addElement(triangle); } else { break; } } } } else // we do not have to preserve the triangle order { waiting_area->removeElement(triangle); output_triangles->addElement(triangle); } } } // remove vertex from hash vertex_hash->erase(hash_element); } else if (event == SM_EOF) { if (vertex_hash->size()) { fprintf(stderr, "FATAL ERROR: some outstanding vertices when reaching SM_EOF\n"); return -1; } else { return 0; } } return 1; }