// ***MGBox*** //Calculate dump size size_t MGBox::dump_size() const{ size_t len = 0; len = (sizeof sdim()); for (size_t i=0; i<sdim(); i++) { len += (m_range[i].dump_size()); } return len; }
//Obtain so transformed 1D curve expression of this curve that //f(t)={sum(xi(t)*g[i]) for i=0(x), 1(y), 2(z)}-g[3], where f(t) is the output //of oneD and xi(t) is i-th coordinate expression of this curve. //This is used to compute intersections with a plane g[4]. std::auto_ptr<MGCurve> MGRLBRep::oneD( const double g[4] //Plane expression(a,b,c,d) where ax+by+cz=d. )const{ size_t i, nbd=bdim(); size_t j, w_id=sdim(); size_t k=order(); size_t ncod=3; if(ncod>w_id) ncod=w_id; const MGBPointSeq& cf=m_line.line_bcoef(); MGLBRep* brep=new MGLBRep(); MGBPointSeq& rcoef=brep->line_bcoef(); rcoef.resize(nbd,1); MGKnotVector& knotv=brep->knot_vector(); knotv.size_change(k,nbd); double min,max; const MGKnotVector& t=knot_vector(); double rt=0.; for(j=0; j<ncod; j++) rt+=coef(0,j)*g[j]; min=max=rt-=coef(0,w_id)*g[3]; rcoef(0,0)=rt; knotv(0)=t(0); for(i=1; i<nbd; i++){ rt=0.; for(j=0; j<ncod; j++) rt+=coef(i,j)*g[j]; rcoef(i,0)=rt-=coef(i,w_id)*g[3]; knotv(i)=t(i); if(min>rt) min=rt; if(max<rt) max=rt; } size_t npk=nbd+k; for(i=nbd; i<npk; i++) knotv(i)=t(i); MGInterval minmax(min,max); m_box=new MGBox(1,&minmax); return std::auto_ptr<MGCurve>(brep); }
//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; }
// Dump Functions int MGBox::dump(MGOfstream & buf) const{ int len = -1; try { size_t dim = sdim(); buf << dim; for(size_t i=0; i<sdim(); i++) { m_range[i].dump(buf); } len = dump_size(); } catch (...) { throw; } return len; }
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() ; }
// 論理演算子の多重定義 // 与曲線と自身が等しいかの比較判定を行う。 //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(); }
//Test if this is actually non_rational, i.e. , all of the weights are //same values. int MGRSBRep::non_rational()const{ size_t sd=sdim(); double weight=coef(0,0,sd); for(size_t i=0; i<bdim_u(); i++) for(size_t j=0; j<bdim_v(); j++) if(!MGREqual2(weight,coef(i,j,sd))) return 0; return 1; }
//Draw this line's 1st and 2nd coordinates in 2D space //using drawing function moveto( , ) and lineto( , ). //wind[] is the window of the screen to draw the line in. //Clipping will be performed about the wind[]. //(wind[0], wind[1]) is the center coordinates of the window. //wind[2] is width and wind[3] is hight of the window. When wind[2]<=0, //no clipping is performed. Even when wind[2]<=0, wind[3] is necessary //to input to specify the resolution of the line. In this case, //wind[0] and wind[1] are not referended. //ynum is the resolution of the line, is the number of //straight line segments for the curve length of wind[3](height of window). //***draw_2D does not perform box including judment, always performs clipping //operation and draws the line. Users must do obvious box inclusion test //if maximum drawing performance is necessary. void MGRLBRep::draw_all2D( int kfunc, //Kind of function move and line, //1:move(int,int), 2:move(float, float), otherwise:move(double,double). int (*moveto)(...), int (*lineto)(...), const double wind[4], //window box to draw the line in. size_t ynum)const//Resolution of the line. { unsigned n=bdim(), k=order(), wid=sdim(); const double* rcoef[3]={ rcoef[0]=m_line.m_line_bcoef.data(0,0), rcoef[1]=m_line.m_line_bcoef.data(0,1), rcoef[2]=m_line.m_line_bcoef.data(0,wid) }; const double* knotp=m_line.m_knot_vector.data(); double* work=new double[k*k+3*k]; std::vector<double> pvector; int nrw; if(wind[2]>0.){//If clipping is necessary. double xwin[2], ywin[2]; double xw=wind[2], yw=wind[3]; double error=MGTolerance::rc_zero(); double xerror=xw*error, yerror=yw*error; xw*=0.5; yw*=0.5; xwin[0]=wind[0]-xw+xerror; xwin[1]=wind[0]+xw-xerror; ywin[0]=wind[1]-yw+yerror; ywin[1]=wind[1]+yw-yerror; if(kfunc==1){ xwin[0]+=0.6; xwin[1]-=0.6; ywin[0]+=0.6; ywin[1]-=0.6;} //xwin[] , ywin[] are window coordinates. MGVector P=start_point(); if(xwin[0]<=P[0] && P[0]<=xwin[1] && ywin[0]<=P[1] && P[1]<=ywin[1]) pvector.push_back(param_s()); MGCParam_list plist=isect_1D(xwin[0],0); MGCParam_list::Citerator i, ie; ie=plist.end(); for(i=plist.begin(); i!=ie; i++) pvector.push_back(*i); plist=isect_1D(xwin[1],0); ie=plist.end(); for(i=plist.begin(); i!=ie; i++) pvector.push_back(*i); plist=isect_1D(ywin[0],1); ie=plist.end(); for(i=plist.begin(); i!=ie; i++) pvector.push_back(*i); plist=isect_1D(ywin[1],1); ie=plist.end(); for(i=plist.begin(); i!=ie; i++) pvector.push_back(*i); P=end_point(); if(xwin[0]<=P[0] && P[0]<=xwin[1] && ywin[0]<=P[1] && P[1]<=ywin[1]) pvector.push_back(param_e()); //*** sort the parameter value array. std::vector<double>::iterator vi=pvector.begin(), ve=pvector.end(); std::sort(vi,ve); nrw=pvector.size(); }else{ pvector=std::vector<double>(2); pvector[0]=param_s(); pvector[1]=param_e(); nrw=2; } double* isparam=&(pvector[0]); bldrwcr_(kfunc,(S_fp)moveto,(S_fp)lineto,ynum,wind,nrw,isparam,0, k,n,knotp,rcoef,work); delete[] work; }
//Compute intersection point of 1D sub NURBS of original B-rep. //Parameter values of intersection point will be returned. MGCParam_list MGRLBRep::intersect_1D( double f, // Coordinate value size_t coordinate // Coordinate kind of the data f(from 0). )const{ assert(coordinate<sdim()); MGVector N(-1., f); //Normal of Vector(f,1.). return isect_nD(N,1,coordinate); }
//Compute intersection points of 2D sub NURBS of original B-rep. //Parameter values of this at intersection points will be returned. //Straight line sl and this(RLBRep) will be projected to 2D plane of //coordinate kind (coordinate, coordinate+1), then intersection will //be computed. MGCParam_list MGRLBRep::isect_2D( const MGStraight& sl,// Straight line. size_t coordinate // Coordinate kind of 2D sub space. )const{ assert(coordinate<sdim()); MGVector C(3,sl.nearest_to_origin(),0,coordinate); C(2)=1.; MGVector D(3,sl.direction(0.),0,coordinate); D(2)=0.; MGVector N=C*D; //Normal of Vector C and D. //I.e., normal of the plane that includes sl and passes through origin. return isect_nD(N,2,coordinate); }
//Return non_homogeneous B-Coefficients with weights of //the rational B-Spline. This MGSPointSeq includes weights. MGSPointSeq MGRSBRep::non_homogeneous_bcoef() const{ size_t i,j,r, sd=sdim(), m=bdim_u(), n=bdim_v(); MGSPointSeq cp(m,n,sd+1); for(i=0; i<m; i++){ for(j=0; j<n; j++){ double weight=coef(i,j,sd); for(r=0; r<sd; r++) cp(i,j,r)=coef(i,j,r)/weight; cp(i,j,sd)=weight; } } return cp; }
//Compute intersection points of 3D sub NURBS of original B-rep. //Parameter values of this at intersection points will be returned. //This(RLBRep) will be projected to 3D plane of coordinate kind //(coordinate, coordinate+1, coordinate+2), then intersection will //be computed. MGCParam_list MGRLBRep::isect_3D( const MGPlane& pl, // Plane. size_t coordinate // Coordinate kind of 3D sub space. )const{ assert(coordinate<sdim()); MGVector C(3,pl.root_point(),0,coordinate); MGVector PN(3,pl.normal(),0,coordinate); //Plane Normal. MGVector N(4,PN); N(3)=-(C%PN); //N is 4D vector that is normal to C, pl.u_deriv() and pl.v_deriv(). return isect_nD(N,3,coordinate); }
//Dump Function // Dumped Vector Dimension and each element int MGVector::dump(MGOfstream& buf) const{ int len = -1; try{ int dim = sdim(); buf<<dim; for(int i=0; i<dim; i++) buf << m_element[i]; len = dump_size(); } catch(...){ throw; } return len; }
void getDims(hid_t id, bool isDataset, std::vector<int>& dims) { hid_t space; if (!isDataset) space = H5Aget_space(id); else space = H5Dget_space(id); size_t rank = H5Sget_simple_extent_ndims(space); std::vector<hsize_t> sdim(rank); if (rank > 0) { H5Sget_simple_extent_dims(space, &sdim[0], NULL); } dims.resize(rank); for (size_t i = 0; i < rank; ++i) { dims[i] = sdim[i]; } }
void drawInventoryItem(video::IVideoDriver *driver, gui::IGUIFont *font, InventoryItem *item, core::rect<s32> rect, const core::rect<s32> *clip) { if(item == NULL) return; video::ITexture *texture = NULL; texture = item->getImage(); if(texture != NULL) { const video::SColor color(255,255,255,255); const video::SColor colors[] = {color,color,color,color}; driver->draw2DImage(texture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(texture->getOriginalSize())), clip, colors, true); } else { video::SColor bgcolor(255,50,50,128); driver->draw2DRectangle(bgcolor, rect, clip); } if(font != NULL) { std::string text = item->getText(); if(font && text != "") { v2u32 dim = font->getDimension(narrow_to_wide(text).c_str()); v2s32 sdim(dim.X,dim.Y); core::rect<s32> rect2( /*rect.UpperLeftCorner, core::dimension2d<u32>(rect.getWidth(), 15)*/ rect.LowerRightCorner - sdim, sdim ); video::SColor bgcolor(128,0,0,0); driver->draw2DRectangle(bgcolor, rect2, clip); font->draw(text.c_str(), rect2, video::SColor(255,255,255,255), false, false, clip); } } }
void VsDataset::loadDims() { hid_t space = H5Dget_space(getId()); size_t rank = H5Sget_simple_extent_ndims(space); if (rank <= 0) { VsLog::errorLog() <<"VsDataset::loadDims() - Rank was <= 0 for dataset: " << getFullName() <<std::endl; return; } std::vector<hsize_t> sdim(rank); H5Sget_simple_extent_dims(space, &sdim[0], NULL); dims.resize(rank); for (size_t i = 0; i < rank; ++i) { dims[i] = sdim[i]; } }
//Dump Function int MGMatrix::dump(MGOfstream& buf) const{ int len = 0; try{ size_t dim = sdim(); size_t mtx_len = dim*dim; buf << dim; for(size_t i=0; i<mtx_len; i++) buf<<m_matrix[i]; len = dump_size(); } catch (...){ throw; } return len; }
//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; }
//Changing this object's space dimension. MGRSBRep& MGRSBRep::change_dimension( size_t dim, // new space dimension size_t start1, // Destination order of new object. size_t start2) // Source order of this object. { size_t dim0=sdim(); MGSPointSeq cp1(dim0,surface_bcoef()); //Exclude weights. MGSPointSeq cp2(dim,cp1,start1,start2); //Change order of coordinates. MGSPointSeq cp3(dim+1,cp2); //Get area for weights. const MGSPointSeq& sp=surface_bcoef(); for(size_t i=0; i<cp3.length_u(); i++) for(size_t j=0; j<cp3.length_v(); j++) cp3(i,j,dim)=sp(i,j,dim0);//Set weights. m_surface=MGSBRep(cp3,knot_vector_u(),knot_vector_v()); update_mark(); return *this; }
//Compute intersection points of (n+1)-Dimensional sub NURBS // and (n+1)-dimension plane that passes through the origin. //(n+1)-Dimensional sub NURBS comprises from n dimension coordinate // and weight element data. //Parameter values of this at intersection points will be returned. //MGVector N is the normal vector of the plane. MGCParam_list MGRLBRep::isect_nD( const MGVector& N, // Normal of (n+1)-dimension plane. size_t dimension, // Number of dimension n. size_t coordinate // Coordinate kind of n-dimensional sub NURBS. )const{ assert(dimension<4); //Currently dimension must be up to 3. double m[4]; size_t cod[4]; size_t i,j; MGMatrix mat; mat.to_axis(N,dimension); double len=N.len(); for(j=0; j<=dimension; j++) m[j]=mat(j,dimension)*len; //Multiplication of len is to adjust the correctness(tolerance) of //the intersection computation. size_t nbd=bdim(), w_id=sdim(); size_t ncod=dimension; if(ncod>w_id) ncod=w_id; cod[0]=coordinate; for(j=1; j<ncod; j++){ cod[j]=cod[j-1]+1; if(cod[j]>=w_id) cod[j]=0; } for(j=ncod; j<dimension; j++) cod[j]=w_id+1; //To enforce retrieval of zero from m_line.line_bcoef(). MGLBRep brep; MGBPointSeq& brepcf=brep.line_bcoef(); brepcf.resize(nbd,1); brep.knot_vector()=knot_vector(); double min,max; cod[dimension]=w_id; const MGBPointSeq& cf=m_line.line_bcoef(); double x=cf(0,cod[0])*m[0]; for(j=1; j<=dimension; j++) x+=cf(0,cod[j])*m[j]; min=max=brepcf(0,0)=x; for(i=1; i<nbd; i++){ x=cf(i,cod[0])*m[0]; for(j=1; j<=dimension; j++) x +=cf(i,cod[j])*m[j]; brepcf(i,0)=x; if(x<min) min=x; if(x>max) max=x; } double error=MGTolerance::wc_zero(); if(max<-error || min>error) return MGCParam_list(); // cout<<brep<<endl; return brep.isect_1D(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; }
bool MGSBRep::operator<(const MGSBRep& gel2)const{ size_t nu1=bdim_u(), nu2=gel2.bdim_u(); if(nu1==nu2){ size_t nv1=bdim_v(), nv2=gel2.bdim_v(); if(nv1==nv2){ size_t nsd1=sdim(), nsd2=gel2.sdim(); if(nsd1==nsd2){ MGVector v1(nsd1), v2(nsd1); for(size_t i=0; i<nsd1; i++){ v1(i)=m_surface_bcoef.ref(0,0,i); v2(i)=gel2.m_surface_bcoef.ref(0,0,i); } return v1.len()<v2.len(); }else return nsd1<nsd2; }else return nv1<nv2; }else return nu1<nu2; }
// 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; }
//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 MGRSBRep::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{ size_t m; size_t dim=sdim(); MGVector result(dim); if(ndu==0 && ndv==0){ MGVector data=m_surface.eval(u,v); double weight=data.ref(dim); for(m=0; m<dim; m++) result(m)=data.ref(m)/weight; }else{ double* deriv; double deriva[27]; size_t len=dim*(ndu+1)*(ndv+1); if(len<=27) deriv=deriva; else deriv=new double[len]; eval_all(u,v,ndu,ndv,deriv); result=MGVector(dim,deriv+len-dim); if(len>27) delete[] deriv; } return result; }
//Compute position, 1st and 2nd derivatives. // パラメータ値を与えて位置、一次微分値、二次微分値をもとめる。 //Evaluate right continuous surface data. //Evaluate all positional data and 1st and 2nd derivatives. void MGRSBRep::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 dim=sdim(); size_t iid=3*dim; double data_area[27]; double* data; if(dim<=3) data=data_area; else data=new double[dim*3*3]; eval_all(u,v,2,2,data); f=MGPosition(dim,data); fu=MGVector(dim,data+iid); fv=MGVector(dim,data+dim); fuv=MGVector(dim,data+dim+iid); fuu=MGVector(dim,data+2*iid); fvv=MGVector(dim,data+2*dim); if(dim>3) delete[] data; }
//Intersection point of NURBS and straight line. MGCCisect_list MGRLBRep::isect(const MGStraight& sline) const{ MGCCisect_list list(this,&sline); if(!has_common(sline)) return list; MGCParam_list clist; double errsave=MGTolerance::wc_zero(); MGTolerance::set_wc_zero(errsave*.3);//make error smaller. if(sdim()<=2 && sline.sdim()<=2) clist=isect_2D(sline); else { MGPlane plane(sline, mgORIGIN); //The plane that includes sline and passes through the origin. clist=isect_3D(plane); } MGTolerance::set_wc_zero(errsave); //Retrieve error. MGPosition p; double t1,t2; MGCParam_list::Citerator i; for(i=clist.begin(); i!=clist.end(); i++){ t1=(*i); p=eval(t1); if(sline.on(p,t2)) list.append(MGCCisect(p,t1,t2)); } return list; }
// ***MGMatrix*** //Calculate dump size size_t MGMatrix::dump_size() const{ // !!! In stead of to USE STL Vector, BUT NOT to USE Iterator size_t len = 0; len = (sizeof sdim()) + (sizeof ref(0,0)) * sdim() * sdim(); return len; }
//Evaluate all of i'th derivative data for 0<=i<=nderiv. //Output will be put on deriv[j+i*sdim()] //for 0<=i<=nderiv and 0<=j<sdim(), i.e. //deriv[j+i*sdim()] is i-th derivative data for 0<=j<sdim(). void MGRSBRep::eval_all( double u, double v, //Parameter value to evaluate. size_t ndu, size_t ndv, //Order of Derivative along u and v direction. 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]. ) const { size_t dim=sdim(); size_t dimp1=dim+1; size_t mdu=ndu+1, mdv=ndv+1; size_t md=mdu; if(md<mdv) md=mdv; size_t idderi=mdv*dim; //deriv[r+j*dim+i*idderi] for deriv[i][j][r]. //Prepare necessary binominal coefficient data. double *bc; double bca[9]; if(md<=3) bc=bca; else bc=new double[md*md]; MGBinominal(md-1, bc); //Actually bc is an array of bc[md][md], and contains //binominal(i,j). double data_area[36];// 36=(2+1)*(2+1)*(3+1), ie ndu=2, ndv=2, dim=3. double *data; size_t data_len=dimp1*mdu*mdv; if(data_len<=36) data=data_area; else data=new double[data_len]; //Actually data is 3 dimensional array of data[mdu][mdv][dimp1], //i.e., data[r+dimp1*j+mdv*dimp1*i]=data[i][j][r]; size_t iddata=mdv*dimp1; //data[r+dimp1*j+iddata*i]=data[i][j][r]; m_surface.eval_all(u,v,ndu,ndv,data); // data[r+dimp1*j+iddata*i]=data[i][j][r] is the data of //i-th along u and j-th along v derivative // of r-th space dimension element. For r=dim, wieght. double val, weight=data[dim]; size_t r, i, j, m,n; for(r=0; r<dim; r++){ for(m=0; m<=ndu; m++){ size_t mmd=m*md; for(n=0; n<=ndv; n++){ size_t nmd=n*md; val=data[r+dimp1*n+iddata*m]; size_t id1=r+m*idderi; for(j=1; j<=n; j++) val-= bc[nmd+j]*data[dim+dimp1*j]*deriv[id1+(n-j)*dim]; size_t id2=r+n*dim; for(i=1; i<=m; i++){ val-=bc[mmd+i]*data[dim+iddata*i]*deriv[id2+(m-i)*idderi]; double val2=0.; size_t id3=r+(m-i)*idderi, id4=dim+iddata*i; for(j=1; j<=n; j++) val2+=bc[nmd+j]*data[id4+dimp1*j]*deriv[id3+(n-j)*dim]; val-=bc[mmd+i]*val2; } deriv[r+n*dim+m*idderi]=val/weight; } } } if(data_len>36) delete[] data; if(md>3) delete[] bc; }
//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; }
void drawItemStack(video::IVideoDriver *driver, gui::IGUIFont *font, const ItemStack &item, const core::rect<s32> &rect, const core::rect<s32> *clip, IGameDef *gamedef) { if(item.empty()) return; const ItemDefinition &def = item.getDefinition(gamedef->idef()); video::ITexture *texture = gamedef->idef()->getInventoryTexture(def.name, gamedef); // Draw the inventory texture if(texture != NULL) { const video::SColor color(255,255,255,255); const video::SColor colors[] = {color,color,color,color}; driver->draw2DImage(texture, rect, core::rect<s32>(core::position2d<s32>(0,0), core::dimension2di(texture->getOriginalSize())), clip, colors, true); } if(def.type == ITEM_TOOL && item.wear != 0) { // Draw a progressbar float barheight = rect.getHeight()/16; float barpad_x = rect.getWidth()/16; float barpad_y = rect.getHeight()/16; core::rect<s32> progressrect( rect.UpperLeftCorner.X + barpad_x, rect.LowerRightCorner.Y - barpad_y - barheight, rect.LowerRightCorner.X - barpad_x, rect.LowerRightCorner.Y - barpad_y); // Shrink progressrect by amount of tool damage float wear = item.wear / 65535.0; int progressmid = wear * progressrect.UpperLeftCorner.X + (1-wear) * progressrect.LowerRightCorner.X; // Compute progressbar color // wear = 0.0: green // wear = 0.5: yellow // wear = 1.0: red video::SColor color(255,255,255,255); int wear_i = MYMIN(floor(wear * 600), 511); wear_i = MYMIN(wear_i + 10, 511); if(wear_i <= 255) color.set(255, wear_i, 255, 0); else color.set(255, 255, 511-wear_i, 0); core::rect<s32> progressrect2 = progressrect; progressrect2.LowerRightCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); color = video::SColor(255,0,0,0); progressrect2 = progressrect; progressrect2.UpperLeftCorner.X = progressmid; driver->draw2DRectangle(color, progressrect2, clip); } if(font != NULL && item.count >= 2) { // Get the item count as a string std::string text = itos(item.count); v2u32 dim = font->getDimension(narrow_to_wide(text).c_str()); v2s32 sdim(dim.X,dim.Y); core::rect<s32> rect2( /*rect.UpperLeftCorner, core::dimension2d<u32>(rect.getWidth(), 15)*/ rect.LowerRightCorner - sdim, sdim ); video::SColor bgcolor(128,0,0,0); driver->draw2DRectangle(bgcolor, rect2, clip); video::SColor color(255,255,255,255); font->draw(text.c_str(), rect2, color, false, false, clip); } }