/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Vector.h" #include "mg/Unit_vector.h" #include "mg/Position.h" #include "mg/Transf.h" #include "mg/Position_list.h" #include "mg/Straight.h" #include "mg/LBRep.h" #include "mg/Plane.h" #include "mg/SBRep.h" #include "mg/Tolerance.h" #include "cskernel/Blgi2d.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif using namespace std; // MGSBRep5.cpp // // Implements Surface B-Representation class MGSBRep. //Compute ratio at s of the span (s0, s1). //Ratio computation of linear case. void get_ratio2( double s0,double s1,double s, double& r0, double& r1//r0:ratio at s0 side, r1:ration at s1 side will be output. ){ r0=(s1-s)/(s1-s0); r1=1.-r0; } double cfunc(double x){ double x42=x*x; x42*=4.; return x42-x*x42; } //Ratio computation of cubic case. void get_ratio3( double s0,double s1,double s, double& r0, double& r1//r0:ratio at s0 side, r1:ration at s1 side will be output. ){ double x=(s1-s)/(s1-s0); if(x<=.5){ r0=cfunc(x); r1=1.-r0; }else{ r1=cfunc(1.-x); r0=1.-r1; } } void get_angle( const MGLBRep& tie, //tie curve of rail0 and 1. bool& is_straight_tie0, bool& is_straight_tie1, //boolian that indicates if tie's tangent vector at the start(is_straight_tie0) or //end(is_straight_tie1) point is parallel to the vector from the start point //to the end point of tie will be output. double& theta0, double& theta1 //angles between the surface's normal and the tie's principal normal //at the tie's start(theta0) or end(theta1) point will be output. ){ double s0=tie.param_s(), s1=tie.param_e(); MGUnit_vector E1=tie.eval(s1)-tie.eval(s0); //at the start of the tie. MGUnit_vector T0,N0,B0; double crvtr0,torsn0; tie.Frenet_frame(s0,T0,N0,B0,crvtr0,torsn0); // std::cout<& perimeters2 ){ const MGLBRep& peri0=*(perimeters2[0]); const MGLBRep& peri3=*(perimeters2[3]); perimeters2.assign(1,new MGLBRep); MGLBRep& peri1=*(perimeters2[1]); peri1=peri3; MGVector V0=peri0.eval(peri0.param_s(),1), V1=peri0.eval(peri0.param_e(),1); MGMatrix M; M.set_rotate(V0,V1); peri1-=peri3.start_point(); peri1*=M; peri1+=peri0.end_point(); } //Given two curves(peri0 and 1), get a curve(peri3) that is peri1's slide along peri0 //from the peri0's end point to the start point. //peri0's end point and peri1's start point must coincide. void get_peri013( MGPvector& perimeters2 ){ const MGLBRep& peri0=*(perimeters2[0]); const MGLBRep& peri1=*(perimeters2[1]); perimeters2.assign(3,new MGLBRep); MGLBRep& peri3=*(perimeters2[3]); peri3=peri1; MGVector V0=peri0.eval(peri0.param_s(),1), V1=peri0.eval(peri0.param_e(),1); MGMatrix M; M.set_rotate(V1,V0); peri3-=peri1.start_point(); peri3*=M; peri3+=peri0.start_point(); } //Given two curves(peri1 and 2), get a curve(peri0) that is peri2's slide along peri1 //from the peri1's end point to the start point. //peri1's end point and peri2's end point must coincide. void get_peri120( MGPvector& perimeters2 ){ const MGLBRep& peri1=*(perimeters2[1]); const MGLBRep& peri2=*(perimeters2[2]); perimeters2.assign(0,new MGLBRep); MGLBRep& peri0=*(perimeters2[0]); peri0=peri2; MGVector V0=peri1.eval(peri1.param_s(),1), V1=peri1.eval(peri1.param_e(),1); MGMatrix M; M.set_rotate(V1,V0); peri0-=peri2.end_point(); peri0*=M; peri0+=peri1.start_point(); } //Given two curves(peri2 and 3), get a curve(peri0) that is peri2's slide along peri3 //from the peri3's end point to the start point. //peri3's end point and peri2's start point must coincide. void get_peri230( MGPvector& perimeters2 ){ const MGLBRep& peri3=*(perimeters2[3]); const MGLBRep& peri2=*(perimeters2[2]); perimeters2.assign(0,new MGLBRep); MGLBRep& peri0=*(perimeters2[0]); peri0=peri2; MGVector V0=peri3.eval(peri3.param_s(),1), V1=peri3.eval(peri3.param_e(),1); MGMatrix M; M.set_rotate(V1,V0); peri0-=peri2.start_point(); peri0*=M; peri0+=peri3.start_point(); } //Generalized ruled surface construction. //Build a surface by ruled surface method. That is, costruct a surface by sliding //the blending curve(a tie curve of the rails) of perimeters 3 and 1 along //perimeter 0 and 2(0 and 2 make the rail). //Or by sliding the blending curve of perimeter 0 and 2 //along perimeter 3 and 1(3 and 1 make the rail). MGSBRep::MGSBRep( bool along_u, //indicates which perimeters make a rail. //if true, perimeter 0 and 2, if false, perimeter 3 and 1 make rail. const MGPvector& perimeters //‹«ŠEόƒŠƒXƒg(vmin,umax,vmax,umin‚̏‡,•Σ”ԍ†0,1,2,3‚̏‡) //perimeters must be the same knot configuration along u(perimeter 0 and 2) //and along v(perimeter 3 and1). ){ const MGLBRep& peri0=*(perimeters[0]); const MGLBRep& peri1=*(perimeters[1]); const MGLBRep& peri2=*(perimeters[2]); const MGLBRep& peri3=*(perimeters[3]); int sd=peri0.sdim(); int nu=peri0.bdim(), nv=peri1.bdim(); int num1=nu-1, nvm1=nv-1; int len=nu; if(len& peris, //‹«ŠEόƒŠƒXƒg(vmin,umax,vmax,umin‚̏‡,•Σ”ԍ†0,1,2,3‚̏‡). Let i be the perimeter number, //and the data is missing, perimeter[i] must be null. If perimeter 3 data is missing, //perimeters.size() may be 3. If perimeter 2 and 3 data are missing, perimeters.size() may //be 2. //When perimeters were not the same knot configuration along u(perimeter 0 and 2) //or along v(perimeter 3 and1), they will be rebuild to have the same configuration. MGPvector& perimeters2 //new perimeters will be output. ){ int n=(int)peris.size();if(n<2) return -2; std::vector perimeters(4); int i; for(i=0; i peri2(2); if(type==10 || type==1 || type==3 || type==5){//when 0 and 2 provided. peri2[0]=perimeters[0]; peri2[1]=perimeters[2]; MGPvector lb2=rebuild_knot(peri2); perimeters2.assign(0,lb2.release(0)); perimeters2.assign(2,lb2.release(1)); } if(type==10 || type==0 || type==2 || type==8){//when 1 and 3 provided. peri2[0]=perimeters[1]; peri2[1]=perimeters[3]; MGPvector lb2=rebuild_knot(peri2); perimeters2.assign(1,lb2.release(0)); perimeters2.assign(3,lb2.release(1)); } if(type==10) return 10; //3. process when parallel two perimeters are provided. if(type==5){ perimeters2.assign(1,new MGLBRep( MGStraight(perimeters2[2]->end_point(),perimeters2[0]->end_point()))); perimeters2.assign(3,new MGLBRep( MGStraight(perimeters2[2]->start_point(),perimeters2[0]->start_point()))); return 5; } if(type==8){ perimeters2.assign(0,new MGLBRep( MGStraight(perimeters2[1]->start_point(),perimeters2[3]->start_point()))); perimeters2.assign(2,new MGLBRep( MGStraight(perimeters2[1]->end_point(),perimeters2[3]->end_point()))); return 8; } //4. approximate the perimeter that has not the opposite one. for(i=0; i<4; i++){ if(!perimeters2[i]){ if(perimeters[i]) perimeters2.assign(i,new MGLBRep(*(perimeters[i]))); } } //5. Adjust the common corner points. MGLBRep& l0=*(perimeters2[0]); MGLBRep& l1=*(perimeters2[1]); MGLBRep& l2=*(perimeters2[2]); MGLBRep& l3=*(perimeters2[3]); MGPosition P0, P1, P2, P3; if(type==1 || type==2 || type==6) P0=(l0.start_point()+l3.start_point())*.5; if(type==2 || type==3 || type==4) P1=(l0.end_point()+l1.start_point())*.5; if(type==0 || type==3 || type==7) P2=(l1.end_point()+l2.end_point())*.5; if(type==0 || type==1 || type==9) P3=(l3.end_point()+l2.start_point())*.5; double fixp[2]; if(!P0.is_null()){//P0 fixp[0]=l0.param_e(); l0.move(2,l0.param_s(),P0,fixp); fixp[0]=l3.param_e(); l3.move(2,l3.param_s(),P0,fixp); } if(!P1.is_null()){//P1 fixp[0]=l0.param_s(); l0.move(2,l0.param_e(),P1,fixp); fixp[0]=l1.param_e(); l1.move(2,l1.param_s(),P1,fixp); } if(!P2.is_null()){//P2 fixp[0]=l1.param_s(); l1.move(2,l1.param_e(),P2,fixp); fixp[0]=l2.param_s(); l2.move(2,l2.param_e(),P2,fixp); } if(!P3.is_null()){//P3 fixp[0]=l2.param_e(); l2.move(2,l2.param_s(),P3,fixp); fixp[0]=l3.param_s(); l3.move(2,l3.param_e(),P3,fixp); } //6. process when non-parallel two perimeters are provided. int type2=type; if(type==4){ get_peri013(perimeters2);type2=2; }else if(type==6){ get_peri031(perimeters2);type2=2; }else if(type==7){ get_peri120(perimeters2);type2=3; }else if(type==9){ get_peri230(perimeters2);type2=1; } //std::cout<