Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* __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;
}
Ejemplo n.º 3
0
/* __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;
}
Ejemplo n.º 4
0
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++;
}
Ejemplo n.º 5
0
/* __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;
}
Ejemplo n.º 6
0
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;
}