示例#1
0
void BigInt::ToComplement()
{
	Refine();
	for(long long i = 0; i < MAXBIT - 1; i++)
		m_element[i] = JINZHI - 1 - m_element[i];
	m_element[0] += 1;
	Refine();
}
示例#2
0
/* Refine a curve until it can be approximated with straight lines to within
** the given tolerance. Always does at least one refinement, even if the
** original curve is inside tolerance. */
void
CubicBspline::Refine_Tolerance(CubicBspline &result, const float tolerance)
{
    Refine(result);
    while ( ! result.Within_Tolerance(tolerance) )
	result.Refine(result);
}
示例#3
0
文件: Tile.cpp 项目: reima/sep3d
void Tile::Init(float roughness) {
  // Zufallsgenerator initialisieren
  srand(static_cast<unsigned int>(time(0)));

  // x- und z-Koordinaten berechnen.
  // Das Wurzel-Tile ersteckt sich entlang der x- und z-Achse immer im Bereich
  // [-2.5, 2.5]
  int i = 0;
  for (int y = 0; y < size_; ++y) {
    for (int x = 0; x < size_; ++x, ++i) {
      vertices_[i].x = x * 5.0f / (size_ - 1) - 2.5f;
      vertices_[i].z = y * 5.0f / (size_ - 1) - 2.5f;
    }
  }

  // Ecken mit Zufallshöhenwerten initialisieren
  int block_size = size_ - 1;
  vertices_[I(0, 0)].y = randf();
  vertices_[I(0, block_size)].y = randf();
  vertices_[I(block_size, 0)].y = randf();
  vertices_[I(block_size, block_size)].y = randf();

  // Verfeinerungsschritte durchführen bis sämtliche Werte berechnet sind
  while (block_size > 1) {
    Refine(block_size, roughness);
    block_size = block_size / 2;
  }
}
示例#4
0
BigInt::BigInt(const BigInt& x)
{
	m_element = new unsigned long long[MAXBIT];
	m_isRefined = false;
	for(long long i = 0; i < MAXBIT; i++)
		m_element[i] = x.GetElement(i);
	Refine();
}
void Run()
	{
	SetStartTime();
	Log("Started %s\n", GetTimeAsStr());
	for (int i = 0; i < g_argc; ++i)
		Log("%s ", g_argv[i]);
	Log("\n");

#if	TIMING
	TICKS t1 = GetClockTicks();
#endif
	if (g_bRefine)
		Refine();
	else if (g_bRefineW)
		{
		extern void DoRefineW();
		DoRefineW();
		}
	else if (g_bProfDB)
		ProfDB();
	else if (g_bSW)
		Local();
	else if (0 != g_pstrSPFileName)
		DoSP();
	else if (g_bProfile)
		Profile();
	else if (g_bPPScore)
		PPScore();
	else if (g_bPAS)
		ProgAlignSubFams();
	else
		DoMuscle();

#if	TIMING
	extern TICKS g_ticksDP;
	extern TICKS g_ticksObjScore;
	TICKS t2 = GetClockTicks();
	TICKS TotalTicks = t2 - t1;
	TICKS ticksOther = TotalTicks - g_ticksDP - g_ticksObjScore;
	double dSecs = TicksToSecs(TotalTicks);
	double PctDP = (double) g_ticksDP*100.0/(double) TotalTicks;
	double PctOS = (double) g_ticksObjScore*100.0/(double) TotalTicks;
	double PctOther = (double) ticksOther*100.0/(double) TotalTicks;
	Log("                 Ticks     Secs    Pct\n");
	Log("          ============  =======  =====\n");
	Log("DP        %12ld  %7.2f  %5.1f%%\n",
	  (long) g_ticksDP, TicksToSecs(g_ticksDP), PctDP);
	Log("OS        %12ld  %7.2f  %5.1f%%\n",
	  (long) g_ticksObjScore, TicksToSecs(g_ticksObjScore), PctOS);
	Log("Other     %12ld  %7.2f  %5.1f%%\n",
	  (long) ticksOther, TicksToSecs(ticksOther), PctOther);
	Log("Total     %12ld  %7.2f  100.0%%\n", (long) TotalTicks, dSecs);
#endif

	ListDiagSavings();
	Log("Finished %s\n", GetTimeAsStr());
	}
