/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Position_list.h" #include "mg/CSisect_list.h" #include "mg/SSisect_list.h" #include "mg/Matrix.h" #include "mg/Straight.h" #include "mg/Ellipse.h" #include "mg/RLBRep.h" #include "mg/SurfCurve.h" #include "mg/BSumCurve.h" #include "mg/Plane.h" #include "mg/SPhere.h" #include "mg/Cylinder.h" #include "mg/SBRep.h" #include "mg/RSBRep.h" #include "mg/BSumSurf.h" #include "mg/Tolerance.h" #include "cskernel/Bluprt.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif using namespace std; //***************************************************************/ //* All rights reserved. */ //***************************************************************/ // Implements MGRSBRep Class // // Defines Rational Surface B-Representation. // This NURBS is of homogeneous form, i.e., B-Coefficients have // weight included values. // When usual NURBS form is (xij, yij, zij, wij) , // MGRSBRep form is (xij*wij, yij*wij, zij*wij, wij) // for i=0,..., m-1, and j=0,..., n-1. //******** Intersection implementation ******* // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGCurve& curve)const{ return curve.isect(*this); } // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGRLBRep& curve)const{ return curve.isect(*this); } // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGEllipse& curve)const{ return curve.isect(*this); } // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGLBRep& curve)const{ return curve.isect(*this); } // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGSurfCurve& curve)const{ return curve.isect(*this); } // Surface と Curve の交点を求める。 MGCSisect_list MGRSBRep::isect(const MGBSumCurve& curve)const{ return curve.isect(*this); } // Surface と Surface の交線を求める。 //Compute intesection of Sphere and Surface. MGSSisect_list MGRSBRep::isect(const MGSurface& srf2) const{ MGSSisect_list list=srf2.isect(*this); list.replace12(); return list; } MGSSisect_list MGRSBRep::isect(const MGPlane& srf2) const{ return intersectPl(srf2); } MGSSisect_list MGRSBRep::isect(const MGSphere& srf2) const{ return intersect(srf2); } MGSSisect_list MGRSBRep::isect(const MGCylinder& srf2) const{ return intersect(srf2); } MGSSisect_list MGRSBRep::isect(const MGSBRep& srf2) const{ return intersect(srf2); } MGSSisect_list MGRSBRep::isect(const MGRSBRep& srf2) const{ return intersect(srf2); } MGSSisect_list MGRSBRep::isect(const MGBSumSurf& srf2) const{ return intersect(srf2); } //The following two function will be used in perps or isect //to decide how many division of the surface along u or v direction //should be applied before using perp_guess or isect_guess. int MGRSBRep::intersect_dnum_u() const{ return (bdim_u()+2-order_u())*order_u(); } int MGRSBRep::intersect_dnum_v() const{ return (bdim_v()+2-order_v())*order_v(); } //"isect_incr_pline" is a dedicated function of isect_start_incr, will get // shortest parameter line necessary to compute intersection. MGCurve* MGRSBRep::isect_incr_pline( const MGPosition& uv, //last intersection point. int kdt, //Input if u=const v-parameter line or not. // true:u=const, false:v=const. double du, double dv,//Incremental parameter length. double& u, //next u value will be output double& v, //next v value will be output int incr //Invremental id value of B-coef's. )const{ MGRLBRep* rlb=new MGRLBRep; m_surface.isect_incr_pline2(uv,kdt,du,dv,u,v,incr,rlb->homogeneous()); return rlb; } //Return order of intersection line order of MGLBRep. int MGRSBRep::isect_order() const{ int ku=order_u(), kv=order_v(); if(ku(copy_surface()); (*sf2D)-=PN; (*sf2D)*=mat; //std::cout<<(*sf2D);//////////// sf2D->change_dimension(2); //sf2D is the 2D surface that is transformed from the original this //surface so that the straight line sl is seen as a point of origin(0.,.0.). if(!uvbox_is_null) sf2D->limit(uvbox); //std::cout<<(*sf2D);//////////// int m=sf2D->bdim_u(), n=sf2D->bdim_v(); int mm1=m-1, nm1=n-1; MGSPointSeq sp=sf2D->surface_bcoef().non_homogeneous(); //std::cout<<(sp);//////////// MGKnotVector& tu=sf2D->knot_vector_u(); MGKnotVector& tv=sf2D->knot_vector_v(); int kum1=tu.order()-1, kvm1=tv.order()-1; for(int i=kum1; i>uv) list.append(sl.eval(t),t,uv); } } } } delete sf2D; return list; } //Test if the RSBRep is planar or not. //Returned is 0(false) if this is not planar, 1(true) if this is planar. int MGRSBRep::planar( MGPlane& plane, //Plane that might be closest to this. //plane is always output even if not planar. double& deviation //maximum deviation of this from the output plane. )const{ double u0=param_s_u(), u1=param_e_u(); double v0=param_s_v(), v1=param_e_v(); MGUnit_vector N=(normal(u0,v0)+normal(u0,v1)+normal(u1,v0)+normal(u1,v1)); MGPosition P=(eval(u0,v0)+eval(u0,v1)+eval(u1,v0)+eval(u1,v1) +eval((u0+u1)*.5,(v0+v1)*.5))/5.; plane=MGPlane(N,P); int ncdm1=sdim(); int i,j,k; // double mt[4]; for(k=0; k<=3; k++) mt[k]=mat(k,3); int m=bdim_u(), n=bdim_v(); deviation=0.; double d=P%N;//d is surface expression's d(ax+by+cz=d), of plane(P,N). for(i=0; itol) break; } if(jm_surface_bcoef; cp.resize(m,n,1); for(i=0; im_uknot=knot_vector_u(); surf->m_vknot=knot_vector_v(); return surf; } #define INCNUM 15 ///Rebuild this MGRSBRep. Rebuild means: /// Change the parameterization. std::unique_ptr MGRSBRep::rebuild( int how_rebuild, //intdicates how rebuild be done. // =0: no approximation(only parameter change) // =1: Reconstructed with new knot configuration again as rational spline(MGRSBRep). // =2: approximated by non-rational spline(MGSBRep) with new knot configuration. int parameter_normalization, //Indicates how the parameter normalization be done: //=0: no surface parameter normalization. //=1: normalize to u_range=(0., 1.), and v_range=(0.,1.); //=2: normalize to make the average length of the 1st derivative along u and v // of the base surface is as equal to 1. as possible. double tol, ///=4 is recomended. ///order[0]:u-order, [1]:v-order. ///When how_rebuild!=2, order is not used. ///When order=0 is input, order[0]=order[1]=4 are assumed. )const{ std::unique_ptr srfNew; if(how_rebuild==2){ std::unique_ptr snew=approximate_as_SBRep(parameter_normalization,tol,order); srfNew=std::unique_ptr(snew.release()); }else{ MGKnotVector uknots, vknots; get_new_surface_knots(parameter_normalization,uknots,vknots); if(how_rebuild){ //1. Rebuild surface MGRSBRep sn(surface_bcoef(),uknots,vknots); if(tol<=0.) tol=MGTolerance::line_zero(); uknots.change_knot_number(uknots.bdim()*INCNUM); vknots.change_knot_number(vknots.bdim()*INCNUM); int err; srfNew=std::unique_ptr(new MGRSBRep(sn,uknots,vknots,err)); double errSave=MGTolerance::set_line_zero(tol); srfNew->remove_knot(); MGTolerance::set_line_zero(errSave); }else{ srfNew=std::unique_ptr(new MGRSBRep(surface_bcoef(),uknots,vknots)); } } srfNew->copy_appearance(*this); return srfNew; }