Beispiel #1
0
void trimesh_t::remove_splinters() {
	list<trimesh_node_t*>::iterator triangle_iterator;
	int edge, dummy, i, j=0, k = 0;
	vertex_t new_verticies[3];

	cout << "starting to desplinter.\n";

	for (triangle_iterator = triangles.begin(); triangle_iterator != triangles.end(); triangle_iterator++) {
		// Copy verticies into a local list
		for (i=0; i<3; i++)
			new_verticies[i] = *(*triangle_iterator)->verticies[i];
	
		// Do ratio test
		if (!ratio_test(new_verticies, &dummy)) {	
			// If this triangle fails the test, search edge neighbors
			// for one that passes
			j++;
			for(edge = 0; edge < 3; edge++) {						
				if ((*triangle_iterator)->repair_triangles((*triangle_iterator), (*triangle_iterator)->neighbors[edge]) == 0) {
					k++;
					break;
				}
			}
			// Combine and split these triangles into two non-degenerate triangles

		}
	}

	cout << "try to desplinter " << j << "triangles, suceeded on " << k << "triangles \n";
}
int solver2(
    int m,		/* number of constraints */
    int N,		/* number of variables */
    int nz,		/* number of nonzeros in sparse constraint matrix */
    int *ia, 		/* array row indices */
    int *ka, 		/* array of indices into ia and a */
    double *a,		/* array of nonzeros in the constraint matrix */
    double *b, 		/* right-hand side */
    double *c,          /* objective coefficients */
    double *c2,         /* objective coefficients */
    double  f, 		/* objective function shift */
    int *basics,
    int *nonbasics,
    int *basicflag,
    int *freevars,
    int d1,
    int d2,
    double **BETAhat
    )
{

    double  *x_B;	/* primal basics */
    double  *y_N;	/* dual nonbasics */

    double  *xbar_B;	/* primal basic perturbation */
    double  *ybar_N;	/* dual nonbasic perturbation */

    double  *dy_N;	/*  dual  basics step direction - values (sparse) */
    int    *idy_N;	/*  dual  basics step direction - row indices */
    int     ndy_N;	/* number of nonz in dy_N */

    double  *dx_B;	/* primal basics step direction - values (sparse) */
    int    *idx_B;	/* primal basics step direction - row indices */
    int     ndx_B;	/* number of nonz in dx_B */

    double  *at;	/* sparse data structure for A^T */
    int    *iat;
    int    *kat;

    int     col_in;	/* entering column; index in 'nonbasics' */
    int     col_out;	/* leaving column; index in 'basics' */

    int     iter = 0;	/* number of iterations */
    int     i,j,k,n,v=0, j1,j2,ii;

    double  s, t, sbar, tbar, mu=HUGE_VAL, old_mu, primal_obj;

    double  *vec;
    int    *ivec;
    int     nvec;

    int	    status=0;

    int     from_scratch;

    /*******************************************************************
    * For convenience, we put...
    *******************************************************************/

    int n0 = d1*d2;
    n = N-m;

    /*******************************************************************
    * Read in the Data and initialize the common memory sites.
    *******************************************************************/

    CALLOC(    x_B, m,   double );      
    CALLOC( xbar_B, m,   double );      
    CALLOC(   dx_B, m,   double );      
    CALLOC(    y_N, n,   double );      
    CALLOC( ybar_N, n,   double );      
    CALLOC(   dy_N, n,   double );      
    CALLOC(    vec, N,   double );
    CALLOC(  idx_B, m,    int );      
    CALLOC(  idy_N, n,    int );      
    CALLOC(   ivec, N,    int );
    CALLOC(     at, nz,  double );
    CALLOC(    iat, nz,   int );
    CALLOC(    kat, m+1,  int );

    /**************************************************************** 
    *  Initialization.              				    *
    ****************************************************************/

    atnum(m,N,ka,ia,a,kat,iat,at);

    lufac( m, ka, ia, a, basics, 0);

    for (j=0; j<n; j++) {
	  y_N[j] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
       	if (c[basics[i]] != 0.0) {
 	    vec[nvec] = c[basics[i]];
 	    ivec[nvec] = i;
	    nvec++;
	}
    }

    

    btsolve( m, vec, ivec, &nvec );  		
    Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );
    for (k=0; k<ndy_N; k++) {
	y_N[idy_N[k]] = dy_N[k];
    }
    for (j=0; j<n; j++) {
	y_N[j] -= c[nonbasics[j]];
    }

    for (j=0; j<n; j++) {
	   ybar_N[j] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
	if (c2[basics[i]] != 0.0) {
	    vec[nvec] = c2[basics[i]];
	    ivec[nvec] = i;
	    nvec++;
	}
    }
    btsolve( m, vec, ivec, &nvec );  		
    Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );
    for (k=0; k<ndy_N; k++) {
	ybar_N[idy_N[k]] = dy_N[k];
    }
    for (j=0; j<n; j++) {
	ybar_N[j] -= c2[nonbasics[j]];
	if (ybar_N[j] < 0) printf("error: ybar_N[%d] = %e \n", j, ybar_N[j]);
    }

    for (i=0; i<m; i++) {
	       x_B[i] = 0;
	    xbar_B[i] = 0;
    }
    nvec = 0;
    for (i=0; i<m; i++) {
      if ( b[i] != 0.0 ) {
	 vec[nvec] = b[i];
	ivec[nvec] = i;
	nvec++;
      }
    }

    bsolve( m, vec, ivec, &nvec );
    for (i=0; i<nvec; i++) {
	x_B[ivec[i]] = vec[i];
           if (vec[i] < 0) printf("error: x_B[%d] = %e \n", i, vec[i]);
    }