bool RiemannianGeodesic<Real>::Subdivide (const GVector<Real>& end0,
    GVector<Real>& mid, const GVector<Real>& end1)
{
    mid = ((Real)0.5)*(end0 + end1);
    RefineCallbackFunction save = RefineCallback;
    RefineCallback = 0;
    bool changed = Refine(end0, mid, end1);
    RefineCallback = save;
    return changed;
}
void RiemannianGeodesic<Real>::ComputeGeodesic (const GVector<Real>& point0,
    const GVector<Real>& point1, int& quantity, GVector<Real>*& path)
{
    assertion(Subdivisions < 32, "Exceeds maximum iterations\n");
    quantity = (1 << Subdivisions) + 1;

    path = new1<GVector<Real> >(quantity);
    int i;
    for (i = 0; i < quantity; ++i)
    {
        path[i].SetSize(mDimension);
    }

    mCurrentQuantity = 2;
    path[0] = point0;
    path[1] = point1;

    for (mSubdivide = 1; mSubdivide <= Subdivisions; ++mSubdivide)
    {
        // A subdivision essentially doubles the number of points.
        int newQuantity = 2*mCurrentQuantity - 1;
        assertion(newQuantity <= quantity, "Unexpected condition.\n");

        // Copy the old points so that there are slots for the midpoints
        // during the subdivision, the slots interleaved between the old
        // points.
        for (i = mCurrentQuantity-1; i > 0; --i)
        {
            path[2*i] = path[i];
        }

        // Subdivide the polyline.
        for (i = 0; i <= mCurrentQuantity-2; ++i)
        {
            Subdivide(path[2*i], path[2*i+1], path[2*i+2]);
        }

        mCurrentQuantity = newQuantity;

        // Refine the current polyline vertices.
        for (mRefine = 1; mRefine <= Refinements; ++mRefine)
        {
            for (i = 1; i <= mCurrentQuantity-2; ++i)
            {
                Refine(path[i-1], path[i], path[i+1]);
            }
        }
    }

    assertion(mCurrentQuantity == quantity, "Unexpected condition\n");
    mSubdivide = 0;
    mRefine = 0;
    mCurrentQuantity = 0;
}
示例#8
0
文件: Tile.cpp 项目: reima/sep3d
Tile::Tile(Tile *parent, Tile::Direction direction, float roughness,
           Tile *north, Tile *west)
    : lod_(parent->lod_ + 1),
      size_(parent->size_),
      num_lod_(parent->num_lod_ - 1),
      index_buffer_(NULL),
      direction_(direction),
      parent_(parent) {
  vertices_ = new Vector[size_*size_];
  InitFromParent();
  Refine(2, roughness);
  FixEdges(north, west);
  InitChildren(roughness, north, west);
}
示例#9
0
void AdaptiveSparseGrid::BuildFirstLevel() {
	AdaptiveARRAY<int>* px1 = AdaptiveCoordAllocator.NewItem(dim);
	AdaptiveARRAY<int>* px2 = AdaptiveCoordAllocator.NewItem(dim);


	px1 -> fill(1);
	px2 -> fill(0);

	//! The first level is always a single point.
	AdaptiveARRAY<double> x;
	x.redim(dim);
	x.fill(0.5);

	L = 0;

	//! For the fisrt point, we always assign it to rank 0
	if (rank == 0) {
		EvaluateFunctionAtThisPoint(&x);
		AdaptiveData* pData = AdaptiveDataAllocator.NewItem();
		AdaptiveNodeData* pNodeData = AdaptiveNodeDataAllocator.NewItem();
		pData->index = px1;
		pNodeData->index = px2;
		pNodeData->surplus = new double[TotalDof];

		for ( int i = 0; i < TotalDof; i++) {
			pNodeData->surplus[i] = surplus[i];
		}

		pData->NodeData.insert(pNodeData);
		SparseGrid.push_front(pData);
	}

	MPI_Barrier(mpiCOMM);

	//Generate New sons for each dimension
	Refine(px1, px2);

	// Compute the integration value
	if ( type == 1)
	{ UpdateError(); }

	if ( rank != 0) {
		AdaptiveCoordAllocator.DeleteItem(px1);
		AdaptiveCoordAllocator.DeleteItem(px2);
	}
}
示例#10
0
void GenerateIcosphere(Grid& grid, const vector3& center, number radius,
					   int numRefinements, AVector3& aPos, Selector* psel)
{
	Selector defSel;
	if(!psel){
		defSel.assign_grid(grid);
		psel = &defSel;
	}

	Selector& sel = *psel;

//	enable autoselection
	bool autoselectionEnabled = sel.autoselection_enabled();
	sel.enable_autoselection(true);

//	clear the selector
	sel.clear();

//	create an icosahedron. All elements of the sphere will be selected, since we
//	enabled autoselection
	GenerateIcosahedron(grid, center, radius, aPos);

//	perform refinement steps
//	we need a temporary int attachment for the edges
	AInt aInt;
	grid.attach_to_edges(aInt);

//	use a refinement callback to project the new vertices to the sphere
	SphereProjector sphereProjecton(MakeGeometry3d(grid, aPos), center);

	for(int i = 0; i < numRefinements; ++i)
		Refine(grid, sel, aInt, &sphereProjecton);

//	remove attachments
	grid.detach_from_edges(aInt);

//	restore autoselection
	sel.enable_autoselection(autoselectionEnabled);
}
示例#11
0
文件: refine.c 项目: jamjr/Helios-NG
int main(int argc, char **argv)
{
	char dcname[40];
	AccMask setmask = 0;	
	AccMask clearmask = 0;
	char *s;

        PrgName = argv [0];

	if( argc < (1 + 1))
	{
		printf("Usage: %s [[-+=][rwefghvxyzda]] <Objects>\n", PrgName);
		exit(1);
	}

	argv++;
	
	s = *argv;

	if( *s == '+' || *s == '-' || *s == '=' )
	{
		AccMask *mask = &setmask;
		if( *s == '-' ) mask = &clearmask;
		elif( *s == '=' ) clearmask = 0xff;

		s++;
		
		while( *s != '\0' )
		{
			int bit = getbit(*s,FileChars);
			if( bit == 0 ) bit = getbit(*s,DirChars);
			if( bit == 0 ) printf("invalid bit character %c\n",*s);
			*mask |= bit;
			s++;
		}
		argv++;
	}
	
	for( ; *argv != NULL; argv++ )
	{
		char *name = *argv;
		Object *o;
		word e;
		
		o = Locate(CurrentDir,name);
		
		if( o == NULL ) 
		{
			fprintf(stderr,"could not locate %s : %x\n",name,Result2(CurrentDir));		
			continue;
		}
	
		if( clearmask || setmask )
		{
			AccMask mask = o->Access.Access;
			mask &= ~clearmask;
			mask |= setmask;
			
			e = Refine(o,mask);

			if( e < 0 )
				fprintf(stderr,"refine of %s failed: %x\n",name,e);
		}		
		
		DecodeCapability(dcname,&o->Access);	

		printf("%s%s\n",dcname,o->Name);
	}

	return 0;
}
示例#12
0
    /**
     * Sample from the normal distribution with mean 0 and variance 1.
     *
     * @param[out] val the sample from the normal distribution
     * @param[in,out] r a GMP random generator.
     * @param[in] round the rounding direction.
     * @return the MPFR ternary result (&plusmn;1 if val is larger/smaller than
     *   the exact sample).
     **********************************************************************/
    int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const {
      const double
        s  =  0.449871, // Constants from Leva
        t  = -0.386595,
        a  =  0.19600 ,
        b  =  0.25472 ,
        r1 =  0.27597 ,
        r2 =  0.27846 ,
        u1 =  0.606530,           // sqrt(1/e) rounded down and up
        u2 =  0.606531,
        scale = std::pow(2.0, -chunk_); // for turning randoms into doubles

      while (true) {
        mpz_urandomb(_vi, r, chunk_);
        if (mpz_cmp_ui(_vi, m) >= 0) continue; // Very early reject
        double vf = (mpz_get_ui(_vi) + 0.5) * scale;
        mpz_urandomb(_ui, r, chunk_);
        double uf = (mpz_get_ui(_ui) + 0.5) * scale;
        double
          x = uf - s,
          y = vf - t,
          Q = x*x + y * (a*y - b*x);
        if (Q >= r2) continue;    // Early reject
        mpfr_set_ui_2exp(_eps, 1u, -chunk_, MPFR_RNDN);
        mpfr_prec_t prec = chunk_;
        mpfr_set_prec(_u, prec);
        mpfr_set_prec(_v, prec);
        // (u,v) = sw corner of range
        mpfr_set_z_2exp(_u, _ui, -prec, MPFR_RNDN);
        mpfr_set_z_2exp(_v, _vi, -prec, MPFR_RNDN);
        mpfr_set_prec(_up, prec);
        mpfr_set_prec(_vp, prec);
        // (up,vp) = ne corner of range
        mpfr_add(_up, _u, _eps, MPFR_RNDN);
        mpfr_add(_vp, _v, _eps, MPFR_RNDN);
        // Estimate how many extra bits will be needed to achieve the desired
        // precision.
        mpfr_prec_t prec_guard = 3 + chunk_ -
          (std::max)(mpz_sizeinbase(_ui, 2), mpz_sizeinbase(_vi, 2));
        if (Q > r1) {
          int reject;
          while (true) {
            // Rejection curve v^2 + 4 * u^2 * log(u) < 0 has a peak at u =
            // exp(-1/2) = 0.60653066.  So treat uf in (0.606530, 0.606531) =
            // (u1, u2) specially

            // Try for rejection first
            if (uf <= u1)
              reject = Reject(_u, _vp, prec, MPFR_RNDU);
            else if (uf >= u2)
              reject = Reject(_up, _vp, prec, MPFR_RNDU);
            else {              // u in (u1, u2)
              mpfr_set_prec(_vx, prec);
              mpfr_add(_vx, _vp, _eps, MPFR_RNDN);
              reject = Reject(_u, _vx, prec, MPFR_RNDU); // Could use _up too
            }
            if (reject < 0) break; // tried to reject but failed, so accept

            // Try for acceptance
            if (uf <= u1)
              reject = Reject(_up, _v, prec, MPFR_RNDD);
            else if (uf >= u2)
              reject = Reject(_u, _v, prec, MPFR_RNDD);
            else {              // u in (u2, u2)
              mpfr_sub(_vx, _v, _eps, MPFR_RNDN);
              reject = Reject(_u, _vx, prec, MPFR_RNDD); // Could use _up too
            }
            if (reject > 0) break; // tried to accept but failed, so reject

            prec = Refine(r, prec);  // still can't decide, to refine
          }
          if (reject > 0) continue; // reject, back to outer loop
        }
        // Now evaluate v/u to the necessary precision
        mpfr_prec_t prec0 = mpfr_get_prec (val);
        //        while (prec < prec0 + prec_guard) prec = Refine(r, prec);
        if (prec < prec0 + prec_guard)
          prec = Refine(r, prec,
                        (prec0 + prec_guard - prec + chunk_ - 1) / chunk_);
        mpfr_set_prec(_x1, prec0);
        mpfr_set_prec(_x2, prec0);
        int flag;
        while (true) {
          int
            f1 = mpfr_div(_x1, _v, _up, round),   // min slope
            f2 = mpfr_div(_x2, _vp, _u, round);   // max slope
          if (f1 == f2 && mpfr_equal_p(_x1, _x2)) {
            flag = f1;
            break;
          }
          prec = Refine(r, prec);
        }
        mpz_urandomb(_ui, r, 1);
        if (mpz_tstbit(_ui, 0)) {
          flag = -flag;
          mpfr_neg(val, _x1, MPFR_RNDN);
        } else
          mpfr_set(val, _x1, MPFR_RNDN);
        //      std::cerr << uf << " " << vf << " " << Q << "\n";
        return flag;
      }
    }
