Example #1
0
//Evaluate right continuous ndu'th and ndv'th derivative data.
//Function's return value is (d(ndu+ndv)f(u,v))/(du**ndu*dv**ndv).
// ndu=0 and ndv=0 means positional data evaluation.
MGVector MGSBRep::eval(
	double u, double v,	// Parameter value of the surface.
	size_t ndu,			// Order of Derivative along u.
	size_t ndv			// Order of Derivative along v.
	) const
{
	const unsigned ku=order_u(), kv=order_v();
	double cu[10],cv[10];
	double *cup=cu, *cvp=cv;
	if(ku>10) cup=new double[ku];	//This is done to save "new" when ku<=10.
	if(kv>10) cvp=new double[kv];	//This is done to save "new" when kv<=10.
	const int num1=bdim_u()-1, nvm1=bdim_v()-1;
	int idu=m_uknot.eval_coef(u,cup,ndu);
	int idv=m_vknot.eval_coef(v,cvp,ndv);
	size_t i,j,m; int jj;
	const size_t ncd=sdim();
	MGVector S(ncd); double coefall,coefu;
	for(m=0; m<ncd; m++){
		coefall=0.;
		for(j=0;j<kv;j++){
			coefu=0.;
			jj=idv+j;
			for(i=0;i<ku;i++) coefu=coefu+coef(idu+i,jj,m)*cup[i];
			coefall=coefall+coefu*cvp[j];
		}
		S.set(m)=coefall;
	}
	if(ku>10) delete[] cup; if(kv>10) delete[] cvp;
	return S;
}
Example #2
0
// 論理演算子の多重定義
// 与曲線と自身が等しいかの比較判定を行う。
//RSB and SB comparison.
bool MGRSBRep::operator==(const MGSBRep& sb)const{
	if(sdim()!=sb.sdim())
		return 0;//Check of space dimension.
	if(order_u()!=sb.order_u())
		return 0;	//Check of order.
	if(order_v()!=sb.order_v())
		return 0;	//Check of order.

	size_t bdu=bdim_u(), bdv=bdim_v();
	if(bdu!=sb.bdim_u())
		return 0;		//Check of B-Rep dimension.
	if(bdv!=sb.bdim_v())
		return 0;		//Check of B-Rep dimension.
	if(bdu<=0 && bdv<=0)
		return 1;
	if(!non_rational())
		return 0;		//Check of rationality.
	if(knot_vector_u() != sb.knot_vector_u())
		return 0;//Check of knot vector.
	if(knot_vector_v() != sb.knot_vector_v())
		return 0;//Check of knot vector.

	//Finally, check of control polygon.
	return m_surface.surface_bcoef().non_homogeneous()==sb.surface_bcoef();
}
Example #3
0
MGSBRep& MGSBRep::refine(					//BSUNK
	const MGKnotVector& uknot,	// knot of u-direction
	const MGKnotVector& vknot)	// knot of v-direction
