#include "MGCLStdAfx.h" #include "mg/Tolerance.h" #include "mg/KnotArray.h" #include "mg/Surface.h" #include "mg/SurfCurve.h" #include "topo/LEPoint.h" #include "topo/Edge.h" #include "topo/Loop.h" #include "topo/Face.h" #include "TL2/TL2Polyline.h" #include "TL2/TL2Face.h" /****************************************************************/ /* Copyright (c) 2017 by System fugen G.K. */ /* All rights reserved. */ /****************************************************************/ //mgTL2Polyline is a proprietry class for Face tessellation. //mgTL2Polyline holds (u,v) MGLBRep of order 2(polyline). // enum polyline_type{ // WHOLE_INNER=0, //whole points are free inner points. // START_BOUNDARY, //only start point is connected to a boundary line. // END_BOUNDARY, //only end point is connected to a boundary line. // START_END_BOUNDARY,//Only start and end points are connected to a boundary. // //Inner points except start and end are not on a boundary. // WHOLE_BOUNDARY //All of the points are on a boundary. // }; ///Construct polyline MGLBRep whose maximum edge length is square_root(maxElen2). void getXYZline_ensuring_max_edge_length( double maxElen2, ///maxElen2){ int nadd=int(sqrt(vec2/maxElen2)); double diff=(tnext-tpre)/double(nadd+1); for(int k=0; kmaxElen2){ int nadd=int(sqrt(vec2/maxElen2)); double diff=(tnext-tpre)/double(nadd+1); for(int k=0; k=maxElen21){ double diff2=diff*.5; tau.store_with_capacityCheck(j++,tpresave+diff2); } tau.store_with_capacityCheck(j++,tpre); Ppre=Pnow2; } } tpre=tnext; tau.store_with_capacityCheck(j++,tpre); Ppre=Pnow; } tau.set_length(j); MGBPointSeq& bp=uvlineOut.line_bcoef(); MGKnotVector& t=uvlineOut.knot_vector(); int nnew=tau.length(); bp.resize(nnew,2);t.size_change(2,nnew); for(j=0; jget_id(le.param(),id); } //Construct mgTL2Polyline from the straight from pvS to pvE. //The straight is guaranteed to keep the deviation from the surface //within tessellation curve error and within the maximum edge length. //The type of the boundary is set according the boundary infromation of pvS and pvE. mgTL2Polyline::mgTL2Polyline( const MGLEPoint& pvE, const MGLEPoint& pvS ){ MGPosition uv0=pvS.eval(), uv1=pvE.eval(); MGStraight sl(uv1,uv0); const mgTL2Polyline* ipoly=TL2Polyline(pvE.iterator()); const mgTL2parameter& para=ipoly->TL2param(); construct_TL2Polyline(para,sl); short id[3]; if(get_LEpointID(pvS,id)) set_startID(id); if(get_LEpointID(pvE,id)) set_endID(id); } //Compute the angle of this curves's world rep and u=const iso-parameter line world rep //at the parameter t. The parameter t is normalized value from 0.(start point) //to 1.(end point). double mgTL2Polyline::angle2Uline(double t)const{ const MGSurface& srf=TL2param().get_surface(); MGSurfCurve crvOnSrf(srf,*this); MGPosition uvt; MGVector Vcrv; double para_t=param_s(); if(t==0.){ uvt=uv_start(); Vcrv=direWorld_start(); }else{ para_t+=(param_e()-param_s())*t; uvt=eval(para_t); Vcrv=crvOnSrf.eval(para_t,1); } MGVector Vu=srf.eval(uvt,1); MGUnit_vector N=srf.unit_normal(uvt); return Vu.angle2pai(Vcrv,N); } //Compute the angle of this curves's world rep and u=const iso-parameter line world rep //at the point id i. double mgTL2Polyline::angle2Uline_at_i(int i)const{ const MGSurface& srf=TL2param().get_surface(); MGSurfCurve crvOnSrf(srf,*this); MGPosition uvt; MGVector Vcrv; double para_t=param_s(); if(i==0){ uvt=uv_start(); Vcrv=direWorld_start(); }else{ uvt=uv(i); if(i==number_of_points()-1) Vcrv=direWorld_end(); else{ para_t=param_s()+double(i); Vcrv=crvOnSrf.eval(para_t,1); } } MGVector Vu=srf.eval(uvt,1); MGUnit_vector N=srf.unit_normal(uvt); return Vu.angle2pai(Vcrv,N); } ///Construct new curve object by copying to newed area. ///User must delete this copied object by "delete". mgTL2Polyline* mgTL2Polyline::clone()const{ return new mgTL2Polyline(*this); } //Evaluate the direction at t(not normalized ordinary parameter value) in its //world representation. MGVector mgTL2Polyline::direWorld_with_non_normalized(double t)const{ const mgTL2parameter& para=TL2param(); const MGSurface& srf=para.get_surface(); MGSurfCurve crvAftOnsrf(srf,*this); return crvAftOnsrf.eval(t,1); } //Get the direction of the line in the world coordinate at the normalized parameter t. //The parameter t is normalized value from 0.(start point) to 1.(end point). MGVector mgTL2Polyline::direWorld(double t)const{ if(t == 0.) return direWorld_start(); if(t == 1.) return direWorld_end(); double s=param_s(); s=s+(param_e()-s)*t; return direWorld_with_non_normalized(s); } //Get the start or end point direction of the line in the world coordinate. const MGVector& mgTL2Polyline::direWorld_start()const{ if(m_dire_start.is_null()){ double ts=param_s(); m_dire_start=direWorld_with_non_normalized(ts); } return m_dire_start; } const MGVector& mgTL2Polyline::direWorld_end()const{ if(m_dire_end.is_null()){ double te=param_e(); m_dire_end=direWorld_with_non_normalized(te); } return m_dire_end; } //Get id of m_Bpolylines of mgTL2Face from point id of this polyline. //Function's return value is //true if the point i t is a boundary point, false if not. bool mgTL2Polyline::get_id_from_VertexID(int idVertex, short id[3])const{ int npm1=number_of_points()-1; assert(0<=idVertex && idVertex<=npm1); switch(m_type){ case WHOLE_INNER: return false; case WHOLE_BOUNDARY: for(int i=0; i<3; i++) id[i]=m_start[i]; if(m_end[2]>=m_start[2]) id[2]+=idVertex; else id[2]-=idVertex; return true; case START_BOUNDARY: if(idVertex) return false; for(int i=0; i<3; i++) id[i]=m_start[i]; return true; case END_BOUNDARY: if(idVertex==npm1){ for(int i=0; i<3; i++) id[i]=m_end[i]; return true; } return false;; case START_END_BOUNDARY: if(idVertex==0){ for(int i=0; i<3; i++) id[i]=m_start[i]; return true; }else if(idVertex==npm1){ for(int i=0; i<3; i++) id[i]=m_end[i]; return true; } } return false;; } //Get id of m_Bpolylines of mgTL2Face from the parameter t. //Function's return value is //true if the point i t is a boundary point, false if not. bool mgTL2Polyline::get_id(double t, short id[3])const{ short idt=short(t-param_s()+.5); return get_id_from_VertexID(idt,id); } void mgTL2Polyline::set_startID(const short start[3]){ for(int i=0; i<3; i++){ m_start[i]=start[i]; } if(m_type==WHOLE_INNER) m_type=START_BOUNDARY; else if(m_type==END_BOUNDARY) m_type=START_END_BOUNDARY; } void mgTL2Polyline::set_endID(const short end[3]){ for(int i=0; i<3; i++){ m_end[i]=end[i]; } if(m_type==WHOLE_INNER) m_type=END_BOUNDARY; else if(m_type==START_BOUNDARY) m_type=START_END_BOUNDARY; } void mgTL2Polyline::get_startID(short start[3]){ for(int i=0; i<3; i++){ start[i]=m_start[i]; } } void mgTL2Polyline::get_endID(short end[3]){ if(m_type==WHOLE_BOUNDARY){ end[0]=m_start[0]; end[1]=m_start[1]; end[2]=m_end[2]; }else{ for(int i=0; i<3; i++) end[i]=m_end[i]; } } ///Change direction of the line. void mgTL2Polyline::negate(){ MGLBRep::negate(); m_uv_start.set_null(); m_dire_start.set_null(); m_dire_end.set_null(); if(m_type==START_BOUNDARY) m_type=END_BOUNDARY; else if(m_type==END_BOUNDARY) m_type=START_BOUNDARY; else if(m_type==WHOLE_INNER) return; for(int i=0; i<3; i++){ short save=m_start[i]; m_start[i]=m_end[i]; m_end[i]=save; } } //Get i-th point surface parameter (u,v) of this polyline MGPosition mgTL2Polyline::uv(int i)const{ assert(i>=0 && i=0 && i& bpolyls=*(para.Bpoly()); SHLL_COM_EDGES edges=bpolyls[ids[0]]; const MGLBRep* lb=edges[ids[1]]; xyzPN.store_at(0,lb->line_bcoef()(ids[2])); }else{ xyzPN.store_at(0,srf.eval(uvi)); } //std::cout<(edg->base_curve()); } const mgTL2Polyline* TL2Polyline(MGComplex::const_pcellItr ei){ const MGEdge* edg=edge_from_iterator(ei); return TL2Polyline(edg); }