示例#13
0
void AdaptiveSparseGrid::ConstructAdaptiveSparseGrid() {
	//! Define a buffer deque to store all of the intermediate information
	deque<AdaptiveData*> buffer;

	//! iterator for transverse the active index
	set<AdaptiveData*, AdaptiveDataCompare>::iterator it1;
	set<AdaptiveNodeData*, AdaptiveNodeDataCompare>::iterator it2;
	AdaptiveGrid OldIndex;

	AdaptiveData* pData ;
	AdaptiveNodeData* pNodeData;

	//! Here we still keep a copy of active index for each processor for the purpose
	//! of the easy implementation of the adaptivity

	while ( !ActiveIndex.empty() && L <= Lmax ) {
		int gnumber = NumberOfActivePoints();


		if (rank == 0 && print) {
			cout << "Now, it is in Level: " << L << endl;
			cout << "The active number of points are: " << gnumber << endl;
		}

		//Copy the ActiveIndex to an oldIndex
		OldIndex = ActiveIndex;

		ActiveIndex.clear();

		//! Define a temporary matrix to store all of the active point for parallel computation
		Matrix1<double> gpoint;
		gpoint.redim(gnumber, dim);
		double time1, time;
		time1 = MPI_Wtime();
		int row = 1;

		//! Extract the coordiante information
		for (it1 = OldIndex.begin(); it1 != OldIndex.end(); ++it1) {
			for (it2 = (*it1)->NodeData.begin(); it2 != (*it1)->NodeData.end(); ++it2) {
				for ( int i = 1; i <= dim ; i++) {
					gpoint(row, i)  = IndextoCoordinate((*(*it1)->index)(i), (*(*it2)->index)(i));
				}
				row++;
			}
		}

		// Parallel Implementation

		int node;

		AdaptiveARRAY<double> px;
		px.redim(dim);

		//! Distribute the points among the processors
		int numNodesPerProcessor = 0;

		for (int i = 0; i < gnumber; i++)
			if ( (i % size) == rank)
			{ numNodesPerProcessor++; }

		int colnumber = TotalDof * numNodesPerProcessor;
		//!Local value to store function value
		double*  local_value = new double[colnumber];
		//! An array to store the nodes which belong to this processor
		int*     mynodes = new int[numNodesPerProcessor];

		for ( int no = 1 ; no <= numNodesPerProcessor; no++) {
			node = rank + size * (no - 1) + 1;
			mynodes[no - 1] = node;

			for ( int i = 1 ; i <= dim ; i++)
			{ px(i) = gpoint(node, i); }

			EvaluateFunctionAtThisPoint(&px);

			for ( int i = 0; i < TotalDof ; i++) {
				local_value[(no - 1)*TotalDof + i]  = surplus[i] ;
			}
		}

		/**
		 * EDIT BY ARYAN
		 */
		MPI_Barrier(mpiCOMM);

		time = MPI_Wtime();

		if (rank == 0 && print ) { cout << "Parallel Calculation using " << time - time1 << endl; }

		gpoint.cleanup();

		//! Set the action before storing the surplus
		BeforeStoreSurplus();

		int index = 1;
		int cnt = 0, mynode;

		//! Extract the coordiante information
		for (it1 = OldIndex.begin(); it1 != OldIndex.end(); ++it1) {

			int number = (*it1)->NodeData.size();

			//! Define a temporary matrix to store all of the active point for parallel computation
			Matrix1<double> point;
			point.redim(number, dim);

			int row = 1;

			for (it2 = (*it1)->NodeData.begin(); it2 != (*it1)->NodeData.end(); ++it2) {
				for ( int i = 1; i <= dim ; i++) {
					point(row, i)  = IndextoCoordinate((*(*it1)->index)(i), (*(*it2)->index)(i));
				}

				row++;
			}


			//! If there are points in this processor, generate a new data to store information
			if ( numNodesPerProcessor != 0) {
				pData = AdaptiveDataAllocator.NewItem();
				pData->index = (*it1)->index;
				buffer.push_front(pData);
			}


			double* temp = new double[TotalDof * number];
			//! Calculate the hierarchical surplus
			SpInterpolateLevel(point, temp);

			//! Calculate the hierarchial surplus and generate the adaptivity information
			Array<int> local_refine; local_refine.redim(number); local_refine.fill(0);
			Array<int> global_refine; global_refine.redim(number);

			int temp_index = index;
			int temp_cnt = cnt;

			it2 = (*it1)->NodeData.begin();

			for ( int n = 1;  n <= number; n++) {

				if ( (temp_cnt != numNodesPerProcessor) && (temp_index == mynodes[temp_cnt]) ) {
					for ( int i = 0; i < TotalDof; i++) {
						local_value[temp_cnt * TotalDof + i] = surplus[i] = local_value[temp_cnt * TotalDof + i] - temp[(n - 1) * TotalDof + i];
					}

					//! Check the adaptivity criteria
					local_refine(n) = IsRefine(surplus, (*it1)->index, (*it2)->index);
					temp_cnt ++;
				}

				temp_index++;
				++it2;
			}

			//! Free space
			delete[] temp;


			int error = MPI_Allreduce(local_refine.pData, global_refine.pData, number, MPI_INT, MPI_SUM, mpiCOMM);
			//if (error) { cout << "ERORR 221 : " << error <<  "|" << rank << endl; }

			//! Free space
			local_refine.cleanup();

			it2 = (*it1)->NodeData.begin();

			// calculate herarchial surplus for each coordinate
			for ( int n = 1 ; n <= number; n++) {

				//! If this point belongs to this processor
				if ( (cnt != numNodesPerProcessor) && (index == mynodes[cnt]) ) {
					//Copy data to sparse grid
					pNodeData = (*it2);
					pNodeData->surplus = new double[TotalDof];

					for ( int i = 0; i < TotalDof; i++) {
						pNodeData->surplus[i] = local_value[cnt * TotalDof + i];
					}

					//! Refinement
					if ( global_refine(n))
					{ Refine((*it1)->index, (*it2)->index); }

					cnt ++;
					//! Insert the this nodadata to the buffer
					pData->NodeData.insert(pNodeData);
				}

				//! the point doesn't belong to this processor
				else {
					if ( global_refine(n))
					{ Refine((*it1)->index, (*it2)->index); }

					//! If this point doesn't belong to this processor, delete the point.
					AdaptiveCoordAllocator.DeleteItem((*it2)->index);
					AdaptiveNodeDataAllocator.DeleteItem(*it2);
				}

				++it2;
				index++;

			}

			//free space
			global_refine.cleanup();

			//! If there are no point for this processor, delete the data.
			if ( numNodesPerProcessor == 0) {
				AdaptiveCoordAllocator.DeleteItem((*it1)->index);
				AdaptiveDataAllocator.DeleteItem(*it1);
			}
		}// End for

		//free space
		delete[] local_value;
		delete[] mynodes;

		/**
		* EDIT BY ARYAN
		*/
		MPI_Barrier(mpiCOMM);

		time1 = MPI_Wtime();

		if (rank == 0 && print) { cout << "Surplus  Calculation using " << time1 - time << endl; }

		//! Insert all of the active points to the adaptive spare grid.
		SparseGrid.insert(SparseGrid.begin(), buffer.begin(), buffer.end());

		if ( type == 1)
		{ UpdateError(); }

		//free space
		buffer.clear();
		OldIndex.clear();
		L += 1;

		//! Set the action before storing the surplus
		{ AfterStoreSurplus(); }
	}//End for
}
示例#14
0
bool AdaptSurfaceGridToCylinder(Selector& selOut, Grid& grid,
                                Vertex* vrtCenter, const vector3& normal,
                                number radius, number rimSnapThreshold,  AInt& aInt,
                                APosition& aPos)
{
    if(!grid.has_vertex_attachment(aPos)) {
        UG_THROW("Position attachment required!");
    }

    Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);

    if(rimSnapThreshold < 0)
        rimSnapThreshold = 0;

    if(rimSnapThreshold > (radius - SMALL))
        rimSnapThreshold = radius - SMALL;

    const number smallRadius = radius - rimSnapThreshold;
    const number smallRadiusSq = smallRadius * smallRadius;
    const number largeRadius = radius + rimSnapThreshold;
    const number largeRadiusSq = largeRadius * largeRadius;