//Change an original B-Rep to new one with subdivided knot configuration.
//Knots t must be subdivided knots.
{
	int refine_kind;
	if(uknot!=m_uknot){
		if(vknot!=m_vknot) refine_kind=3;
		else               refine_kind=1;
	}else if(vknot!=m_vknot) refine_kind=2;
	else               return *this;
	// refine_kind=1:u-knot only, =2:v-knot only, =3:both u and v-knot. 

	unsigned ku=order_u(); size_t lud=bdim_u();
	unsigned kv=order_v(); size_t lvd=bdim_v();
	size_t is1,is2; surface_bcoef().capacity(is1,is2);
	size_t lud2=uknot.bdim(), lvd2=vknot.bdim();
	MGSPointSeq bcoef(lud2,lvd2,3);
	unsigned k=ku; if(k<kv) k=kv;
	double* work1=new double[k*k];
	double* work2=new double[lvd2*2];
	bsunk_(refine_kind,ku,lud,knot_data_u(),kv,lvd,knot_data_v(),coef_data(),
		is1,is2,lud2,uknot.data(),lvd2,vknot.data(),
		lud2,lvd2,work1,work2,&bcoef(0,0,0));
	delete[] work1; delete[] work2;
	m_uknot=uknot; m_vknot=vknot;
	m_surface_bcoef=bcoef;
	update_mark();
	return *this;
}
Example #4
0
bool MGRSBRep::operator==(const MGRSBRep& rsb2)const{
	size_t sd1=sdim(), sd2=rsb2.sdim();
	if(sd1!=sd2)
		return 0;
	if(order_u()!=rsb2.order_u())
		return 0;	//Check of order.
	if(order_v()!=rsb2.order_v())
		return 0;	//Check of order.
	size_t bdu1=bdim_u(), bdu2=rsb2.bdim_u();
	if(bdu1!=bdu2)
		return 0;
	size_t bdv1=bdim_v(), bdv2=rsb2.bdim_v();
	if(bdv1!=bdv2)
		return 0;
	if(bdu1<=0 && bdv1<=0)
		return 1;
	if(knot_vector_u() != rsb2.knot_vector_u())
		return 0;
	if(knot_vector_v() != rsb2.knot_vector_v())
		return 0;

	double ratio=rsb2.coef(0,0,sd2)/coef(0,0,sd1);
	//Check if weights are equal.
	for(size_t i=0; i<bdu1; i++)
	for(size_t j=0; j<bdv1; j++)
		if(!MGREqual2(ratio,rsb2.coef(i,j,sd2)/coef(i,j,sd1)))
			return 0;

	return m_surface.surface_bcoef().non_homogeneous()
			==rsb2.m_surface.surface_bcoef().non_homogeneous() ;
}
Example #5
0
int MGSBRep::reduce(		//BSUDEC
	int is_u,		//if true, reduce b-rep dimension of u-direction.
	int ndec)		//Number of B-rep dimension to decrease 
