/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Box.h" #include "mg/Position.h" #include "mg/Position_list.h" #include "mg/Transf.h" #include "mg/LBRepEndC.h" #include "mg/Straight.h" #include "mg/LBRep.h" #include "mg/CParam_list.h" #include "mg/CCisect_list.h" #include "mg/CSisect_list.h" #include "mg/SSisect_list.h" #include "mg/Surface.h" #include "mg/Plane.h" #include "mg/SBRep.h" #include "mg/RSBRep.h" #include "mg/Tolerance.h" #include "topo/Face.h" #include "cskernel/Bkdnp.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif using namespace std; // Implementation of intersection of MGSurface and MGPlane. //*******Intersection.************ //Compute intersection points of perimeters of this surface and surf, and //of perimeters of surf and this surface. //These intersection points are used to compute surface to surface //intersection lines. void MGFSurface::intersect12Boundary( const MGFSurface& sf2, //The second surface. MGPosition_list& uvuv_list //The intersection points will be output. //One member of uvuv_list is (u1,v1,u2,v2), where (u1,v1) is //a parameter of this surface and (u2,v2) is a parameter of //surf. )const{ double error=MGTolerance::set_wc_zero(MGTolerance::line_zero()*.5); //Save the error. int numi1=isect_boundary(sf2,uvuv_list,0); //std::cout<2){ //Sort the ip's. int id=0; if(numi1>numi2) id=2; uvuv_list.sort_uv_space(id); } return; } //isect_startPlanePt compute an array of parameter value pairs of this surf and pl2 //for one intersection line of a surface and a plane, // given starting intersetion point uvuv((u1,v1) of this and (u2,v2) of pl2) // and direction in uvuv_startI(4-6) (optionally). //isect_startPlanePt is a dedicated function for isect_startPlane. //isect_startPlanePt halts the computation when intersection //reached to a boundary of this, or reached to one of the points //in uvuv_list. //The function's return value is: // =0: Intersection was not obtained. // !=0: Intersection was obtained as follows: // =1: End point is a point on a perimeter of this surfaces. // =3: End point is one of boundary points in uvuv_list. // =4: End point is the starting point. // =7: isect_startPlanePt halted the computation since intersection was lost // during the computation. int MGFSurface::isect_startPlanePt( const MGPosition& uvuv_startIn, //Starting point of the intersection line. MGPosition_list& uvuv_list, //isect_startPlanePt will halt when ip reached one of //the point in uvuv_list. isect_startPlanePt does not change uvuv_list(actually //uvuv_list is const.) uvuv's space dimension is at least 4, //and the first 2 is (u,v) of this and the next 2 is (u,v) of pl2. const MGPlane& pl2, //2nd surface(MGPlane). double acuRatio,//Accurate ratio, should be decreased by multiplyng .2 //(or a number less than 1.). MGBPointSeq& point, //Surface-surface intersection parameter values //will be returned as:point(.,0) and point(.,1) for(u,v) of this surface //point(.,2) and point(.,3) for(u,v) of pl2. //point will have the dimension of(.,7). MGPosition_list::iterator& uvuv_id //When the end point of ip was one of the points of uvuv_list, //uvuv_list's iterator of the point will be returned, that is, //when the function's return value was 3. //When was not a point of uvuv_list, end() of uvuv_list will be //returned. )const{ //std::cout<<"isect_startPlanePt uvuv_startIn="< .001) tol=.001; double tTol[4]={ tol*knot_vector_u().param_span(), tol*knot_vector_v().param_span(), tol*pl2.u_deriv().len(), tol*pl2.v_deriv().len() }, tTolNow[4]; //tTol is the box tolerance to //terminate the marching. if a point in uvuv_list is within this //tolerance of current intersection point, the marching will be //terminated. MGPosition uvuv_start(4,uvuv_startIn), uvuv_now(4); MGPosition uv1i(2,uvuv_start,0,0); MGPosition uv2i(2,uvuv_start,0,2); MGPosition_list::iterator uvuvi=uvuv_list.begin(), uvuve=uvuv_list.end(); uvuv_id=uvuve;//Initialize the return value of uvuv_id. //Get maximum dt to not pass too far. double dt_max=-1.; for(;uvuvi!=uvuve; uvuvi++){ double uvlen=(uv1i-MGPosition(2,*uvuvi)).len(); if(dt_max<0. || dt_max>uvlen) dt_max=uvlen; } dt_max/=4.; //Define initial parameter direction. int kdt,kdt2;; //When kdt=1: dt=u-value(isect of u=const parameter line) // kdt=0: dt=v-value(isect of v=const parameter line) double du,dv, du3,dv3; //////////Check too short intersection line./////////// if(uvuv_list.size()){ MGPosition& uvuvend2=uvuv_list.front(); double u0=uvuv_start[0], v0=uvuv_start[1]; isect_dt(u0,v0,du,dv,acuRatio); double du2=uvuvend2[0]-u0, dv2=uvuvend2[1]-v0; if(fabs(du2)0. && dt_maxmaxdivt) divt=maxdivt; double dt=dtsave*divt;//dtsave is always plus. if(kdt){if(du<0.) du=-dt;else du=dt;} else{if(dv<0.) dv=-dt;else dv=dt;} isect_start_incr(pl2,uvuv_pre,kdt,du,dv,0,uvuv_now); point.store_at(i,uvuv_now,0,0,4); point.store_at(i,pl2.eval(uvuv_now[2],uvuv_now[3]),4,0,3); //std::cout<<"n="<n) k=n; MGKnotVector t(tau,k); //std::cout<