/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/SBRepVecTP.h" #include "mg/LBRep.h" #include "mg/Surface.h" #include "mg/SBRep.h" #include "mg/Interval.h" #include "mg/Position.h" #include "mg/Tolerance.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // // Implements Tangent Plane Line B-Representation. // A vector version of MGSBRepTP ////////Constructor//////// //Copy Constructor //all of the ownership of m_TP of tp2 will be //transfered to this object. MGSBRepVecTP::MGSBRepVecTP(const MGSBRepVecTP& vectp2){ MGSBRepVecTP* rhsp=const_cast(&vectp2); for(int i=0; i<4; i++){ m_TP[i].push_back(rhsp->m_TP[i]); int i2=i*2; m_to_SE[i2]=rhsp->m_to_SE[i2]; m_to_SE[i2+1]=rhsp->m_to_SE[i2+1]; m_prange[i]=rhsp->m_prange[i]; } } MGSBRepVecTP::MGSBRepVecTP(const MGSBRepTP& tp2){ for(int i=0; i<4; i++){ if(!(tp2.specified(i))) continue; m_TP[i].push_back(new MGLBRep(tp2.TP(i))); m_prange[i]=MGInterval(tp2.TP(i).param_range()); m_to_SE[i*2]=m_to_SE[i*2+1]=true; } } //Assignment. //all of the ownership of m_TP of tp2 will be //transfered to this object. MGSBRepVecTP& MGSBRepVecTP::operator=(const MGSBRepVecTP& vectp2){ MGSBRepVecTP* rhsp=const_cast(&vectp2); for(int i=0; i<4; i++){ m_TP[i].clear(); if(vectp2.specified(i)) m_TP[i].push_back(rhsp->m_TP[i]); int i2=i*2; m_to_SE[i2]=rhsp->m_to_SE[i2]; m_to_SE[i2+1]=rhsp->m_to_SE[i2+1]; m_prange[i]=rhsp->m_prange[i]; } return *this; } //////////////// Member Function /////////////////////// //change the parameter range to [t0,t1] if t0& tpvecm=m_TP[j]; size_t i,n=tpvecm.size(); for(i=0; it1) tpvecm.reverse_sequence(); } m_prange[j].change_range(t0,t1); } void MGSBRepVecTP::change_range( bool along_u, //the objective range is along u parameter or v. const MGInterval& prange ){ change_range(along_u,prange[0].value(), prange[1].value()); } //evaluate TP at the perimeter i's parameter t. //Function's return value is: //true if t was inside the parameter range of a tangent plane of m_TP[i]. //false if t was outside the parameter range of the m_TP[i] for all i. bool MGSBRepVecTP::eval( int i, //perimeter numeber. double t, //parameter vaule of perimeter i. MGVector& normal//evaluated normal will be returned. )const{ if(!(m_prange[i].includes(t))) return false; size_t n=m_TP[i].size(); for(size_t j=0; jTP(i)(t) for i=0,1,2,3, where t is a common // parameter of the data point obtained from deris[i]'s knot vector. //Function's return value is the max out of cosmax[.]. double MGSBRepVecTP::get_perimeters_max_cos( const MGPvector& deris, double taumax[4], double cosmax[4] )const{ assert(deris.size() == 4); MGVector N(3), T(3); MGNDDArray tau; double max=0.; for(int i = 0; i < 4; i++){ if(!specified(i)){ taumax[i] = deris[i]->param_s(); cosmax[i] = 0.; continue; } tau.update_from_knot(deris[i]->knot_vector()); double taus=tau[0]; double cmi=0.; double tmi = taus; if(eval(i,taus,T)){ N = deris[i]->eval(taus); cmi = fabs(N.cangle(T)); tmi = taus; } int ntau=tau.length(); for(int j = 1; j < ntau; j++){ double tauj=tau[j]; double tmid = (tau[j-1]+tauj)*.5; double cm; if(eval(i,tmid,T)){ N = deris[i]->eval(tmid); cm = fabs(N.cangle(T)); if(cmieval(tauj); cm = fabs(N.cangle(T)); if(cmiTP(i)(t) for i=0,1,2,3, where perim[i] is // the same as srf.perimeter_curve(i), and t is a common parameter // of deris[i] and TP(i). double MGSBRepVecTP::get_perimeters_max_sin( const MGSurface& srf, double taumax[4], double sinmax[4], bool* evalf //indicates perimeters to evalate if evalf!=null //When evalf[i] is true, perimeter i is evaluated for 0<=i<=3. )const{ MGVector N(3), T(3); MGPosition uv(2); MGNDDArray tau; double max=0.; for(int i = 0; i < 4; i++){ if(!specified(i) || (evalf && !evalf[i])){ taumax[i] = (i % 2 == 0) ? srf.param_s_u() : srf.param_s_v(); sinmax[i] = 0.; continue; } int id = i%2; switch(i){ case 0: uv(1) = srf.param_s_v(); tau.update_from_knot(srf.knot_vector_u()); break; case 1: uv(0) = srf.param_e_u(); tau.update_from_knot(srf.knot_vector_v()); break; case 2: uv(1) = srf.param_e_v(); tau.update_from_knot(srf.knot_vector_u()); break; case 3: uv(0) = srf.param_s_u(); tau.update_from_knot(srf.knot_vector_v()); break; }; //std::cout<& vectp, const MGInterval& prange //Whole perimeter's parameter range. ){ assert(i<4); MGPvector& tpi=m_TP[i]; tpi.clear(); tpi.push_back(vectp); m_prange[i]=prange; size_t n=tpi.size(); if(!n) return; double plen=prange.length().value(); m_to_SE[2*i]=MGREqual_base(prange[0].value(),tpi[0]->param_s(),plen); m_to_SE[2*i+1]=MGREqual_base(prange[1].value(),tpi[n-1]->param_e(),plen); } //Set i-th perimeter's TP(std::vector version). //vectp[i] must be newed objects, and all of the ownership will be transferer to //this instance. void MGSBRepVecTP::set_TP( int i, //perimeter number. std::vector& vectp, const MGInterval& prange //Whole perimeter's parameter range. ){ assert(i<4); MGPvector& tpi=m_TP[i]; tpi.clear(); size_t n=vectp.size(); for(size_t j=0; jparam_s(),plen); m_to_SE[2*i+1]=MGREqual_base(prange[1].value(),tpi[n-1]->param_e(),plen); } //Set i-th perimeter's TP as a null, as an unspecified one. void MGSBRepVecTP::set_TP_null(int i){ assert(i<4); m_TP[i].clear(); } //Debug Function. std::ostream& operator<<( std::ostream& ostrm, const MGSBRepVecTP& vectp ){ ostrm<<"MGSBRepVecTP::"<<&vectp; for(int i=0; i<4; i++){ ostrm<