//Change the B-Rep by decreasing B-Rep dimension by ndec. This is
//an approximation of the original B-Rep. Return value is error flag.
{
	assert(ndec>=0);
	if(is_u) assert(bdim_u()-ndec>=order_u());
	else 	 assert(bdim_v()-ndec>=order_v());

	if(ndec<=0) return 0;

	size_t kdec=2; if(is_u) kdec=1;
	unsigned ku=order_u(); size_t lud=bdim_u();
	unsigned kv=order_v(); size_t lvd=bdim_v();
	unsigned maxlen=lud; if(maxlen<lvd) maxlen=lvd;
	size_t is1,is2; surface_bcoef().capacity(is1,is2);
	int lud2, lvd2;
	MGKnotVector tu(ku,lud), tv(kv,lvd);
	MGSPointSeq bcoef(lud,lvd,3);
	int iflag;
	unsigned k=ku; if(k<kv) k=kv;
	double* work1=new double[maxlen*(2*k-1)];
	double* work2=new double[maxlen];
	double* work3=new double[lvd*2];
	bsudec_(
		ku,lud,knot_data_u(),kv,lvd,knot_data_v(),coef_data(),
		kdec,ndec,is1,is2,lud,lvd,work1,work2,work3,
		&lud2,&tu(0),&lvd2,&tv(0),&bcoef(0,0,0),&iflag);
	if(iflag==1){
		tu.set_bdim(lud2); tv.set_bdim(lvd2);
		m_uknot=tu; m_vknot=tv;
		bcoef.set_length(lud2,lvd2);
		m_surface_bcoef=bcoef;
		iflag=0;
	}
	delete[] work1; delete[] work2; delete[] work3;
	update_mark();
	return iflag;
}
Example #6
0
//Evaluate right continuous surface data.
//Evaluate all positional data, 1st and 2nd derivatives.
void MGSBRep::eval_all(
		double u, double v,	// Parameter value of the surface.
		MGPosition& f,			// Positional data.
		MGVector&   fu,			// df(u,v)/du
		MGVector&   fv,			// df/dv
		MGVector&   fuv,		// d**2f/(du*dv)
		MGVector&   fuu,		// d**2f/(du**2)
		MGVector&   fvv			// d**2f/(dv**2)
		) const
{
	size_t ku=order_u(), kv=order_v(); 
	size_t ku2=ku+ku, kv2=kv+kv;
	double *ucoef=new double[ku*3], *vcoef=new double[kv*3];
	int bdum1=bdim_u()-1, bdvm1=bdim_v()-1;
	int uid=m_uknot.eval_coef(u,ucoef,0);
	int vid=m_vknot.eval_coef(v,vcoef,0);
	m_uknot.eval_coef(u,ucoef+ku,1); m_uknot.eval_coef(u,ucoef+ku2,2);
	m_vknot.eval_coef(v,vcoef+kv,1); m_vknot.eval_coef(v,vcoef+kv2,2);
	double s,su,suu,c,vj,vj1; size_t i,j,k,dim=sdim();
	int ii,jj;
	MGPosition p(dim);
	MGVector pu(dim),pv(dim),puv(dim),puu(dim),pvv(dim);
	for(k=0; k<dim; k++){
		p(k)=0.0;pu.set(k)=0.0;pv.set(k)=0.0;puv.set(k)=0.0;
		puu.set(k)=0.0;pvv.set(k)=0.0;
		for(j=0; j<kv; j++){
			s=su=suu=0.0;
			jj=vid+j;
			for(i=0; i<ku; i++){
				ii=uid+i;
				c=coef(ii,jj,k);
				s=s+ucoef[i]*c;
				su=su+ucoef[i+ku]*c;
				suu=suu+ucoef[i+ku2]*c;
			}
			vj=vcoef[j]; vj1=vcoef[j+kv];
			p(k)=p(k)+vj*s;
			pu.set(k)=pu.ref(k)+vj*su;
			pv.set(k)=pv.ref(k)+vj1*s;
			puv.set(k)=puv.ref(k)+vj1*su;
			puu.set(k)=puu.ref(k)+vj*suu;
			pvv.set(k)=pvv.ref(k)+vcoef[j+kv2]*s;
		}
	}
	f=p;fu=pu;fv=pv;fuv=puv;fuu=puu;fvv=pvv;
	delete[] ucoef; delete[] vcoef;
}
Example #7
0
//Evaluate all of derivative data (d(i+j)f(u,v))/(du**i*dv**j),
//for 0<=i<=ndu and 0<=j<=ndv.
void MGSBRep::eval_all(
		double u, double v,	// Parameter value of the surface.
		size_t ndu,		//Order of Derivative along u.
		size_t ndv,		//Order of Derivative along v.
		double* deriv	//Output. (d(i+j)f(u,v))/(du**i*dv**j) in
						//deriv[r+j*dim+i*(ndv+1)*dim] for 0<=r<dim=sdim().
						//for 0<=i<=ndu and 0<=j<=ndv.
	//deriv is an array of deriv[ndu+1][ndv+1][r],
	//(d(i+j)f(u,v))/(du**i*dv**j) is returned in deriv[i][j][r].
	) const{
	size_t i,j,jj,r, dim=sdim();
	size_t ider,jder;
	const unsigned ku=order_u(), kv=order_v();
	size_t kundu=ku*(ndu+1), kvndv=kv*(ndv+1);
	double cu[30],cv[30]; double *cup=cu, *cvp=cv;
	if(kundu>30) cup=new double[kundu];	//Done to save "new".
	if(kvndv>30) cvp=new double[kvndv];	//Done to save "new".
	int idu,idv;
	for(ider=0; ider<=ndu; ider++) idu=m_uknot.eval_coef(u,cup+ider*ku,ider);
	for(jder=0; jder<=ndv; jder++) idv=m_vknot.eval_coef(v,cvp+jder*kv,jder);

	double coefall,coefu;
	for(ider=0; ider<=ndu;ider++){
		size_t iderndv1dim=ider*(ndv+1)*dim;
		for(jder=0; jder<=ndv; jder++){
			size_t jderdim=jder*dim;
			for(r=0; r<dim; r++){
				coefall=0.;
				for(j=0;j<kv;j++){
					coefu=0.;
					jj=idv+j;
					for(i=0;i<ku;i++)
						coefu=coefu+coef(idu+i,jj,r)*cup[i+ider*ku];
					coefall=coefall+coefu*cvp[j+jder*kv];
				}
				deriv[r+jderdim+iderndv1dim]=coefall;
			}	
		}
	}

	if(kundu>30) delete[] cup;
	if(kvndv>30) delete[] cvp;
}
Example #8
0
// Compute parameter line.
MGLBRep MGSBRep::parameter_line(
	int is_u		//Indicates x is u-value if is_u is true.
	, double x		//Parameter value.
					//The value is u or v according to is_u.
	, unsigned nderiv		//Order of derivative.
)const{
	unsigned ku=order_u(); size_t lud=bdim_u();
	unsigned kv=order_v(); size_t lvd=bdim_v();
	size_t is1,is2; surface_bcoef().capacity(is1,is2);
	size_t ncd=sdim(), len;
	int kx;	int k;
	if(is_u){ kx=1; len=lvd; k=kv; }
	else    { kx=0; len=lud; k=ku; }
	MGLBRep lb(len,k,ncd);
	MGBPointSeq& rcoef=lb.line_bcoef();
	MGKnotVector& t=lb.knot_vector();
	int n;
	bsepl_(ku,lud,knot_data_u(),kv,lvd,knot_data_v(),coef_data(),
		is1,is2,ncd,kx,x,nderiv,len,&k,&n,&t(0),&rcoef(0,0));
	return lb;
}
Example #9
0
//Modify the original Surface by extrapolating the specified perimeter.
//The extrapolation is C2 continuous if the order >=4.
//The extrapolation is done so that extrapolating length is "length"
//at the position of the parameter value "param" of the perimeter.
MGRSBRep& MGRSBRep::extend(
	int perimeter,	//perimeter number of the Surface.
					// =0:v=min, =1:u=max, =2:v=max, =3:u=min.
	double param,	// parameter value of above perimeter.
	double length,	//chord length to extend at the parameter param of the perimeter.
	double dk){  //Coefficient of how curvature should vary at
//    extrapolation start point. When dk=0, curvature keeps same, i.e.
//    dK/dS=0. When dk=1, curvature becomes zero at length extrapolated point,
//    i.e. dK/dS=-K/length at extrapolation start point.
//    (S=parameter of arc length, K=Curvature at start point)
//    That is, when dk reaches to 1 from 0, curve changes to flat.

	assert(sdim()<=3);
	assert(perimeter>=0 && perimeter<4);
	
	const size_t ncd=surface_bcoef().sdim();
	int at_start=1;//starting perimeter
	size_t nu, nv;
	size_t order; size_t n,m; MGKnotVector* t;
	if(perimeter==1 || perimeter==3){	// Extrapolate to u-direction
		order=order_u();
		n=bdim_u();
		t=&(knot_vector_u());
		if(perimeter==1)
			at_start=0;//ending perimeter
		m=nv=bdim_v();
	}else{
		// Extrapolate to v-direction
		order=order_v();
		n=bdim_v();
		t=&(knot_vector_v());
		if(perimeter==2)
			at_start=0;//ending perimeter
		m=nu=bdim_u();
	}
	//(nu,nv) are new surface B-Rep dimensions of u and v.
	//(order,n,t) is line B-rep to extrapolate.
	//m is the number of line B-reps to extrapolate.

	MGSPointSeq surf;
	MGRLBRep lbtemp;
	MGKnotVector& t1=lbtemp.knot_vector();
	MGBPointSeq& coeftemp=lbtemp.line_bcoef();
	coeftemp.resize(n,ncd);
	double tse;
	if(at_start)
		tse=t->param_s();
	else
		tse=t->param_e();

	MGPosition uv=perimeter_uv(perimeter,param);//Surface parameter value of param.
	size_t ndu=0,ndv=0;
	if(perimeter==0 || perimeter==2) ndv=1;
	else                             ndu=1;
	double slen=length/(eval(uv,ndu,ndv)).len();

	int nnew; double firstd_len,dlen;
	for(size_t i=0; i<m; i++){
		if(perimeter==0 || perimeter==2){
			for(size_t j=0; j<n; j++)
				for(size_t k=0; k<ncd; k++) coeftemp(j,k)=coef(i,j,k);
		}else{
			for(size_t j=0; j<n; j++)
				for(size_t k=0; k<ncd; k++) coeftemp(j,k)=coef(j,i,k);
		}
		coeftemp.set_length(n);

	//Compute first derivative length at the end of the extrapolating line.
		t1=*t; 
		firstd_len=lbtemp.eval(tse,1).len();
		dlen=firstd_len*slen;
		//std::cout<<"before:"<<lbtemp<<std::endl;///////
		lbtemp.extend(at_start,dlen,dk);
		//std::cout<<"after:"<<lbtemp<<std::endl;///////
		nnew=lbtemp.bdim();
		if(perimeter==0 || perimeter==2){
			if(i==0){
				nv=nnew;
				surf.resize(nu,nv,ncd);
			}
			for(int j=0; j<nnew; j++)
				for(size_t k=0; k<ncd; k++) surf(i,j,k)=coeftemp(j,k);
		}else{
			if(i==0){
				nu=nnew;
				surf.resize(nu,nv,ncd);
			}
			for(int j=0; j<nnew; j++)
				for(size_t k=0; k<ncd; k++) surf(j,i,k)=coeftemp(j,k);
		}
	}

	*t=t1;
	surf.set_length(nu,nv);
	surface_bcoef()=surf;

	update_mark();
	return *this;
}
Example #10
0
  typename beziervolume<point_t>::array_type
  beziervolume<point_t>::ocsplit ( ) const
  {
    array_type result;

    std::size_t new_size_u = order_u() + degree_u();
    std::size_t new_size_v = order_v() + degree_v();
    std::size_t new_size_w = order_w() + degree_w();

    // generate point-meshes for different steps of split
    pointmesh3d<point_t> cpsplit_u      ( new_size_u, order_v(),  order_w() );
    pointmesh3d<point_t> cpsplit_uv     ( new_size_u, new_size_v, order_w() );
    pointmesh3d<point_t> cpsplit_uvw    ( new_size_u, new_size_v, new_size_w );

    converter<point_t> converter;

    // split in u
    for (std::size_t v = 0; v != order_v(); ++v)
    {
      for (std::size_t w = 0; w != order_w(); ++w)
      {
        // elevate to virtual nurbscurve to apply knot insertion
        std::vector<point_t> tmp_curve = _points.submesh ( 0, v, w );

        // create knot vector
        std::vector<value_type> kv_min (order_u(), 0);
        std::vector<value_type> kv_max (order_u(), 1);
        std::multiset<value_type> kv;
        kv.insert ( kv_min.begin(), kv_min.end() );
        kv.insert ( kv_max.begin(), kv_max.end() );

        converter.knot_insertion (tmp_curve, kv, order_u(), value_type(0.5));
        cpsplit_u.submesh (tmp_curve.begin(), 0, v, w);
      }
    }

    // split in v
    for (std::size_t u = 0; u != new_size_u; ++u)
    {
      for (std::size_t w = 0; w != order_w(); ++w)
      {
        // elevate to virtual nurbscurve to apply knot insertion
        std::vector<point_t> tmp_curve = cpsplit_u.submesh ( 1, u, w );

        // create knot vector
        std::vector<value_type> kv_min (order_v(), 0);
        std::vector<value_type> kv_max (order_v(), 1);
        std::multiset<value_type> kv;
        kv.insert ( kv_min.begin(), kv_min.end() );
        kv.insert ( kv_max.begin(), kv_max.end() );

        converter.knot_insertion (tmp_curve, kv, order_v(), value_type(0.5));
        cpsplit_uv.submesh (tmp_curve.begin(), 1, u, w);
      }
    }

    // split in w
    for (std::size_t u = 0; u != new_size_u; ++u)
    {
      for (std::size_t v = 0; v != new_size_v; ++v)
      {
        // elevate to virtual nurbscurve to apply knot insertion
        std::vector<point_t> tmp_curve = cpsplit_uv.submesh ( 2, u, v );

        // create knot vector
        std::vector<value_type> kv_min (order_w(), 0);
        std::vector<value_type> kv_max (order_w(), 1);
        std::multiset<value_type> kv;
        kv.insert ( kv_min.begin(), kv_min.end() );
        kv.insert ( kv_max.begin(), kv_max.end() );

        converter.knot_insertion (tmp_curve, kv, order_w(), value_type(0.5));
        cpsplit_uvw.submesh (tmp_curve.begin(), 2, u, v);
      }
    }

    // generate subvolumes
    for (std::size_t w = 0; w != 2; ++w)
    {
      for (std::size_t v = 0; v != 2; ++v)
      {
        for (std::size_t u = 0; u != 2; ++u)
        {
          pointmesh3d<point_t> submesh = cpsplit_uvw.submesh(u*degree_u(), v*degree_v(), w*degree_w(), order_u(), order_v(), order_w());
          beziervolume subvolume (submesh);
          //result[array_index(u)][array_index(v)][array_index(w)] = subvolume;
          result[u][v][w] = subvolume;
        }
      }
    }

    return result;
  }
