Пример #1
0
void testSettemp(int numInts, int *intarray, int checkEvery)
{
    setT *ints= NULL;
    setT *ints2= NULL;
    setT *ints3= NULL;
    int i,j;

    qh_fprintf(stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
    for(j=0; j<numInts; j++){
        if(log_i(ints, "j", j, numInts, checkEvery)){
            if(j<20){
                for(i=0; i<j; i++){
                    ints2= qh_settemp(j);
                }
                qh_settempfree_all();
            }
            for(i= qh_setsize(ints); i<j; i++){  /* Test i<j to test the empty set */
                qh_setappend(&ints, intarray+i);
            }
            ints2= qh_settemp(j);
            if(j>0){
                qh_settemppush(ints);
                ints3= qh_settemppop();
                if(ints!=ints3){
                    qh_fprintf(stderr, 6343, "qh_settemppop: didn't pop the push\n");
                    error_count++;
                }
            }
            qh_settempfree(&ints2);
        }
    }
    qh_setfreelong(&ints);
    if(ints){
        qh_setfree(&ints); /* Was quick memory */
    }
}/*testSettemp*/
/*! Uses the \a projCoords and \a fixedCoordSet (which identifies the indices
	of the fixed coordinates) to project the 6D hyperplanes of the Grasp Wrench 
	Space into 3D. The \a projCoords is an array of 6 values, but only 3 are used.  
	It then calls qhull to perform a halfspace intersection to get the vertices 
	of the 3D volume.  These vertices are stored in \a hullCoords, and indices 
	of the individual faces that make up the volume are stored in \a hullIndices 
	(an Indexed Face Set).
*/
int
GWS::projectTo3D(double *projCoords, std::set<int> fixedCoordSet,
				 std::vector<position> &hullCoords, std::vector<int> &hullIndices)
{
  int i,j,k,validPlanes,numCoords,numInLoop;
  double **planes;
  int freeCoord[3],fixedCoord[3];

  // qhull variables
  boolT ismalloc;
  int curlong,totlong,exitcode;
  char options[200];  
  facetT *facet;

  if (numHyperPlanes == 0) {
	  DBGP("No hyperplanes");
	  return SUCCESS;
  }

  planes = (double **) malloc(numHyperPlanes * sizeof(double *));
  if (!planes) {
#ifdef GRASPITDBG
    pr_error("GWS::ProjectTo3D,Out of memory allocating planes array");
    printf("NumHyperplanes: %d\n",numHyperPlanes);
#endif
    return FAILURE;
  }

  validPlanes = 0;

  // determine which dimensions are free and which are fixed
  // the set keeps things ordered
  for (i=0,j=0,k=0;i<6;i++) {
    if (fixedCoordSet.find(i) == fixedCoordSet.end()) {
      freeCoord[k++] = i;
	} else {
      fixedCoord[j++] = i;
	}
  }

  // project the hyperplanes to three dimensional planes
  for (i=0;i<numHyperPlanes;i++) {
    double len = sqrt(hyperPlanes[i][freeCoord[0]]*hyperPlanes[i][freeCoord[0]] +
                      hyperPlanes[i][freeCoord[1]]*hyperPlanes[i][freeCoord[1]] +
                      hyperPlanes[i][freeCoord[2]]*hyperPlanes[i][freeCoord[2]]);

    if (len>1e-11) {
      planes[validPlanes] = (double *) malloc(4 * sizeof(double));
      if (!planes[validPlanes]) {
		pr_error("Out of memory allocating planes array");
	    DBGP("Out of memory allocating planes array");
		return FAILURE;
	  }
      planes[validPlanes][0] = hyperPlanes[i][freeCoord[0]]/len;
      planes[validPlanes][1] = hyperPlanes[i][freeCoord[1]]/len;
      planes[validPlanes][2] = hyperPlanes[i][freeCoord[2]]/len;
      planes[validPlanes][3] = (hyperPlanes[i][6] + 
	                            hyperPlanes[i][fixedCoord[0]]*projCoords[fixedCoord[0]] +
		                        hyperPlanes[i][fixedCoord[1]]*projCoords[fixedCoord[1]] +
		                        hyperPlanes[i][fixedCoord[2]]*projCoords[fixedCoord[2]])/len;
      
      validPlanes++;
	}
  }

  if (validPlanes<numHyperPlanes) {
	  DBGP("Ignored " << numHyperPlanes-validPlanes << 
		   " hyperplanes which did not intersect this 3-space");
  }
  if (!validPlanes) {
	  DBGA("No valid planes in 3D projection!");
	  return FAILURE;
  }
	   

  //
  // call qhull to do the halfspace intersection
  //
  coordT *array = new coordT[validPlanes*3];
  coordT *p = &array[0];
  
  boolT zerodiv;
  coordT *point, *normp, *coordp, **pointp, *feasiblep;
  vertexT *vertex, **vertexp;

#ifdef GRASPITDBG
  printf("Calling qhull to perform a 3D halfspace intersection of %d planes...\n",validPlanes);
#endif

  ismalloc = False; 	// True if qh_freeqhull should 'free(array)'

  // I want to get rid of this but qh_init needs some sort of file pointer
  // for stdout and stderr
  FILE *qhfp = fopen("logfile","w");

  if (!qhfp) {
	fprintf(stderr,"Could not open qhull logfile!\n");
	qh_init_A(NULL, stdout, stderr, 0, NULL);
  }
  else
   qh_init_A(NULL, qhfp, qhfp, 0, NULL);

  if ((exitcode = setjmp(qh errexit))) {
    delete [] array;
	qh NOerrexit= True;
	qh_freeqhull(!qh_ALL);
	qh_memfreeshort (&curlong, &totlong);
	if (curlong || totlong)  	/* optional */
	   fprintf (stderr, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n",
		 totlong, curlong);
    for (i=0;i<validPlanes;i++)
      free(planes[i]);
    free(planes);
	if (qhfp) fclose(qhfp);
	DBGP("Qhull forces the exit; probably no valid intersection");
    return FAILURE; //exit(exitcode);
  }
  sprintf(options, "qhull -H0,0,0 Pp");
  qh_initflags(options);
  qh_setfeasible(3);
  if (!(qh feasible_point)) printf("why is qh_qh NULL?\n");
  for(i=0;i<validPlanes;i++) {
    qh_sethalfspace (3, p, &p, planes[i],&(planes[i][3]), qh feasible_point);
  }

  qh_init_B(&array[0], validPlanes, 3, ismalloc);
  qh_qhull();
  qh_check_output();
  if (qhfp) fclose(qhfp);

  //
  // Collect the vertices of the volume
  //
  hullCoords.clear();
  numCoords = qh num_facets;
  hullCoords.reserve(numCoords);
  int *indices = new int[numCoords];

  double scale = grasp->getMaxRadius(); // Hmm, is this right?

  point= (pointT*)qh_memalloc (qh normal_size);

  FORALLfacets {
    coordp = point;
	if (facet->offset > 0)
      goto LABELprintinfinite;
	
    normp= facet->normal;
    feasiblep= qh feasible_point;
    if (facet->offset < -qh MINdenom) {
      for (k= qh hull_dim; k--; )
        *(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
    }else {
      for (k= qh hull_dim; k--; ) {
        *(coordp++)= qh_divzero (*(normp++), facet->offset, qh MINdenom_1,&zerodiv) + *(feasiblep++);
        if (zerodiv) {
          goto LABELprintinfinite;
        }
      }
    }    
    hullCoords.push_back(position(point[0]*scale,point[1]*scale,
				  point[2]*scale));
    continue;
    LABELprintinfinite:
    hullCoords.push_back(position(qh_INFINITE,qh_INFINITE,qh_INFINITE));
    fprintf(stderr,"intersection at infinity!\n");
  }
  qh_memfree (point, qh normal_size);


  //
  // use adjacency information to build faces of the volume
  //
  double dot;
  vec3 testNormal, refNormal;

  int numfacets, numsimplicial, numridges, totneighbors, numneighbors, numcoplanars;
  setT *vertices, *vertex_points, *coplanar_points;
  int numpoints= qh num_points + qh_setsize (qh other_points);
  int vertex_i, vertex_n;
  facetT *neighbor, **neighborp;
  int unused_numnumtricoplanarsp; //added because countfacets takes more arguments in qhull 2012
								  //FIXME - understand what this argument does. 
  qh_countfacets (qh facet_list, NULL, !qh_ALL, &numfacets, &numsimplicial, 
      &totneighbors, &numridges, &numcoplanars, &unused_numnumtricoplanarsp);  /* sets facet->visitid */

  qh_vertexneighbors();
  vertices= qh_facetvertices (qh facet_list, NULL, !qh_ALL);
  vertex_points= qh_settemp (numpoints);
  coplanar_points= qh_settemp (numpoints);
  qh_setzero (vertex_points, 0, numpoints);
  qh_setzero (coplanar_points, 0, numpoints);
  FOREACHvertex_(vertices)
    qh_point_add (vertex_points, vertex->point, vertex);
  FORALLfacet_(qh facet_list) {
    FOREACHpoint_(facet->coplanarset)
      qh_point_add (coplanar_points, point, facet);
  }