/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Pvector.h" #include "mg/Curve.h" #include "mg/LBRep.h" #include "mg/RLBRep.h" #include "mg/SPointSeq.h" #include "mg/Surface.h" #include "mg/SBRep.h" #include "mg/RSBRep.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 //同じカーブの種類で同じノットベクトルを持っているスプライン曲線列かどうか調べる bool isSameKnotVector(const MGPvector& pvCurves){ std::vector::const_iterator citer = pvCurves.begin(); MGCurve& curve0=**citer; long CrvId =curve0.type(); //スプラインカーブ以外が含まれていたらfalseを返す if(CrvId != MGCURVE_SPLINE && CrvId != MGCURVE_RSPLINE) return false; std::vector::const_iterator cend = pvCurves.end(); const MGKnotVector& t0 = curve0.knot_vector();//1st knot vector. for(citer++; citer!=cend; citer++){ MGCurve& curvei=**citer; //カーブの種類が違っていたり、ノットベクトルが違っていたらfalseを返す if(curvei.type()!=CrvId || curvei.knot_vector()!=t0) return false; } return true; } //リブ曲線列から面を作成する //リブ曲線の全てのノットが同じスプラインの時MGSBRepかMGRSBRepが返却される //それ以外の場合は、曲線をLBRepで再構成して面を作成するのでMGSBRepが返却される //作成する面のノットベクトルはリブ曲線の向きをu,リブ列方向をvとする //Let v0=start parameter value, v1=terminate parameter value along v, then //v=v0 const parameter line is curves[0], and v=v1 const parameter line is //curves[n-1], where n=curves.size(). n must be greater or equal to 2. //When n==2, the surface is a ruled surface(that is, order_u() is 2). std::unique_ptr MGCL::createSurfaceFromRibs( const MGPvector& curves,//リブ曲線列 bool direction_adjustment //=true, curves[.] direction are adjusted to line //to the same direction. ){ //リブ列のノットベクトルがそろえられているか調べる(Bスプライン以外はfalseが返る) if(isSameKnotVector(curves)){ const MGCurve& crv0 = *(curves.front()); if(crv0.type() == MGCURVE_RSPLINE){//Rational or non Rationalを調べる size_t nRibNum = curves.size(); std::vector vecPtrRLBReps(nRibNum); for(size_t i=0; i(curves[i]); return std::unique_ptr( new MGRSBRep(vecPtrRLBReps,direction_adjustment)); } } //ノットベクトルが異なったリブの場合曲線をリビルドする return std::unique_ptr(new MGSBRep(curves,direction_adjustment)); } std::unique_ptr MGCL::createSurfaceFromRibs( const std::vector& curves,//リブ曲線列 bool direction_adjustment //=true, curves[.] direction are adjusted to line //to the same direction. ){ size_t n=curves.size(); MGPvector curves2(n); for(size_t i=0; i(curves[i]); std::unique_ptr srf= MGCL::createSurfaceFromRibs(curves2,direction_adjustment); curves2.release_all(); return srf; } //リブ曲線列の両端点、中点の距離を平均してdata points tauを作成する void createRibDataPoints(const MGPvector& curves, MGNDDArray& tau){ int nBdim = (int)curves.size(); tau.resize(nBdim); double taui=0.0; int nBdimM1=nBdim-1; double error=MGTolerance::wc_zero()*10.; for(int i=0; i MGCL::create_ruled_surface( const MGCurve& cross1, // a curve as Edge No.0. const MGCurve& cross2, // another curve as Edge No.2. bool direction_adjustment //=true, curves[.] direction are adjusted to line //to the same direction. ){ std::vector curves(2); curves[0]=&cross1; curves[1]=&cross2; return MGCL::createSurfaceFromRibs(curves,direction_adjustment); } ///リブ曲線列から面を作成する ///作成する面のノットベクトルはリブ曲線の向きをu,リブ列方向をvとする ///This constructor only generates MGSBRep even if curves are MGRLBRep of the same ///knot configuration. To avoid this, use createSurfaceFromRibs() that generates ///MGRSBRep when curves are MGRLBRep of the same knot configuration. ///Let v0=start parameter value, v1=terminate parameter value along v, then ///v=v0 const parameter line is curves[0], and v=v1 const parameter line is ///curves[n-1], where n=curves.size(). n must be greater or equal to 2. ///When n==2, the surface is a ruled surface(that is, this->order_u() is 2). ///When direction_adjustment=true, curves[i] directions are adjusted to line up ///to the same direciton as the curves[i-1]'s. ///When direction_adjustment=false, no curves of curves[i] are negated and ///the directions of curves[i] are the direcitons of ribs. MGSBRep::MGSBRep(const MGPvector& curves,bool direction_adjustment) :MGSurface(){ int i=0, nRibNum = (int)curves.size(); if(nRibNum < 2) return; MGPvector lbs=rebuild_knot(curves); //リビルド実行 MGLBRep& lbs0=*(lbs[0]); if(direction_adjustment){ double tmid=(lbs0.param_s()+lbs0.param_e())*.5;//param of mid point. MGVector dir1=lbs0.eval(tmid,1); for(i=1; i len) len = lenv; //lenはlenu,lenvの大きい方の値が入る int lenuv = lenu * lenv; int nOrder = m_uknot.order(), nSdim = lbs[0]->sdim(); if(nOrdercoef(i,k); } } } int blg4spError = 2; for(i=0; i& curves,bool direction_adjustment){ size_t n=curves.size(); MGPvector curves2(n); for(size_t i=0; i(curves[i]); operator=(MGSBRep(curves2,direction_adjustment)); curves2.release_all(); } //リブ曲線列から面を作成する //作成する面のノットベクトルはリブ曲線の向きをu,リブ列方向をvとする //This constructor only generates MGSBRep even if curves are MGRLBRep of the same //knot configuration. To avoid this, use createSurfaceFromRibs() that generates //MGRSBRep when curves are MGRLBRep of the same knot configuration. //Let v0=start parameter value, v1=terminate parameter value along v, then //v=v0 const parameter line is curves[0], and v=v1 const parameter line is //curves[n-1], where n=curves.size(). n must be greater or equal to 2. //When n==2, the surface is a ruled surface(that is, this->order_u() is 2). MGRSBRep::MGRSBRep( const std::vector& vecPtrRibRLBReps, bool direction_adjustment//=true, curves[.] direction are adjusted to line //to the same direction. ){ size_t i=0, nRibNum=vecPtrRibRLBReps.size(); std::vector vecPtrRibLBReps(nRibNum); for(i=0; ihomogeneous(); } *this = MGRSBRep(MGSBRep(vecPtrRibLBReps),direction_adjustment); }