//	the cylinder geometry
    vector3 axis;
    VecNormalize(axis, normal);
    vector3 center = aaPos[vrtCenter];

//	recursively select all vertices in the cylinder which can be reached from a
//	selected vertex by following an edge. Start with the given one.
//	We'll also select edges which connect inner with outer vertices. Note that
//	some vertices are considered rim-vertices (those with a distance between
//	smallRadius and largeRadius). Those are neither considered inner nor outer.
    Selector& sel = selOut;
    sel.clear();
    sel.select(vrtCenter);

    stack<Vertex*> vrtStack;
    vrtStack.push(vrtCenter);

    Grid::edge_traits::secure_container edges;
    Grid::face_traits::secure_container faces;
    vector<Quadrilateral*> quads;

    while(!vrtStack.empty()) {
        Vertex* curVrt = vrtStack.top();
        vrtStack.pop();

        //	we have to convert associated quadrilaterals to triangles.
        //	Be careful not to alter the array of associated elements while we iterate
        //	over it...
        quads.clear();
        grid.associated_elements(faces, curVrt);
        for(size_t i = 0; i < faces.size(); ++i) {
            if(faces[i]->num_vertices() == 4) {
                Quadrilateral* q = dynamic_cast<Quadrilateral*>(faces[i]);
                if(q)
                    quads.push_back(q);
            }
        }

        for(size_t i = 0; i < quads.size(); ++i) {
            Triangulate(grid, quads[i], &aaPos);
        }

        //	now check whether edges leave the cylinder and mark them accordingly.
        //	Perform projection of vertices to the cylinder rim for vertices which
        //	lie in the threshold area.
        grid.associated_elements(edges, curVrt);

        for(size_t i_edge = 0; i_edge < edges.size(); ++i_edge) {
            Edge* e = edges[i_edge];
            Vertex* vrt = GetConnectedVertex(e, curVrt);

            if(sel.is_selected(vrt))
                continue;

            vector3 p = aaPos[vrt];
            vector3 proj;
            ProjectPointToRay(proj, p, center, axis);
            number distSq = VecDistanceSq(p, proj);

            if(distSq < smallRadiusSq) {
                sel.select(vrt);
                vrtStack.push(vrt);
            }
            else if(distSq < largeRadiusSq) {
                sel.select(vrt);
                //	cut the ray from center through p with the cylinder hull to calculate
                //	the new position of vrt.
                vector3 dir;
                VecSubtract(dir, p, center);
                number t0, t1;
                if(RayCylinderIntersection(t0, t1, center, dir, center, axis, radius))
                    VecScaleAdd(aaPos[vrt], 1., center, t1, dir);
            }
            else {
                //	the edge will be refined later on
                sel.select(e);
            }
        }
    }