Example #11
0
 inline bool
 beziervolume<point_t>::valid ( ) const
 {
   return (_points.size() == order_u() + order_v());
 }
Example #12
0
//Test if part of the surface is planar or not within the tolerance tol.
//The part of the surface is input by the surface parameter range uvbox.
//Returned is 0(false) if this is not planar, 1(true) if planar.
int MGSBRep::planar(
	const MGBox& uvbox,//This surface parameter range.
	double tol,	//maximum deviation allowed to regard the sub surface as a plane.
	int* divideU//Direction to subdivide will be output, if this was not planar.
				//=1: u direction, =0: v direction.
	) const{
	MGBox uvb=param_range()&uvbox;
	MGPosition P; 
	MGUnit_vector N;
	int direction;
	if(!flat(uvb,tol,direction,P,N)){
		if(divideU) *divideU=direction;
		return 0;
	};

	const MGInterval& urng=uvbox[0];
	double u0=urng[0].value(), u1=urng[1].value();
	const MGInterval& vrng=uvbox[1];
	double v0=vrng[0].value(), v1=vrng[1].value();
	double um=(u0+u1)*0.5, vm=(v0+v1)*0.5;
	int ncd=sdim();
	unsigned ku=order_u(), kv=order_v();
	const MGKnotVector& tv=knot_vector_v();
	int j0=tv.locate(v0)-kv+1, j1=tv.locate(v1);
		//Coef necessary for v direction part is from j0 to j1
		//(B-rep dimension is j1-j0+1).
		//Knot vector necessary is from j0 to j1+kv.
	int nunew, nvnew=j1-j0+1;

	tol*=1.1;
	size_t nu, nv, sizeu, sizev;
	surface_bcoef().length(nu, nv); surface_bcoef().capacity(sizeu, sizev);
	unsigned kmax=ku; if(kmax<kv) kmax=kv;
	double* work=new double[kmax*kmax];

	MGSPointSeq surf1(nvnew, nu, ncd); size_t irc=nvnew*nu;
	int nmax=nu; if(nmax<nvnew) nmax=nvnew;
	int nvncd=nvnew; if(nvncd<ncd) nvncd=ncd;
	MGBPointSeq temp(nmax,nvncd);
	MGKnotVector t(kmax, nmax);
	double* tpointer=t.data(); double* temppointer=temp.data();

	for(int k=0; k<ncd; k++){
		double Pk=P[k];
		bluprt_(ku, nu, knot_data_u(), coef_data(0,j0,k),
			sizeu,nvnew,u0,u1,nmax,work,&nunew,tpointer,temppointer,1);
		for(int i=0; i<nunew; i++) for(int j=0; j<nvnew; j++) surf1(j,i,k)=temp(i,j)-Pk;
	}
	//surf1.set_length(nvnew,nunew);cout<<surf1<<endl;//////////

	const double* tvnew=knot_data_v()+j0;
	int nvnew2;
	double x;
	int i,j;
	for(i=0; i<nunew; i++){
		bluprt_(kv,nvnew,tvnew,surf1.data(0,i,0),
			irc,ncd,v0,v1,nmax,work,&nvnew2,tpointer,temppointer,1);
		//temp.set_length(nvnew2);cout<<temp<<endl;///////////
		for(j=0; j<nvnew2; j++){
			x=0.;
			for(int k=0; k<ncd; k++)
				x-=temp(j,k)*N[k];
			if(x<0.) x=-x;
			if(x>tol) break;
		}
		if(j<nvnew2) break;
	}

	int retcode=1;
	if(i<nunew || j<nvnew2){
		if(divideU){
//		*divideU=direction;
		MGVector dfdu=eval(um,vm,1,0), dfdv=eval(um,vm,0,1);
		double ulen=dfdu.len()*(u1-u0), vlen=dfdv.len()*(v1-v0);
		if(ulen*5.<vlen) *divideU=0;
		else if(ulen>vlen*5.) *divideU=1;
		else{

		//Compute maximum deviation from the plane along u direction.
		double udevi0, udevi1, vdevi0, vdevi1;
		size_t jm=nvnew2/2;
		x=0.;
		for(int k=0; k<ncd; k++)
			x-=surf1(jm,0,k)*N[k];
		udevi0=udevi1=x;
		for(i=1; i<nunew; i++){
			x=0.;
			for(int k=0; k<ncd; k++)
				x-=surf1(jm,i,k)*N[k];
			if(x<udevi0)
				udevi0=x;
			if(x>udevi1)
				udevi1=x;
		}
		size_t im=nunew/2;
		bluprt_(kv,nvnew,tvnew,surf1.data(0,im,0),
			irc,ncd,v0,v1,nmax,work,&nvnew2,tpointer,temppointer,1);
		x=0.;
		for(int k=0; k<ncd; k++)
			x-=temp(0,k)*N[k];
		vdevi0=vdevi1=x;
		for(j=1; j<nvnew2; j++){
			x=0.;
			for(int k=0; k<ncd; k++)
				x-=temp(j,k)*N[k];
			if(x<vdevi0)
				vdevi0=x;
			if(x>vdevi1)
				vdevi1=x;
		}
		if((udevi1-udevi0)>=(vdevi1-vdevi0))
			*divideU=1;
		else
			*divideU=0;

		}

		}
		retcode=0;
	}
	delete[] work;

	return retcode;

}
Example #13
0
  void
  beziersurface::preprocess ( std::size_t   subdiv_u, 
                              std::size_t   subdiv_v )
  {
    // clear old convex hull
    _chull.clear();

    // elevate if necessary
    if (_degree_u < 2) {
      elevate_u();
    }

    if (_degree_v < 2) {
      elevate_v();
    }

    // compute parameter domain partition if necessary
    //_trimdomain.partition();

    // generate convex hull according to subdivision parameter
    pointmesh2d<point_type> cp_orig(_points.begin(), _points.end(), order_u(), order_v());
    pointmesh2d<point_type> cp_u;
    pointmesh2d<point_type> cp_uv;

    trimdomain::bbox_type domainsize = _bezierdomain;
    double umin = _bezierdomain.min[point_type::u];
    double umax = _bezierdomain.max[point_type::u];
    double vmin = _bezierdomain.min[point_type::v];
    double vmax = _bezierdomain.max[point_type::v];

    value_type range_u = umax - umin;
    value_type range_v = vmax - vmin;
    value_type step_u = range_u / value_type(subdiv_u+1);
    value_type step_v = range_v / value_type(subdiv_v+1);

    // for each row of control polygon
    for (std::size_t r = 0; r <= _degree_v; ++r)
    {
      // create knot vector
      std::vector<value_type>    hlp1(_degree_u+1, umin);
      std::vector<value_type>    hlp2(_degree_u+1, umax);

      std::multiset<value_type>  kv_u(hlp1.begin(), hlp1.end());

      kv_u.insert(hlp2.begin(), hlp2.end());

      std::vector<point_type> row = cp_orig.row(r);

      for (std::size_t i = 1; i <= subdiv_u; ++i)
      {
        converter3d conv;
        conv.knot_insertion(row, kv_u, _degree_u + 1, value_type(umin) + value_type(i) * value_type(step_u));
      }

      cp_u.add_row(row.begin(), row.end());
    }

    cp_u.transpose();

    // for each row of transposed control polygon
    for (std::size_t r = 0; r < cp_u.height(); ++r)
    {
      // create knot vector
      std::vector<value_type> hlp1(_degree_v+1, vmin);
      std::vector<value_type> hlp2(_degree_v+1, vmax);
      std::multiset<value_type> kv_v(hlp1.begin(), hlp1.end());
      kv_v.insert(hlp2.begin(), hlp2.end());

      std::vector<point_type> row = cp_u.row(r);

      for (std::size_t i = 1; i <= subdiv_v; ++i)
      {
        converter3d conv;
        conv.knot_insertion(row, kv_v,  _degree_v + 1,  value_type(vmin) + value_type(i) * value_type(step_v));
      }

      cp_uv.add_row(row.begin(), row.end());
    }

    cp_uv.transpose();

    std::vector<gpucast::math::vec4f> uv(cp_uv.width() * cp_uv.height());
    //    std::generate(uv.begin(), uv.end(), gen_uv(cp_uv.width(), cp_uv.height(),
    //					       min_u_, max_u_, min_v_, max_v_));

    // for bezier patches always 0.0 - 1.0 -> min_u, max_u, min_v, max_v are only for trimming ...
    // ... as they transform the parameter space into the original b-spline space
    std::generate(uv.begin(), uv.end(), uvgenerator<gpucast::math::vec4f> ( cp_uv.width(), 
                                                                   cp_uv.height(), 
                                                                   float(0), 
                                                                   float(1), 
                                                                   float(0), 
                                                                   float(1), 
                                                                   bit_cast<unsigned, float>(unsigned(order_u())),
                                                                   bit_cast<unsigned, float>(unsigned(order_v()))));

    std::vector<gpucast::math::vec4f> attrib(uv.size());

    pointmesh2d<gpucast::math::vec4f> cp_color (uv.begin(),  uv.end(), cp_uv.width(), cp_uv.height());
    pointmesh2d<gpucast::math::vec4f> cp_attrib(uv.begin(),  uv.end(), cp_uv.width(), cp_uv.height());

    // generate chulls for each subdivision and merge them
    for (std::size_t v = 0; v <= subdiv_v; ++v)
    {
      for (std::size_t u = 0; u <= subdiv_u; ++u)
      {
        // copy control points of submesh
        pointmesh2d<point3d>      subpat     = cp_uv.subpatch    (u * _degree_u, (u+1)*_degree_u, v * _degree_v, (v+1)*_degree_v);

        // copy 4-double texture coordinate information from submesh
        pointmesh2d<gpucast::math::vec4f>  subpat_col = cp_color.subpatch (u * _degree_u, (u+1)*_degree_u, v * _degree_v, (v+1)*_degree_v);

        // discard rational component of control points for convex hull generation
        std::vector<gpucast::math::vec3d> tmp;
        std::transform(subpat.begin(), subpat.end(), std::inserter(tmp, tmp.end()), gpucast::math::rational_to_euclid3d<point3d>());

        // generate chull for subpatch
        convex_hull tmp_ch;
        tmp_ch.set(tmp.begin(), tmp.end(), subpat_col.begin(), subpat_col.end());

        // merge chull with complete chull
        _chull.merge(tmp_ch);
      }
    }
  }