Browse Source

robustify

David Rose 19 years ago
parent
commit
2229f81ecf

+ 25 - 0
panda/src/mathutil/triangulator.I

@@ -28,6 +28,31 @@ add_vertex(double x, double y) {
   return add_vertex(LPoint2d(x, y));
   return add_vertex(LPoint2d(x, y));
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Triangulator::get_num_vertices
+//       Access: Published
+//  Description: Returns the number of vertices in the pool.  Note
+//               that the Triangulator might append new vertices, in
+//               addition to those added by the user, if any of the
+//               polygon is self-intersecting, or if any of the holes
+//               intersect some part of the polygon edges.
+////////////////////////////////////////////////////////////////////
+INLINE int Triangulator::
+get_num_vertices() const {
+  return _vertices.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Triangulator::get_vertex
+//       Access: Published
+//  Description: Returns the nth vertex.
+////////////////////////////////////////////////////////////////////
+INLINE const LPoint2d &Triangulator::
+get_vertex(int n) const {
+  nassertr(n >= 0 && n < (int)_vertices.size(), LPoint2d::zero());
+  return _vertices[n];
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Triangulator::Triangle::Constructor
 //     Function: Triangulator::Triangle::Constructor
 //       Access: Private
 //       Access: Private

+ 37 - 12
panda/src/mathutil/triangulator.cxx

@@ -137,6 +137,11 @@ triangulate() {
   for (i = 0; i < num_segments; ++i) {
   for (i = 0; i < num_segments; ++i) {
     permute.push_back(i + 1);
     permute.push_back(i + 1);
   }
   }
+
+  // Actually, I'm not sure why we should shuffle the index.  That
+  // makes the result non-deterministic, and isn't one order--for
+  // instance, the initial order--as good as any other?
+  /*
   Randomizer randomizer;
   Randomizer randomizer;
   for (i = 0; i < num_segments; ++i) {
   for (i = 0; i < num_segments; ++i) {
     int j = randomizer.random_int(num_segments);
     int j = randomizer.random_int(num_segments);
@@ -145,6 +150,7 @@ triangulate() {
     permute[i] = permute[j];
     permute[i] = permute[j];
     permute[j] = t;
     permute[j] = t;
   }
   }
+  */
   choose_idx = 0;
   choose_idx = 0;
 
 
   //  cerr << "got " << num_segments << " segments\n";
   //  cerr << "got " << num_segments << " segments\n";
@@ -1490,7 +1496,7 @@ get_angle(point_t *vp0, point_t *vpnext, point_t *vp1) {
 int Triangulator::
 int Triangulator::
 get_vertex_positions(int v0, int v1, int *ip, int *iq) {
 get_vertex_positions(int v0, int v1, int *ip, int *iq) {
   vertexchain_t *vp0, *vp1;
   vertexchain_t *vp0, *vp1;
-  register int i;
+  int i;
   double angle, temp;
   double angle, temp;
   int tp = 0, tq = 0;
   int tp = 0, tq = 0;
 
 
@@ -1543,11 +1549,14 @@ get_vertex_positions(int v0, int v1, int *ip, int *iq) {
  */
  */
 int Triangulator::
 int Triangulator::
 make_new_monotone_poly(int mcur, int v0, int v1) {
 make_new_monotone_poly(int mcur, int v0, int v1) {
-  //  printf("make_new_monotone_poly(%d, %d, %d)\n", mcur, v0, v1);
   int p, q, ip, iq;
   int p, q, ip, iq;
   int mnew = newmon();
   int mnew = newmon();
   int i, j, nf0, nf1;
   int i, j, nf0, nf1;
   vertexchain_t *vp0, *vp1;
   vertexchain_t *vp0, *vp1;
+
+  if (v0 <= 0 || v1 <= 0) {
+    return -1;
+  }
   
   
   vp0 = &vert[v0];
   vp0 = &vert[v0];
   vp1 = &vert[v1];
   vp1 = &vert[v1];
@@ -1606,7 +1615,7 @@ make_new_monotone_poly(int mcur, int v0, int v1) {
 
 
 int Triangulator::
 int Triangulator::
 monotonate_trapezoids(int n) {
 monotonate_trapezoids(int n) {
-  register int i;
+  int i;
   int tr_start;
   int tr_start;
 
 
   vert.clear();
   vert.clear();
@@ -1695,7 +1704,7 @@ traverse_polygon(int mcur, int trnum, int from, int dir) {
   int retval = 0;  //, tmp;
   int retval = 0;  //, tmp;
   int do_switch = false;
   int do_switch = false;
 
 
-  if (trnum <= 0)
+  if (mcur < 0 || trnum <= 0)
     return 0;
     return 0;
 
 
   //  printf("visited size = %d, visited[trnum] = %d\n", visited.size(), visited[trnum]);
   //  printf("visited size = %d, visited[trnum] = %d\n", visited.size(), visited[trnum]);
@@ -1977,12 +1986,12 @@ traverse_polygon(int mcur, int trnum, int from, int dir) {
 
 
 void Triangulator::
 void Triangulator::
 triangulate_monotone_polygons(int nvert, int nmonpoly) {
 triangulate_monotone_polygons(int nvert, int nmonpoly) {
-  register int i;
+  int i;
   point_t ymax, ymin;
   point_t ymax, ymin;
   int p, vfirst, posmax, posmin, v;
   int p, vfirst, posmax, posmin, v;
   int vcount, processed;
   int vcount, processed;
 
 
-#ifdef DEBUG
+  #ifdef DEBUG
   for (i = 0; i < nmonpoly; i++)
   for (i = 0; i < nmonpoly; i++)
     {
     {
       fprintf(stderr, "\n\nPolygon %d: ", i);
       fprintf(stderr, "\n\nPolygon %d: ", i);
@@ -1992,17 +2001,24 @@ triangulate_monotone_polygons(int nvert, int nmonpoly) {
       while (mchain[p].vnum != vfirst)
       while (mchain[p].vnum != vfirst)
 	{
 	{
 	  fprintf(stderr, "%d ", mchain[p].vnum);
 	  fprintf(stderr, "%d ", mchain[p].vnum);
+          if (mchain[p].vnum == -1) {
+            fprintf(stderr, " xx");
+            break;
+          }
 	  p = mchain[p].next;
 	  p = mchain[p].next;
 	}
 	}
     }
     }
   fprintf(stderr, "\n");
   fprintf(stderr, "\n");
-#endif
+  #endif
 
 
   for (i = 0; i < nmonpoly; i++)
   for (i = 0; i < nmonpoly; i++)
     {
     {
       vcount = 1;
       vcount = 1;
       processed = false;
       processed = false;
       vfirst = mchain[mon[i]].vnum;
       vfirst = mchain[mon[i]].vnum;
+      if (vfirst <= 0) {
+        return;
+      }
       ymin = vert[vfirst].pt;
       ymin = vert[vfirst].pt;
       ymax = ymin;
       ymax = ymin;
       posmin = mon[i];
       posmin = mon[i];
@@ -2011,14 +2027,17 @@ triangulate_monotone_polygons(int nvert, int nmonpoly) {
       p = mchain[mon[i]].next;
       p = mchain[mon[i]].next;
       while ((v = mchain[p].vnum) != vfirst)
       while ((v = mchain[p].vnum) != vfirst)
 	{
 	{
-	 if (mchain[p].marked)
+          if (v <= 0) {
+            return;
+          }
+          if (mchain[p].marked)
 	   {
 	   {
 	     processed = true;
 	     processed = true;
 	     break;		/* break from while */
 	     break;		/* break from while */
 	   }
 	   }
-	 else
-	   mchain[p].marked = true;
-
+          else
+            mchain[p].marked = true;
+          
 	  if (_greater_than(&vert[v].pt, &ymax))
 	  if (_greater_than(&vert[v].pt, &ymax))
 	    {
 	    {
 	      ymax = vert[v].pt;
 	      ymax = vert[v].pt;
@@ -2062,11 +2081,13 @@ triangulate_monotone_polygons(int nvert, int nmonpoly) {
  */
  */
 void Triangulator::
 void Triangulator::
 triangulate_single_polygon(int nvert, int posmax, int side) {
 triangulate_single_polygon(int nvert, int posmax, int side) {
-  register int v;
+  int v;
   vector_int rc;	/* reflex chain */
   vector_int rc;	/* reflex chain */
   int ri;
   int ri;
   int endv, tmp, vpos;
   int endv, tmp, vpos;
 
 
+  //  cerr << "triangulate_single_polygon(" << nvert << ", " << posmax << ", " << side << ")\n";
+
   if (side == TRI_RHS)		/* RHS segment is a single segment */
   if (side == TRI_RHS)		/* RHS segment is a single segment */
     {
     {
       rc.push_back(mchain[posmax].vnum);
       rc.push_back(mchain[posmax].vnum);
@@ -2096,6 +2117,10 @@ triangulate_single_polygon(int nvert, int posmax, int side) {
   
   
   while ((v != endv) || (ri > 1))
   while ((v != endv) || (ri > 1))
     {
     {
+      if (v <= 0) {
+        // Something went wrong.
+        return;
+      }
       if (ri > 0)		/* reflex chain is non-empty */
       if (ri > 0)		/* reflex chain is non-empty */
 	{
 	{
 	  if (CROSS(vert[v].pt, vert[rc[ri - 1]].pt, 
 	  if (CROSS(vert[v].pt, vert[rc[ri - 1]].pt, 

+ 3 - 0
panda/src/mathutil/triangulator.h

@@ -47,6 +47,9 @@ PUBLISHED:
   int add_vertex(const LPoint2d &point);
   int add_vertex(const LPoint2d &point);
   INLINE int add_vertex(double x, double y);
   INLINE int add_vertex(double x, double y);
 
 
+  INLINE int get_num_vertices() const;
+  INLINE const LPoint2d &get_vertex(int n) const;
+
   void clear_polygon();
   void clear_polygon();
   void add_polygon_vertex(int index);
   void add_polygon_vertex(int index);