//	refine selected edges and use a special refinement callback, which places
//	new vertices on edges which intersect a cylinder on the cylinders hull.
    CylinderCutProjector refCallback(MakeGeometry3d(grid, aPos),
                                     center, axis, radius);
    Refine(grid, sel, aInt, &refCallback);

//	finally select all triangles which lie in the cylinder
    sel.clear();
    vrtStack.push(vrtCenter);
    sel.select(vrtCenter);

    while(!vrtStack.empty()) {
        Vertex* curVrt = vrtStack.top();
        vrtStack.pop();
        grid.associated_elements(faces, curVrt);

        for(size_t i_face = 0; i_face < faces.size(); ++i_face) {
            Face* f = faces[i_face];
            if(sel.is_selected(f))
                continue;

            sel.select(f);

            for(size_t i = 0; i < f->num_vertices(); ++i) {
                Vertex* vrt = f->vertex(i);
                if(!sel.is_selected(vrt)) {
                    number dist = DistancePointToRay(aaPos[vrt], center, axis);
                    if(dist < (radius - SMALL)) {
                        sel.select(vrt);
                        vrtStack.push(vrt);
                    }
                }
            }
        }
    }

    sel.clear<Vertex>();

    return true;
}
示例#15
0
int Execute(int argc,char* argv[])
{
	int i;
	cmdLineString In,Out;
	cmdLineReadable Binary,Verbose,NoResetSamples,NoClipTree,Confidence,Manifold,PolygonMesh;
	cmdLineInt Depth(8),SolverDivide(8),IsoDivide(8),Refine(3);
	cmdLineInt KernelDepth;
	cmdLineFloat SamplesPerNode(1.0f),Scale(1.1f);
	char* paramNames[]=
	{
		"in","depth","out","refine","noResetSamples","noClipTree",
		"binary","solverDivide","isoDivide","scale","verbose",
		"kernelDepth","samplesPerNode","confidence","manifold","polygonMesh"
	};
	cmdLineReadable* params[]=
	{
		&In,&Depth,&Out,&Refine,&NoResetSamples,&NoClipTree,
		&Binary,&SolverDivide,&IsoDivide,&Scale,&Verbose,
		&KernelDepth,&SamplesPerNode,&Confidence,&Manifold,&PolygonMesh
	};
	int paramNum=sizeof(paramNames)/sizeof(char*);
	int commentNum=0;
	char **comments;

	comments=new char*[paramNum+7];
	for(i=0;i<paramNum+7;i++){comments[i]=new char[1024];}

	const char* Rev = "Rev: V2 ";
	const char* Date = "Date: 2006-11-09 (Thur, 09 Nov 2006) ";

	cmdLineParse(argc-1,&argv[1],paramNames,paramNum,params,0);

	if(Verbose.set){echoStdout=1;}

	DumpOutput2(comments[commentNum++],"Running Multi-Grid Octree Surface Reconstructor (degree %d). Version 3\n", Degree);
	if(In.set)				{DumpOutput2(comments[commentNum++],"\t--in %s\n",In.value);}
	if(Out.set)				{DumpOutput2(comments[commentNum++],"\t--out %s\n",Out.value);}
	if(Binary.set)			{DumpOutput2(comments[commentNum++],"\t--binary\n");}
	if(Depth.set)			{DumpOutput2(comments[commentNum++],"\t--depth %d\n",Depth.value);}
	if(SolverDivide.set)	{DumpOutput2(comments[commentNum++],"\t--solverDivide %d\n",SolverDivide.value);}
	if(IsoDivide.set)		{DumpOutput2(comments[commentNum++],"\t--isoDivide %d\n",IsoDivide.value);}
	if(Refine.set)			{DumpOutput2(comments[commentNum++],"\t--refine %d\n",Refine.value);}
	if(Scale.set)			{DumpOutput2(comments[commentNum++],"\t--scale %f\n",Scale.value);}
	if(KernelDepth.set)		{DumpOutput2(comments[commentNum++],"\t--kernelDepth %d\n",KernelDepth.value);}
	if(SamplesPerNode.set)	{DumpOutput2(comments[commentNum++],"\t--samplesPerNode %f\n",SamplesPerNode.value);}
	if(NoResetSamples.set)	{DumpOutput2(comments[commentNum++],"\t--noResetSamples\n");}
	if(NoClipTree.set)		{DumpOutput2(comments[commentNum++],"\t--noClipTree\n");}
	if(Confidence.set)		{DumpOutput2(comments[commentNum++],"\t--confidence\n");}
	if(Manifold.set)		{DumpOutput2(comments[commentNum++],"\t--manifold\n");}
	if(PolygonMesh.set)		{DumpOutput2(comments[commentNum++],"\t--polygonMesh\n");}

	double t;
	double tt=Time();
	Point3D<float> center;
	Real scale=1.0;
	Real isoValue=0;
	//////////////////////////////////
	// Fix courtesy of David Gallup //
	TreeNodeData::UseIndex = 1;     //
	//////////////////////////////////
	Octree<Degree> tree;
	PPolynomial<Degree> ReconstructionFunction=PPolynomial<Degree>::GaussianApproximation();

	center.coords[0]=center.coords[1]=center.coords[2]=0;
	if(!In.set || !Out.set)
	{
		ShowUsage(argv[0]);
		return 0;
	}
	
	TreeOctNode::SetAllocator(MEMORY_ALLOCATOR_BLOCK_SIZE);

	t=Time();
	int kernelDepth=Depth.value-2;
	if(KernelDepth.set){kernelDepth=KernelDepth.value;}

	tree.setFunctionData(ReconstructionFunction,Depth.value,0,Real(1.0)/(1<<Depth.value));
	DumpOutput("Function Data Set In: %lg\n",Time()-t);
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));
	if(kernelDepth>Depth.value){
		fprintf(stderr,"KernelDepth can't be greater than Depth: %d <= %d\n",kernelDepth,Depth.value);
		return EXIT_FAILURE;
	}


	t=Time();