/*
    printf ("m = %d,n = %d,nz = %d\n",m,N,nz);
    printf(
"---------------------------------------------------------------------------\n"
"          |   Primal      |        |                           arithmetic  \n"
"  Iter    |  Obj Value    |   mu   |   nonz(L)     nonz(U)     operations  \n"
"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n"
);*/

    /****************************************************************
    * 	Main loop                                                   *
    ****************************************************************/

    for (iter=0; iter<MAX_ITER; iter++) {


      /*************************************************************
      * STEP 1: Find mu                                            *
      *************************************************************/

      old_mu = mu;
      mu = -HUGE_VAL;
      col_in  = -1;
      for (j=0; j<n; j++) {
		if (ybar_N[j] > EPS2) { 
			if ( mu < -y_N[j]/ybar_N[j] ) {
			     mu = -y_N[j]/ybar_N[j];
			     col_in  = j;
			}
		}
      }
      col_out = -1;
      for (i=0; i<m; i++) {
         if (freevars[basics[i]] == 0) {
		if (xbar_B[i] > EPS2) { 
			if ( mu < -x_B[i]/xbar_B[i] ) {
			     mu = -x_B[i]/xbar_B[i];
			     col_out = i;
			     col_in  = -1;
			}
		}
         }
      }

      /*************************************************************
      * STEP 0: Record current portfolio                           *
      *************************************************************/

      primal_obj = sdotprod(c,x_B,basics,m) + f;
      if ( mu <= EPS3 || primal_obj > -EPS0) {	/* OPTIMAL */
          for (j1=0; j1<d1; j1++) {
	      for (j2=0; j2<d2; j2++) {
		  BETAhat[j1][j2] = 0;
	      }
	  }
	  for (i=0; i<m; i++) {
	    if (basics[i] < n0 && x_B[i] > EPS0) {
	      ii = basics[i];
	      j1 = ii%d1;
	      j2 = ii/d1;
	      BETAhat[j1][j2] = x_B[i];
	    }
	    else if (basics[i] < 2*n0 && x_B[i] > EPS0) {
	      ii = basics[i]-n0;
	      j1 = ii%d1;
	      j2 = ii/d1;
	      BETAhat[j1][j2] = -x_B[i];
	    }
	  }
          for (j1=0; j1<d1; j1++) {
            for (j2=0; j2<d2; j2++) {
	      if (ABS(BETAhat[j1][j2]) > 1e-5) {
	      }
            }
          }
	  status = 0;
	  break;
      }

      if ( col_out >= 0 ) {

        /*************************************************************
	*                          -1  T                             *
	* STEP 2: Compute dy  = -(B  N) e                            * 
	*                   N            i			     *
	*         where i = col_out                                  *
        *************************************************************/

	vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  		

	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

        /*************************************************************
	* STEP 3: Ratio test to find entering column                 * 
        *************************************************************/

	col_in = ratio_test2( dy_N, idy_N, ndy_N, y_N, ybar_N, mu );

	if (col_in == -1) { 	/* INFEASIBLE*/
	    status = 2;
	    printf("infeasible \n");
	    break;
	}

        /*************************************************************
	*                        -1                                  *
	* STEP 4: Compute dx  = B  N e                               * 
	*                   B         j                              *
	*                                                            *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;

	bsolve( m, dx_B, idx_B, &ndx_B );

      } else {

        /*************************************************************
	*                        -1                                  *
	* STEP 2: Compute dx  = B  N e                               * 
	*                   B         j                              *
        *************************************************************/

	j = nonbasics[col_in];
	for (i=0, k=ka[j]; k<ka[j+1]; i++, k++) {
	     dx_B[i] =  a[k];
	    idx_B[i] = ia[k];
	}
	ndx_B = i;

	bsolve( m, dx_B, idx_B, &ndx_B );

        /*************************************************************
	* STEP 3: Ratio test to find leaving column                  * 
        *************************************************************/

	col_out = ratio_test( dx_B, idx_B, ndx_B, x_B, xbar_B, basics, freevars, mu );

	if (col_out == -1) {	/* UNBOUNDED */
	    status = 1;
	    printf("unbounded \n");
	    break;
	}

        /*************************************************************
	*                          -1  T                             *
	* STEP 4: Compute dy  = -(B  N) e                            * 
	*                   N            i			     *
	*                                                            *
        *************************************************************/

	 vec[0] = -1.0;
	ivec[0] = col_out;
	nvec = 1;

	btsolve( m, vec, ivec, &nvec );  		

	Nt_times_y( N, at, iat, kat, basicflag, vec, ivec, nvec, 
		     dy_N, idy_N, &ndy_N );

      }

      /*************************************************************
      *                                                            *
      * STEP 5: Put       t = x /dx                                *
      *                        i   i                               *
      *                   _   _                                    *
      *                   t = x /dx                                *
      *                        i   i                               *
      *                   s = y /dy                                *
      *                        j   j                               *
      *                   _   _                                    *
      *                   s = y /dy                                *
      *                        j   j                               *
      *************************************************************/

      for (k=0; k<ndx_B; k++) if (idx_B[k] == col_out) break;

      t    =    x_B[col_out]/dx_B[k];
      tbar = xbar_B[col_out]/dx_B[k];

      for (k=0; k<ndy_N; k++) if (idy_N[k] == col_in) break;

      s    =    y_N[col_in]/dy_N[k];
      sbar = ybar_N[col_in]/dy_N[k];

      /*************************************************************
      *                                _    _    _                 *
      * STEP 7: Set y  = y  - s dy     y  = y  - s dy              *
      *              N    N       N     N    N       N             *
      *                                _    _                      *
      *             y  = s             y  = s                      *
      *              i                  i                          *
      *             _    _    _                                    *
      *             x  = x  - t dx     x  = x  - t dx              *
      *              B    B       B     B    B       B             *
      *             _    _                                         *
      *             x  = t             x  = t                      *
      *              j                  j                          *
      *************************************************************/

      for (k=0; k<ndy_N; k++) {
		j = idy_N[k];
		y_N[j]    -= s   *dy_N[k];
		ybar_N[j] -= sbar*dy_N[k];
      }

      y_N[col_in]    = s;
      ybar_N[col_in] = sbar;

      for (k=0; k<ndx_B; k++) {
		i = idx_B[k];
		x_B[i]    -= t   *dx_B[k];
		xbar_B[i] -= tbar*dx_B[k];

      }

      x_B[col_out]     = t;
      xbar_B[col_out]  = tbar;

      /*************************************************************
      * STEP 8: Update basis                                       * 
      *************************************************************/

      i =    basics[col_out];
      j = nonbasics[col_in];
      basics[col_out]   = j;
      nonbasics[col_in] = i;
      basicflag[i] = -col_in-1;
      basicflag[j] = col_out;

      /*************************************************************
      * STEP 9: Refactor basis and print statistics                *
      *************************************************************/

      from_scratch = refactor( m, ka, ia, a, basics, col_out, v);

      if (from_scratch) {
          primal_obj = sdotprod(c,x_B,basics,m) + f;
/*          printf("%8d %14.7e %9.2e \n", iter, high(primal_obj), high(mu));
            fflush(stdout);*/
      }
    } 

    primal_obj = sdotprod(c,x_B,basics,m) + f;

    /****************************************************************
    * 	Transcribe solution to x vector and dual solution to y      *
    ****************************************************************/

    /****************************************************************
    * 	Split out slack variables and shift dual variables.
    ****************************************************************/

    /****************************************************************
    * 	Free work space                                             *
    ****************************************************************/
 
    Nt_times_y(-1, at, iat, kat, basicflag, vec, ivec, nvec, dy_N, idy_N, &ndy_N);

    FREE(at);
    FREE(iat);

    FREE(xbar_B);
    FREE(kat);
    FREE(ybar_N);

    lu_clo();
    btsolve(0, vec, ivec, &nvec);
    bsolve(0, vec, ivec, &nvec);

    FREE(  vec );
    FREE( ivec );
    FREE(  x_B );
    FREE(  y_N );
    FREE( dx_B );
    FREE(idx_B );
    FREE( dy_N );
    FREE(idy_N );
    FREE( nonbasics );
    FREE( basics );

    
    return status;
}   /* End of solver */
Beispiel #3
0
// Takes two edge-neighbor triangles, joins them into a quadrilateral,
// and then splits them the opposite way.  This is used to repair degenerate
// triangles and to remove very small sliver triangles.
int trimesh_node_t::repair_triangles(trimesh_node_t* triangle_a, trimesh_node_t* triangle_b) {
	int i,j, edge_a = -1, edge_b = -1, dummy;
	vertex_t* quad_verticies[4];
	trimesh_node_t* quad_neighbors[4];
	trimesh_node_t* old_quad_neighbor[4];
	trimesh_node_t* new_quad_neighbor[4];
	vertex_t verticies_a[3];
	vertex_t verticies_b[3];
	vector_t normal_a, normal_b;
	int vertex_a[3];
	int vertex_b[3];


	// Get the common edge
	for (i=0; i<3; i++) {
		if ((triangle_a->neighbors[i]) == triangle_b) 
			edge_a = i;
		if ((triangle_b->neighbors[i]) == triangle_a)
			edge_b = i;
	}

	// If these triangles are not edge neighbors, return without doing anything
	if ((edge_a == -1) || (edge_b == -1))
		return(1);

	// The verticies for quadrilateral, in order, are:
	// opposite vertex of a from edge
	// next vertex of a
	// opposite vertex of b from edge
	// next vetex of a

	vertex_a[0] = opposite_vertex_from_edge(edge_a);
	vertex_a[1] = next_vertex(vertex_a[0]);
	vertex_a[2] = next_vertex(vertex_a[1]);
	vertex_b[0] = opposite_vertex_from_edge(edge_b);
	vertex_b[1] = next_vertex(vertex_b[0]);
	vertex_b[2] = next_vertex(vertex_b[1]);

	quad_verticies[0] = triangle_a->verticies[vertex_a[0]];
	quad_verticies[1] = triangle_a->verticies[vertex_a[1]];
	quad_verticies[2] = triangle_b->verticies[vertex_b[0]];
	quad_verticies[3] = triangle_b->verticies[vertex_b[1]];

	// The edge neighbors for the quadrilateral come from calling
	// get edge on the vertex number list...
	
	quad_neighbors[0] = triangle_a->neighbors[get_edge_number(vertex_a[0], vertex_a[1])];
	quad_neighbors[1] = triangle_b->neighbors[get_edge_number(vertex_b[2], vertex_b[0])];
	quad_neighbors[2] = triangle_b->neighbors[get_edge_number(vertex_b[0], vertex_b[1])];
	quad_neighbors[3] = triangle_a->neighbors[get_edge_number(vertex_a[2], vertex_a[0])];

	// Test resultant triangles to make sure they both pass the ratio test, and their
	// normal angle is not too different.  If not, do not do this. (This catches the case of
	// non-convex quadrilaterals) 

	verticies_a[0] = *quad_verticies[0];
	verticies_a[1] = *quad_verticies[1];
	verticies_a[2] = *quad_verticies[2];
	verticies_b[0] = *quad_verticies[2];
	verticies_b[1] = *quad_verticies[3];
	verticies_b[2] = *quad_verticies[0];

	if (ratio_test(verticies_a, &dummy) && ratio_test(verticies_b, &dummy)) {

		normal_a = normalize(cross(sub(verticies_a[1],verticies_a[0]), sub(verticies_a[2], verticies_a[0])));
		normal_b = normalize(cross(sub(verticies_b[1],verticies_b[0]), sub(verticies_b[2], verticies_b[0])));

		// If triangles have the same normal to within 90 degrees...
		if (dot(normal_a, normal_b) > 0) {
		// Write them out.

			old_quad_neighbor[0] = triangle_a;
			old_quad_neighbor[1] = triangle_b;
			old_quad_neighbor[2] = triangle_b;
			old_quad_neighbor[3] = triangle_a;


			// Now split the quadrilateral into two triangles, overwriting the old triangles

			// Update Verticies
			triangle_a->verticies[0] = quad_verticies[0];
			triangle_a->verticies[1] = quad_verticies[1];
			triangle_a->verticies[2] = quad_verticies[2];

			triangle_b->verticies[0] = quad_verticies[2];
			triangle_b->verticies[1] = quad_verticies[3];
			triangle_b->verticies[2] = quad_verticies[0];

			// Update Neighbors
			triangle_a->neighbors[0] = quad_neighbors[0];
			triangle_a->neighbors[1] = quad_neighbors[1];
			triangle_a->neighbors[2] = triangle_b;

			triangle_b->neighbors[0] = quad_neighbors[2];
			triangle_b->neighbors[1] = quad_neighbors[3];
			triangle_b->neighbors[2] = triangle_a;
	
			// Update our neigbors as to their new neighbors
			new_quad_neighbor[0] = triangle_a;
			new_quad_neighbor[1] = triangle_a;
			new_quad_neighbor[2] = triangle_b;
			new_quad_neighbor[3] = triangle_b;

			for (j=0; j<4; j++) {
				for(i=0; i<3; i++) {
					if (quad_neighbors[j]->neighbors[i] == old_quad_neighbor[j]) {
						quad_neighbors[j]->neighbors[i] = new_quad_neighbor[j];
						break;
					}
				}
			}
			return(0);
		}
		else {
			return(1);
		}
	}
	else {
		return(1);
	}
}