Exemplo n.º 1
0
void QhullVertexSet::
freeQhSetTemp()
{
    if(qhsettemp_defined){
        UsingLibQhull q(qhsettemp_qhull, QhullError::NOthrow);
        if(q.defined()){
            int exitCode = setjmp(qh errexit);
            if(!exitCode){ // no object creation -- destructors skipped on longjmp()
                qh_settempfree(referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
            }
            q.maybeThrowQhullMessage(exitCode, QhullError::NOthrow);
        }
    }
}//freeQhSetTemp
Exemplo n.º 2
0
void Compute_Convex_Hull( const SWIFT_Real* vs, int vn, int*& fs, int& fn )
{
    int i;

    // qhull variables
    int exitcode;
    facetT *facet;
    vertexT *vertex;
    vertexT **vertexp;
    setT *vertices;
    coordT *qhv = (coordT*)malloc( sizeof(coordT)*vn*3 );
    coordT *p = qhv;
    const SWIFT_Real* vsp = vs;

    // Load the coordinates into the vertex array for qhull since SWIFT_Real
    // may not be the same type.
    for( i = 0; i < vn; i++ ) {
        *p++ = *vsp++;
        *p++ = *vsp++;
        *p++ = *vsp++;
    }

    qh_init_A( stdin, stdout, stderr, 0, NULL );
    if( (exitcode = setjmp (qh errexit)) ) exit(exitcode);
    qh_initflags( options );
    qh_init_B( qhv, vn, 3, True );
    qh_qhull();
#ifdef SWIFT_DEBUG
    qh_check_output();
#endif

    fs = new int[((vn<<1) + 4)*3];
    fn = 0;
    FORALLfacets {
        setT *vertices = qh_facet3vertex(facet);
        FOREACHvertex_( vertices ) {
            fs[fn++] = qh_pointid(vertex->point);
        }
        // Swap the face vertex indices back
        i = fs[fn-1]; fs[fn-1] = fs[fn-2]; fs[fn-2] = i;
        qh_settempfree(&vertices);
    }
    //qh NOerrexit = True;
    qh_freeqhull(qh_ALL);

    fn /= 3;
}
Exemplo n.º 3
0
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;
	}
}
Exemplo n.º 4
0
void Compute_Convex_Hull( coordT* vs, int vn, int*& fs, int& fn )
{
    int i;

    // qhull variables
    int exitcode;
    facetT *facet;
    vertexT *vertex;
    vertexT **vertexp;
    setT *vertices;

    qh_init_A( stdin, stdout, stderr, 0, NULL );
    if( (exitcode = setjmp (qh errexit)) ) exit(exitcode);
    qh_initflags( options );
    qh_init_B( vs, vn, 3, True );
    qh_qhull();
#ifdef SWIFT_DEBUG
    qh_check_output();
#endif

    fs = new int[((vn<<1) + 4)*3];
    fn = 0;
    FORALLfacets {
        setT *vertices = qh_facet3vertex(facet);
        FOREACHvertex_( vertices ) {
            fs[fn++] = qh_pointid(vertex->point);
        }
        // Swap the face vertex indices back
        i = fs[fn-1]; fs[fn-1] = fs[fn-2]; fs[fn-2] = i;
        qh_settempfree(&vertices);
    }
    //qh_freeqhull(qh_ALL);
    qh_freeqhull(!qh_ALL);

    int i1, i2;
    qh_memfreeshort(&i1, &i2);

    fn /= 3;
}
Exemplo n.º 5
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*/
Exemplo n.º 6
0
CCLib::ReferenceCloud* qHPR::removeHiddenPoints(CCLib::GenericIndexedCloudPersist* theCloud, const CCVector3d& viewPoint, double fParam)
{
	assert(theCloud);

	unsigned nbPoints = theCloud->size();
	if (nbPoints == 0)
		return 0;

	//less than 4 points? no need for calculation, we return the whole cloud
	if (nbPoints < 4)
	{
		CCLib::ReferenceCloud* visiblePoints = new CCLib::ReferenceCloud(theCloud);
		if (!visiblePoints->addPointIndex(0,nbPoints)) //well even for less than 4 points we never know ;)
		{
			//not enough memory!
			delete visiblePoints;
			visiblePoints = 0;
		}
		return visiblePoints;
	}

	double maxRadius = 0;

	//convert point cloud to an array of double triplets (for qHull)
	coordT* pt_array = new coordT[(nbPoints+1)*3];
	{
		coordT* _pt_array = pt_array;

		for (unsigned i=0; i<nbPoints; ++i)
		{
			CCVector3d P = CCVector3d::fromArray(theCloud->getPoint(i)->u) - viewPoint;
			*_pt_array++ = static_cast<coordT>(P.x);
			*_pt_array++ = static_cast<coordT>(P.y);
			*_pt_array++ = static_cast<coordT>(P.z);

			//we keep track of the highest 'radius'
			double r2 = P.norm2();
			if (maxRadius < r2)
				maxRadius = r2;
		}
		
		//we add the view point (Cf. HPR)
		*_pt_array++ = 0;
		*_pt_array++ = 0;
		*_pt_array++ = 0;

		maxRadius = sqrt(maxRadius);
	}

	//apply spherical flipping
	{
		maxRadius *= pow(10.0,fParam) * 2;
	
		coordT* _pt_array = pt_array;
		for (unsigned i=0; i<nbPoints; ++i)
		{
			CCVector3d P = CCVector3d::fromArray(theCloud->getPoint(i)->u) - viewPoint;

			double r = (maxRadius/P.norm()) - 1.0;
			*_pt_array++ *= r;
			*_pt_array++ *= r;
			*_pt_array++ *= r;
		}
	}

	//array to flag points on the convex hull
	std::vector<bool> pointBelongsToCvxHull;

	static char qHullCommand[] = "qhull QJ Qci";
	if (!qh_new_qhull(3,nbPoints+1,pt_array,False,qHullCommand,0,stderr))
	{
		try
		{
			pointBelongsToCvxHull.resize(nbPoints+1,false);
		}
		catch (const std::bad_alloc&)
		{
			//not enough memory!
			delete[] pt_array;
			return 0;
		}

		vertexT *vertex = 0,**vertexp = 0;
		facetT *facet = 0;

		FORALLfacets
		{
			//if (!facet->simplicial)
			//	error("convhulln: non-simplicial facet"); // should never happen with QJ

			setT* vertices = qh_facet3vertex(facet);
			FOREACHvertex_(vertices)
			{
				pointBelongsToCvxHull[qh_pointid(vertex->point)] = true;
			}
			qh_settempfree(&vertices);
		}
	}

	delete[] pt_array;
	pt_array = 0;

	qh_freeqhull(!qh_ALL);
	//free long memory
	int curlong, totlong;
	qh_memfreeshort (&curlong, &totlong);
	//free short memory and memory allocator

	if (!pointBelongsToCvxHull.empty())
	{
		//compute the number of points belonging to the convex hull
		unsigned cvxHullSize = 0;
		{
			for (unsigned i=0; i<nbPoints; ++i)
				if (pointBelongsToCvxHull[i])
					++cvxHullSize;
		}

		CCLib::ReferenceCloud* visiblePoints = new CCLib::ReferenceCloud(theCloud);
		if (cvxHullSize!=0 && visiblePoints->reserve(cvxHullSize))
		{
			for (unsigned i=0; i<nbPoints; ++i)
				if (pointBelongsToCvxHull[i])
					visiblePoints->addPointIndex(i); //can't fail, see above

			return visiblePoints;

		}
		else //not enough memory
		{
			delete visiblePoints;
			visiblePoints = 0;
		}
	}

	return 0;
}
Exemplo n.º 7
0
/*-------------------------------------------------
-qhull- hull_dim convex hull of num_points starting at first_point
returns:
  returns facet_list, numfacets, etc. 
*/
void qh_qhull (void) {
  setT *maxpoints, *vertices;
  facetT *facet;
  int numpart, i, numoutside;
  realT dist;
  boolT isoutside;

  qh hulltime= qh_CPUclock;
  if (qh DELAUNAY && qh upper_threshold[qh hull_dim-1] > REALmax/2
                  && qh lower_threshold[qh hull_dim-1] < -REALmax/2) {
    for (i= qh_PRINTEND; i--; ) {
      if (qh PRINTout[i] == qh_PRINTgeom && qh DROPdim < 0 
 	  && !qh GOODthreshold && !qh SPLITthresholds)
	break;  /* in this case, don't set upper_threshold */
    }
    if (i < 0) {
      if (qh UPPERdelaunay)
	qh lower_threshold[qh hull_dim-1]= 0.0;
      else 
	qh upper_threshold[qh hull_dim-1]= 0.0;
      if (!qh GOODthreshold)
	qh SPLITthresholds= True; /* build upper-convex hull even if Qg */
      /* qh_initqhull_globals errors if Qg without Pdk/etc. */
    }
  }
  maxpoints= qh_maxmin(qh first_point, qh num_points, qh hull_dim);
  /* qh_maxmin sets DISTround and other precision constants */
  vertices= qh_initialvertices(qh hull_dim, maxpoints, qh first_point, qh num_points); 
  qh_initialhull (vertices);  /* initial qh facet_list */
  qh_partitionall (vertices, qh first_point, qh num_points);
  qh_resetlists (False /*qh visible_list newvertex_list newfacet_list */);
  qh facet_next= qh facet_list;
  qh_furthestnext (/* qh facet_list */);
  if (qh PREmerge) {
    qh cos_max= qh premerge_cos;
    qh centrum_radius= qh premerge_centrum;
  }
  if (qh ONLYgood) {
    if (qh GOODvertex > 0 && qh MERGING) {
      fprintf (qh ferr, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.  Use 'Q0'\n");
      qh_errexit (qh_ERRinput, NULL, NULL);
    }
    if (!(qh GOODthreshold || qh GOODpoint)) {
      fprintf (qh ferr, "qhull input error: 'Qg' (ONLYgood) needs a good threshold ('Pd0D0'), a\n\
good point (QGn or QG-n), or a good vertex with 'Q0' (QVn).\n");
      qh_errexit (qh_ERRinput, NULL, NULL);
    }
    if (qh GOODvertex > 0  && !qh MERGING  /* matches qh_partitionall */
	&& !qh_isvertex (qh GOODvertexp, vertices)) {
      facet= qh_findbestnew (qh GOODvertexp, qh facet_list, 
			  &dist, &isoutside, &numpart);
      zadd_(Zdistgood, numpart);
      if (!isoutside) {
        fprintf (qh ferr, "qhull input error: point for QV%d is inside initial simplex\n",
	       qh_pointid(qh GOODvertexp));
        qh_errexit (qh_ERRinput, NULL, NULL);
      }
      if (!qh_addpoint (qh GOODvertexp, facet, False)) {
	qh_settempfree(&vertices);
	qh_settempfree(&maxpoints);
	return;
      }
    }
    qh_findgood (qh facet_list, 0);
  }
Exemplo n.º 8
0
CCLib::ReferenceCloud* qHPR::removeHiddenPoints(CCLib::GenericIndexedCloudPersist* theCloud, float viewPoint[], float fParam)
{
	assert(theCloud);

	unsigned i,nbPoints = theCloud->size();

	if (nbPoints==0)
		return 0;

	CCLib::ReferenceCloud* newCloud = new CCLib::ReferenceCloud(theCloud);

	//less than 4 points ? no need for calculation, we return the whole cloud
	if (nbPoints<4)
	{
		if (!newCloud->reserve(nbPoints)) //well, we never know ;)
		{
			//not enough memory!
			delete newCloud;
			return 0;
		}
		newCloud->addPointIndex(0,nbPoints);
		return newCloud;
	}

	//view point
	coordT Cx = viewPoint[0];
	coordT Cy = viewPoint[1];
	coordT Cz = viewPoint[2];

	float* radius = new float[nbPoints];
	if (!radius)
	{
		//not enough memory!
		delete newCloud;
		return 0;
	}
	float r,maxRadius = 0.0;

	//table of points
	coordT* pt_array = new coordT[(nbPoints+1)*3];
	coordT* _pt_array = pt_array;
	theCloud->placeIteratorAtBegining();

//#define BACKUP_PROJECTED_CLOUDS
#ifdef BACKUP_PROJECTED_CLOUDS
	FILE* fp = fopen("output_centered.asc","wt");
#endif
	double x,y,z;
	for (i=0;i<nbPoints;++i)
	{
		const CCVector3* P = theCloud->getNextPoint();
		*(_pt_array++)=x=coordT(P->x)-Cx;
		*(_pt_array++)=y=coordT(P->y)-Cy;
		*(_pt_array++)=z=coordT(P->z)-Cz;
		//we pre-compute the radius ...
		r = (float)sqrt(x*x+y*y+z*z);
		//in order to determine the max radius
		if (maxRadius<r)
			maxRadius = r;
		radius[i] = r;
#ifdef BACKUP_PROJECTED_CLOUDS
		fprintf(fp,"%f %f %f %f\n",x,y,z,r);
#endif
	}
	//we add the view point (Cf. HPR)
	*(_pt_array++)=0.0;
	*(_pt_array++)=0.0;
	*(_pt_array++)=0.0;
#ifdef BACKUP_PROJECTED_CLOUDS
	fprintf(fp,"%f %f %f %f\n",0,0,0,0);
	fclose(fp);
#endif

	maxRadius *= 2.0f*pow(10.0f,fParam);

	_pt_array = pt_array;
#ifdef BACKUP_PROJECTED_CLOUDS
	fp = fopen("output_transformed.asc","wt");
#endif
	for (i=0;i<nbPoints;++i)
	{
		//Spherical flipping
		r = maxRadius/radius[i]-1.0f;
#ifndef BACKUP_PROJECTED_CLOUDS
		*(_pt_array++) *= double(r);
		*(_pt_array++) *= double(r);
		*(_pt_array++) *= double(r);
#else
		x = *_pt_array * double(r);
		*(_pt_array++) = x;
		y = *_pt_array * double(r);
		*(_pt_array++) = y;
		z = *_pt_array * double(r);
		*(_pt_array++) = z;
		fprintf(fp,"%f %f %f %f\n",x,y,z,r);
#endif
	}
#ifdef BACKUP_PROJECTED_CLOUDS
	fclose(fp);
#endif

	//we re-use the radius to record if each point belongs to the convex hull
	//delete[] radius;
	//uchar* pointBelongsToCvxHull = new uchar[nbPoints];
	uchar* pointBelongsToCvxHull = (uchar*)radius;
	memset(pointBelongsToCvxHull,0,sizeof(uchar)*(nbPoints+1));

	if (!qh_new_qhull(3,nbPoints+1,pt_array,False,(char*)"qhull QJ s Qci Tcv",0,stderr))
	{
		vertexT *vertex,**vertexp;
		facetT *facet;
		setT *vertices;

		int j, i = 0;
		FORALLfacets
		{
			/*if (!facet->simplicial)
				error("convhulln: non-simplicial facet"); // should never happen with QJ
				*/

			j = 0;
			vertices = qh_facet3vertex (facet);
			FOREACHvertex_(vertices)
			{
				pointBelongsToCvxHull[qh_pointid(vertex->point)]=1;
				++j;
			}
			qh_settempfree(&vertices);

			if (j < 3)
				printf("Warning, facet %d only has %d vertices\n",i,j); // likewise but less fatal

			i++;
		}
	}