#if 1
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,Confidence.set);
#else
if(Confidence.set){
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,0,1);
}
else{
	tree.setTree(In.value,Depth.value,Binary.set,kernelDepth,Real(SamplesPerNode.value),Scale.value,center,scale,!NoResetSamples.set,0,0);
}
#endif
	DumpOutput2(comments[commentNum++],"#             Tree set in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("   Tree Size: %.3f MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20));
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	if(!NoClipTree.set){
		t=Time();
		tree.ClipTree();
		DumpOutput("Tree Clipped In: %lg\n",Time()-t);
		DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
		DumpOutput("   Tree Size: %.3f MB\n",float(sizeof(TreeOctNode)*tree.tree.nodes())/(1<<20));
	}

	t=Time();
	tree.finalize1(Refine.value);
	DumpOutput("Finalized 1 In: %lg\n",Time()-t);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	t=Time();
	tree.maxMemoryUsage=0;
	tree.SetLaplacianWeights();
	DumpOutput2(comments[commentNum++],"#Laplacian Weights Set In: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	t=Time();
	tree.finalize2(Refine.value);
	DumpOutput("Finalized 2 In: %lg\n",Time()-t);
	DumpOutput("Leaves/Nodes: %d/%d\n",tree.tree.leaves(),tree.tree.nodes());
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	tree.maxMemoryUsage=0;
	t=Time();
	tree.LaplacianMatrixIteration(SolverDivide.value);
	DumpOutput2(comments[commentNum++],"# Linear System Solved In: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput("Memory Usage: %.3f MB\n",float(MemoryInfo::Usage())/(1<<20));

	CoredVectorMeshData mesh;
	tree.maxMemoryUsage=0;
	t=Time();
	isoValue=tree.GetIsoValue();
	DumpOutput("Got average in: %f\n",Time()-t);
	DumpOutput("Iso-Value: %e\n",isoValue);
	DumpOutput("Memory Usage: %.3f MB\n",float(tree.MemoryUsage()));

	t=Time();
	if(IsoDivide.value) tree.GetMCIsoTriangles( isoValue , IsoDivide.value , &mesh , 0 , 1 , Manifold.set , PolygonMesh.set );
	else                tree.GetMCIsoTriangles( isoValue ,                   &mesh , 0 , 1 , Manifold.set , PolygonMesh.set );
	if( PolygonMesh.set ) DumpOutput2(comments[commentNum++],"#         Got Polygons in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	else                  DumpOutput2(comments[commentNum++],"#        Got Triangles in: %9.1f (s), %9.1f (MB)\n",Time()-t,tree.maxMemoryUsage);
	DumpOutput2(comments[commentNum++],"#              Total Time: %9.1f (s)\n",Time()-tt);
	PlyWritePolygons(Out.value,&mesh,PLY_BINARY_NATIVE,center,scale,comments,commentNum);

	return 1;
}