//------------------------------------------------------------------- void SearchZones::addShiftedPrimitiveSearchZone(uint finger_id,vertexT const* curr_vtx) { setT *neighbor_facets=curr_vtx->neighbors; PrimitiveSearchZone* p_search_zone = new PrimitiveSearchZone(); p_search_zone->hyperplane_ids_.reserve(qh_setsize(neighbor_facets)); for(uint i=0; i < (uint)qh_setsize(neighbor_facets); i++) p_search_zone->hyperplane_ids_.push_back(((facetT*)neighbor_facets->e[i].p)->id); search_zones_[finger_id]->push_back(p_search_zone); }
void testSetcompactCopy(int numInts, int *intarray, int checkEvery) { setT *ints= qh_setnew(20); setT *ints2= NULL; int i,j,k; qh_fprintf(stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1); for(j=0; j<numInts; j++){ if(log_i(ints, "j", j, numInts, checkEvery)){ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */ for(k= 0; k<i%7; k++){ qh_setappend(&ints, NULL); } qh_setappend(&ints, intarray+i); } qh_setfree(&ints2); ints2= qh_setcopy(ints, 0); qh_setcompact(ints); qh_setcompact(ints2); checkSetContents("qh_setcompact", ints, j, 0, 0, -1); checkSetContents("qh_setcompact", ints2, j, 0, 0, -1); qh_setcompact(ints); checkSetContents("qh_setcompact", ints, j, 0, 0, -1); } } qh_setfree(&ints); qh_setfree(&ints2); }/*testSetcompactCopy*/
void testSetdelSetadd(int numInts, int *intarray, int checkEvery) { setT *ints=qh_setnew(1); int i,j,isCheck; qh_fprintf(stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1); for(j=1; j<numInts; j++){ /* size 0 not valid */ if(log_i(ints, "j", j, numInts, MAXint)){ for(i= qh_setsize(ints); i<j; i++){ qh_setappend(&ints, intarray+i); } checkSetContents("qh_setappend", ints, j, 0, -1, -1); for(i= 0; i<j && i<100; i++){ /* otherwise too slow */ isCheck= log_i(ints, "", i, numInts, checkEvery); (void)isCheck; /* unused */ qh_setdelnthsorted(ints, i); qh_setaddnth(&ints, i, intarray+i); if(checkEvery==1){ checkSetContents("qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1); } } checkSetContents("qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1); } } qh_setfree(&ints); }/*testSetdelSetadd*/
/*-<a href="qh-stat.htm#TOC" >-------------------------------</a><a name="collectstatistics">-</a> qh_collectstatistics() collect statistics for qh.facet_list */ void qh_collectstatistics(void) { facetT *facet, *neighbor, **neighborp; vertexT *vertex, **vertexp; realT dotproduct, dist; int sizneighbors, sizridges, sizvertices, i; qh old_randomdist= qh RANDOMdist; qh RANDOMdist= False; zval_(Zmempoints)= qh num_points * qh normal_size + sizeof(qhT) + sizeof(qhstatT); zval_(Zmemfacets)= 0; zval_(Zmemridges)= 0; zval_(Zmemvertices)= 0; zval_(Zangle)= 0; wval_(Wangle)= 0.0; zval_(Znumridges)= 0; zval_(Znumfacets)= 0; zval_(Znumneighbors)= 0; zval_(Znumvertices)= 0; zval_(Znumvneighbors)= 0; zval_(Znummergetot)= 0; zval_(Znummergemax)= 0; zval_(Zvertices)= qh num_vertices - qh_setsize(qh del_vertices); if (qh MERGING || qh APPROXhull || qh JOGGLEmax < REALmax/2) wmax_(Wmaxoutside, qh max_outside); if (qh MERGING) wmin_(Wminvertex, qh min_vertex); FORALLfacets facet->seen= False; if (qh DELAUNAY) { FORALLfacets { if (facet->upperdelaunay != qh UPPERdelaunay) facet->seen= True; /* remove from angle statistics */ } }
void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery) { setT *ints= qh_setnew(1); setT *ints2= NULL; int i,j; qh_fprintf(stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and 0..%d. Test", numInts-1); for(j=0; j<numInts; j++){ if(log_i(ints, "j", j, numInts, checkEvery)){ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */ qh_setaddsorted(&ints, intarray+i); } checkSetContents("qh_setaddsorted", ints, j, 0, 0, -1); if(j>3){ qh_setdelsorted(ints, intarray+i/2); checkSetContents("qh_setdelsorted", ints, j-1, 0, i/2+1, -1); qh_setaddsorted(&ints, intarray+i/2); checkSetContents("qh_setaddsorted i/2", ints, j, 0, 0, -1); } qh_setdellast(ints); checkSetContents("qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1); if(j>0){ qh_setaddsorted(&ints, intarray+j-1); checkSetContents("qh_setaddsorted j-1", ints, j, 0, -1, -1); } if(j>4){ qh_setdelnthsorted(ints, i/2); if (checkEvery==1) checkSetContents("qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1); /* test qh_setdelnth and move-to-front */ qh_setdelsorted(ints, intarray+i/2+1); checkSetContents("qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1); qh_setaddsorted(&ints, intarray+i/2+1); if (checkEvery==1) checkSetContents("qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1); qh_setaddsorted(&ints, intarray+i/2); checkSetContents("qh_setaddsorted i/2 again", ints, j, 0, -1, -1); } qh_setfree(&ints2); ints2= qh_setcopy(ints, 0); qh_setcompact(ints); qh_setcompact(ints2); checkSetContents("qh_setcompact", ints, j, 0, 0, -1); checkSetContents("qh_setcompact 2", ints2, j, 0, 0, -1); qh_setcompact(ints); checkSetContents("qh_setcompact 3", ints, j, 0, 0, -1); qh_setfree(&ints2); } } qh_setfreelong(&ints); if(ints){ qh_setfree(&ints); /* Was quick memory */ } }/*testSetdelsortedEtc*/
void testSetappendSet(int numInts, int *intarray, int checkEvery) { setT *ints=qh_setnew(1); setT *ints2; int i,j,k; qh_fprintf(stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1); for(j=0; j<numInts; j++){ if(log_i(ints, "j", j, numInts, numInts)){ for(i= qh_setsize(ints); i<j; i++){ qh_setappend(&ints, intarray+i); } if(checkEvery==1){ checkSetContents("qh_setappend", ints, j, 0, -1, -1); } ints2= qh_setnew(j==0 ? 0 : j-1); /* One less than needed */ for(i= 0; i<=j && i<=20; i++){ /* otherwise too slow */ if(log_i(ints, "", i, numInts, numInts)){ for(k= qh_setsize(ints2); k<i; k++){ qh_setappend(&ints2, intarray+k); } if(checkEvery==1){ checkSetContents("qh_setappend 2", ints2, i, 0, -1, -1); } qh_setappend_set(&ints, ints2); checkSetContents("qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1); qh_settruncate(ints, j); if(checkEvery==1){ checkSetContents("qh_settruncate", ints, j, 0, -1, -1); } } } qh_setfree(&ints2); } } qh_setfree(&ints); }/*testSetappendSet*/
bool QhullCalc::Calc( const std::vector<v3d> &pin, std::vector<v3d> &pout, std::vector<std::vector<int> > &fout)const { if(pin.size() < 4) return false; try { char cmd[]="qhull "; if(qh_new_qhull(3,int(pin.size()),const_cast<double*>(&pin[0].x),false,cmd,NULL,NULL)) return false; pointT *point, *pointtemp; FORALLpoints { pout.push_back(v3d(point[0],point[1],point[2])); } facetT *facet; vertexT *vertex, **vertexp; FORALLfacets { std::vector<int> idx; setT *vertices=qh_facet3vertex(facet); qh_setsize(vertices); FOREACHvertex_(vertices) { idx.push_back(qh_pointid(vertex->point)); } fout.push_back(idx); qh_settempfree(&vertices); } qh_freeqhull(!qh_ALL); int curlong, totlong; qh_memfreeshort(&curlong, &totlong); if(curlong || totlong) { return false; } return true; } catch(...) { return false; } }
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*/
void testSetlastEtc(int numInts, int *intarray, int checkEvery) { setT *ints= NULL; setT *ints2= NULL; int i,j,prepend; qh_fprintf(stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1); for(j=0; j<numInts; j++){ if(log_i(ints, "j", j, numInts, checkEvery)){ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */ if(!qh_setunique(&ints, intarray+i)){ qh_fprintf(stderr, 6340, "qh_setunique: not able to append next element %d\n", i); error_count++; } if(checkEvery==1){ checkSetContents("qh_setunique", ints, i+1, 0, -1, -1); } if(qh_setunique(&ints, intarray+i)){ qh_fprintf(stderr, 6341, "qh_setunique: appended next element twice %d\n", i); error_count++; } if(qh_setunique(&ints, intarray+i/2)){ qh_fprintf(stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i); error_count++; } } checkSetContents("qh_setunique 2", ints, j, 0, -1, -1); if(j==0 && NULL!=qh_setlast(ints)){ qh_fprintf(stderr, 6339, "qh_setlast: returned last element of empty set\n"); error_count++; } if(j>0){ if(intarray+j-1!=qh_setlast(ints)){ qh_fprintf(stderr, 6338, "qh_setlast: wrong last element\n"); error_count++; } prepend= (j<100 ? j/4 : 0); ints2= qh_setnew_delnthsorted(ints, qh_setsize(ints), j/2, prepend); if(qh_setsize(ints2)!=j+prepend-1){ qh_fprintf(stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(ints2)); error_count++; } /* Define prepended elements. Otherwise qh_setdelnthsorted may fail */ for(i= 0; i<prepend; i++){ void **p= &SETelem_(ints2, i); *p= intarray+0; } for(i= 0; i<prepend; i++){ qh_setdelnthsorted(ints2, 0); /* delete undefined prefix */ } checkSetContents("qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1); if(j>2){ qh_setzero(ints2, j/2, j-1); /* max size may be j-1 */ if(qh_setsize(ints2)!=j-1){ qh_fprintf(stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(ints2)); error_count++; } qh_setcompact(ints2); checkSetContents("qh_setzero", ints2, j/2, 0, -1, -1); } } qh_setfree(&ints2); } } qh_setfreelong(&ints); if(ints){ qh_setfree(&ints); /* Was quick memory */ } }/*testSetlastEtc*/
void testSetequalInEtc(int numInts, int *intarray, int checkEvery) { setT *ints= NULL; setT *ints2= NULL; setT *ints3= NULL; int i,j,n; qh_fprintf(stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1); for(j=0; j<numInts; j++){ if(log_i(ints, "j", j, numInts, checkEvery)){ n= qh_setsize(ints); qh_setlarger(&ints); checkSetContents("qh_setlarger", ints, n, 0, -1, -1); for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */ qh_setappend(&ints, intarray+i); } checkSetContents("qh_setappend", ints, j, 0, -1, -1); if(!qh_setequal(ints, ints)){ qh_fprintf(stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j); error_count++; } if(j==0 && !qh_setequal(ints, ints2)){ qh_fprintf(stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n"); error_count++; } if(j>0){ if(qh_setequal(ints, ints2)){ qh_fprintf(stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j); error_count++; } qh_setfree(&ints3); ints3= qh_setcopy(ints, 0); checkSetContents("qh_setreplace", ints3, j, 0, -1, -1); qh_setreplace(ints3, intarray+j/2, intarray+j/2+1); if(j==1){ checkSetContents("qh_setreplace 2", ints3, j, j/2+1, -1, -1); }else if(j==2){ checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, -1); }else{ checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1); } if(qh_setequal(ints, ints3)){ qh_fprintf(stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j); error_count++; } if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){ qh_fprintf(stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j); error_count++; } if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){ qh_fprintf(stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j); error_count++; } if(!qh_setequal_skip(ints, j/2, ints3, j/2)){ qh_fprintf(stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j); error_count++; } if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){ qh_fprintf(stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j); error_count++; } if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){ qh_fprintf(stderr, 6330, "qh_setdel: failed to find added element\n", j); error_count++; } checkSetContents("qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1)); /* swaps last element with deleted element */ if(j>3){ qh_setdelnth(ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */ checkSetContents("qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1)); } if(qh_setin(ints3, intarray+j/2)){ qh_fprintf(stderr, 6331, "qh_setin: found deleted element\n"); error_count++; } if(j>4 && !qh_setin(ints3, intarray+1)){ qh_fprintf(stderr, 6332, "qh_setin: did not find second element\n"); error_count++; } if(j>4 && !qh_setin(ints3, intarray+j-2)){ qh_fprintf(stderr, 6333, "qh_setin: did not find last element\n"); error_count++; } if(-1!=qh_setindex(ints2, intarray)){ qh_fprintf(stderr, 6334, "qh_setindex: found element in empty set\n"); error_count++; } if(-1!=qh_setindex(ints3, intarray+j/2)){ qh_fprintf(stderr, 6335, "qh_setindex: found deleted element in set\n"); error_count++; } if(0!=qh_setindex(ints, intarray)){ qh_fprintf(stderr, 6336, "qh_setindex: did not find first in set\n"); error_count++; } if(j-1!=qh_setindex(ints, intarray+j-1)){ qh_fprintf(stderr, 6337, "qh_setindex: did not find last in set\n"); error_count++; } } qh_setfree(&ints2); } } qh_setfree(&ints3); qh_setfreelong(&ints); if(ints){ qh_setfree(&ints); /* Was quick memory */ } }/*testSetequalInEtc*/
/*! 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); }