/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/BSumCurve.h" #include "mg/LBRep.h" #include "mg/Straight.h" #include "mg/RLBRep.h" #include "mg/Ellipse.h" #include "mg/SurfCurve.h" #include "mg/BSumCurve.h" #include "mg/CCisect_list.h" #include "mg/CSisect_list.h" #include "mg/Surface.h" #include "mg/Sphere.h" #include "mg/Cylinder.h" #include "mg/SBRep.h" #include "mg/RSBRep.h" #include "mg/BSumSurf.h" #include "mg/Ifstream.h" #include "mg/Ofstream.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // //Define MGBSumCurve Class(Boolean sum curve of three curves). //MGBSumCurve is a curve to support the class MGBSumSurf, is boolean sum of //three curves, m_g1, m_g2, and m_g12. //MGBSumCurve(t) is defined as m_g1(t)+m_g2(t)-m_g12(t). // ////////////Constructor///////////// //Void constructor(初期化なしでオブジェクトを作成する。) MGBSumCurve::MGBSumCurve():MGCurve(),m_g1(0),m_g2(0),m_g12(0){;} //Copy constructor. MGBSumCurve::MGBSumCurve(const MGBSumCurve& curve) :MGCurve(curve),m_g1(0),m_g2(0),m_g12(0){ if(!curve.m_g1) return; m_g1=curve.m_g1->clone(); m_g2=curve.m_g2->clone(); m_g12=curve.m_g12->clone(); } //constructor of three curves. //The ownership of g1, g2, and g12 will be transfered to this MGBSumCurve. MGBSumCurve::MGBSumCurve(MGCurve* g1, MGCurve* g2, MGCurve* g12) :MGCurve(*g1),m_g1(g1), m_g2(g2), m_g12(g12){ update_mark(); } //constructor of three curves. //The ownership of g1, g2, and g12 will be transfered to this MGBSumCurve. MGBSumCurve::MGBSumCurve(const MGCurve& g1, const MGCurve& g2, const MGCurve& g12) :MGCurve(g1),m_g1(g1.clone()), m_g2(g2.clone()), m_g12(g12.clone()){ update_mark(); } ////////// Destructor ////////// MGBSumCurve::~MGBSumCurve(){ delete m_g1; delete m_g2; delete m_g12; } ////////// Operator overload(演算子多重定義) ////////// //Assignment. //When the leaf object of this and geo2 are not equal, this assignment //does nothing. MGBSumCurve& MGBSumCurve::operator=(const MGBSumCurve& crv2){ if(&crv2==this) return *this; MGCurve::operator=(crv2); delete m_g1; m_g1=0; delete m_g2; m_g2=0; delete m_g12; m_g12=0; if(!crv2.m_g1) return *this; m_g1=crv2.m_g1->clone(); m_g2=crv2.m_g2->clone(); m_g12=crv2.m_g12->clone(); return *this; } MGBSumCurve& MGBSumCurve::operator=(const MGGel& gel2){ const MGBSumCurve* gel2_is_this=dynamic_cast(&gel2); if(gel2_is_this) operator=(*gel2_is_this); return *this; } //Update the curve by translation. // 与ベクトルだけ曲線を平行移動して自身とする。 MGBSumCurve& MGBSumCurve::operator+= (const MGVector& v){ (*m_g1)+=v; (*m_g2)+=v; (*m_g12)+=v; return *this; } //Update the curve by translation. // 与ベクトルだけ曲線をマイナス方向に平行移動して自身とする。 MGBSumCurve& MGBSumCurve::operator-= (const MGVector& v){ (*m_g1)-=v; (*m_g2)-=v; (*m_g12)-=v; return *this; } //Update the curve by multiplying scale. // 与えられたスケールを曲線にかける。 MGBSumCurve& MGBSumCurve::operator*= (double scale){ (*m_g1)*=scale; (*m_g2)*=scale; (*m_g12)*=scale; return *this; } //Update the curve by transformation of matrix. // 与えられた変換で直線の変換を行い自身の直線とする。 MGBSumCurve& MGBSumCurve::operator*= (const MGMatrix& mat){ (*m_g1)*=mat; (*m_g2)*=mat; (*m_g12)*=mat; return *this; } //Update the curve by transformation of transf. // 与えられた変換で曲線のトランスフォームを行い自身とする。 MGBSumCurve& MGBSumCurve::operator*= (const MGTransf& tr){ (*m_g1)*=tr; (*m_g2)*=tr; (*m_g12)*=tr; return *this; } //Transformation object construction MGBSumCurve MGBSumCurve::operator+ (const MGVector& v)const{ MGBSumCurve cc(*this); cc+=v; return cc; } MGBSumCurve operator+ (const MGVector& v, const MGBSumCurve& cc){ return cc+v; } MGBSumCurve MGBSumCurve::operator- (const MGVector& v) const{ MGBSumCurve cc(*this); cc-=v; return cc; } MGBSumCurve MGBSumCurve::operator* (double scale) const{ MGBSumCurve cc(*this); cc*=scale; return cc; } MGBSumCurve operator* (double scale, const MGBSumCurve& cc){ return cc*scale; } MGBSumCurve MGBSumCurve::operator* (const MGMatrix& mat) const{ MGBSumCurve cc(*this); cc*=mat; return cc; } MGBSumCurve MGBSumCurve::operator* (const MGTransf& tr) const{ MGBSumCurve cc(*this); cc*=tr; return cc; } //Logical operator overload(論理演算子多重定義) //Test if two curves are equal. // 与曲線と自身が等しいかの比較判定を行う。 bool MGBSumCurve::operator== (const MGBSumCurve& crv2)const{ if(!m_g1 && !crv2.m_g1) return true; if((*m_g1)!=(*(crv2.m_g1))) return false; if((*m_g2)!=(*(crv2.m_g2))) return false; if((*m_g12)!=(*(crv2.m_g12))) return false; return true; } bool MGBSumCurve::operator<(const MGBSumCurve& gel2)const{ return *m_g1<*(gel2.m_g1); } bool MGBSumCurve::operator==(const MGGel& gel2)const{ const MGBSumCurve* gel2_is_this=dynamic_cast(&gel2); if(gel2_is_this) return operator==(*gel2_is_this); return false; } bool MGBSumCurve::operator<(const MGGel& gel2)const{ const MGBSumCurve* gel2_is_this=dynamic_cast(&gel2); if(gel2_is_this) return operator<(*gel2_is_this); return false; } ////////// Member Function /////////// //Returns B-Rep Dimension. int MGBSumCurve::bdim()const{ const MGKnotVector& t=knot_vector(); return t.bdim(); } //Return minimum box that includes the curve of parameter interval. // 入力のパラメータ範囲の曲線部分を囲むボックスを返す。 MGBox MGBSumCurve::box_limitted( const MGInterval& rang // Parameter Range of the curve. )const{ MGBox bx=m_g1->box_limitted(rang); bx|=m_g2->box_limitted(rang); bx|=m_g12->box_limitted(rang); return bx; } //Changing this object's space dimension. MGBSumCurve& MGBSumCurve::change_dimension( int sdim, // new space dimension int start1, // Destination order of new object. int start2 // Source order of this object. ){ m_g1->change_dimension(sdim,start1,start2); m_g2->change_dimension(sdim,start1,start2); m_g12->change_dimension(sdim,start1,start2); return *this; } //Change parameter range, be able to change the direction by providing //t1 greater than t2. void MGBSumCurve::change_range( double t1, //Parameter value for the start of original. double t2 //Parameter value for the end of original. ){ m_g1->change_range(t1,t2); m_g2->change_range(t1,t2); m_g12->change_range(t1,t2); } //Exchange ordering of the coordinates. //Exchange coordinates (i) and (j). MGBSumCurve& MGBSumCurve::coordinate_exchange( int i, int j ){ m_g1->coordinate_exchange(i,j); m_g2->coordinate_exchange(i,j); m_g12->coordinate_exchange(i,j); return *this; } //Construct new curve object by copying to newed area. //User must delete this copied object by "delete". MGBSumCurve* MGBSumCurve::clone()const{ MGBSumCurve* bss=new MGBSumCurve(*this); return bss; } //copy as a newed curve. The new curve will be MGLBRep or MGRLBRep. //When original curve was a MGRLBRep, the new curve will be a MGRLBRep. //Otherwise, the new curve will be a MGLBRep. //Returned object must be deleted. MGCurve* MGBSumCurve::copy_as_nurbs()const{ return new MGLBRep(*this); } //Construct new curve object by changing //the original object's space dimension. //User must delete this copied object by "delete". MGBSumCurve* MGBSumCurve::copy_change_dimension( int sdim, // new space dimension int start1, // Destination order of new line. int start2 // Source order of this line. )const{ MGBSumCurve* bss=new MGBSumCurve(*this); bss->change_dimension(sdim,start1,start2); return bss; } // Evaluate n'th derivative data. n=0 means positional data evaluation. MGVector MGBSumCurve::eval( double t, //Parameter value. int nderiv, //Order of Derivative. int left //Left continuous(left=true) //or right continuous(left=false). )const{ MGVector val=m_g1->eval(t,nderiv,left); val+=m_g2->eval(t,nderiv,left); val-=m_g12->eval(t,nderiv,left); return val; } //Extrapolate this curve by an (approximate) chord length. //The extrapolation is C2 continuous. void MGBSumCurve::extend( double length, //approximate chord length to extend. bool start //Flag of which point to extend, start or end point of the line. //If start is true extend on the start point. ){ } //Intersection of MGBSumCurve and curve. MGCCisect_list MGBSumCurve::isect(const MGCurve& curve2)const{ MGCCisect_list list=curve2.isect(*this); return list.replace12(); } //Intersection of MGBSumCurve and MGStraight. MGCCisect_list MGBSumCurve::isect(const MGStraight& curve2)const{ return intersect(curve2); } //Intersection of MGBSumCurve and MGSurfCurve. MGCCisect_list MGBSumCurve::isect(const MGSurfCurve& curve2)const{ MGCCisect_list list=curve2.isect(*this); return list.replace12(); } MGCSisect_list MGBSumCurve::isect(const MGSurface& srf)const{ return srf.isect(*this); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGPlane& surf)const{ return intersect_with_plane(surf); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGSphere& surf)const{ return surf.intersect(*this); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGCylinder& surf)const{ return surf.intersect(*this); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGSBRep& surf)const{ return surf.intersect(*this); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGRSBRep& surf)const{ return surf.intersect(*this); } //Intersection with a Surface MGCSisect_list MGBSumCurve::isect(const MGBSumSurf& surf)const{ return surf.intersect(*this); } //Access to i-th element of knot double MGBSumCurve::knot(int i)const{ const MGKnotVector& t=knot_vector(); return t[i]; } //Returns the knot vector of the curve. const MGKnotVector& MGBSumCurve::knot_vector() const{ int nu1=(m_g1->knot_vector()).bdim(); int nu2=(m_g2->knot_vector()).bdim(); int nu3=(m_g12->knot_vector()).bdim(); if(nu1>=nu2){ if(nu1>=nu3) return m_g1->knot_vector(); else return m_g12->knot_vector(); }else if(nu2>=nu3) return m_g2->knot_vector(); else return m_g12->knot_vector(); } //Update this by limiting the parameter range of the curve. // 自身に指定したパラメータ範囲のlimitをつける。 MGBSumCurve& MGBSumCurve::limit(const MGInterval& rng){ m_g1->limit(rng); m_g2->limit(rng); m_g12->limit(rng); return *this; } //Negate the curve direction(曲線の方向を反転する) void MGBSumCurve::negate(){ m_g1->negate(); m_g2->negate(); m_g12->negate(); } //Obtain parameter value if this curve is negated by "negate()". double MGBSumCurve::negate_param(double t)const{ double tspte=param_s()+param_e(); return tspte-t; } //Returns the order. int MGBSumCurve::order()const{ const MGKnotVector& kv=knot_vector(); return kv.order(); } //Normalize parameter value t to the nearest knot if their distance is //within tolerance. double MGBSumCurve::param_normalize(double t)const{ const MGKnotVector& kv=knot_vector(); return kv.param_normalize(t); } //Compute part of this curve from parameter t1 to t2. //Returned is the pointer to newed object, and should be deleted //by calling program, or memory leaked. MGBSumCurve* MGBSumCurve::part( double t1, double t2, int multiple //Indicates if start and end knot multiplicities //are necessary. =0:unnecessary, !=0:necessary. )const{ MGCurve* g1=m_g1->part(t1,t2,multiple); MGCurve* g2=m_g2->part(t1,t2,multiple); MGCurve* g12=m_g12->part(t1,t2,multiple); return new MGBSumCurve(g1,g2,g12); } //Compute all the perpendicular points of this curve and the second one. //That is, if f(s) and g(t) are the points of the two curves f and g, //then obtains points where the following conditions are satisfied: // fs*(f-g)=0. gt*(g-f)=0. //Here fs and gt are 1st derivatives at s and t of f and g. //MGPosition P in the MGPosition_list contains this and crv's parameter //as: P(0)=this curve's parameter, P(1)=crv2's parameter value. MGPosition_list MGBSumCurve::perps( const MGCurve& crv2 //The second curve )const{ MGPosition_list list=crv2.perps(*this); return MGPosition_list(list,1,0); } MGPosition_list MGBSumCurve::perps( const MGStraight& crv2 //The second curve )const{ return perpsSl(crv2); } //Return sweep surface from crv //Returned is a newed MGSurface, must be deleted. MGSurface* MGBSumCurve::sweep( const MGUnit_vector& uvec, //Sweep Direction. double start_dist, //distance to start edge. double end_dist //distance to end edge. )const{ MGLBRep tempCrv(*this); MGSurface *rtnSrf = tempCrv.sweep(uvec, start_dist, end_dist); return rtnSrf; } //Unlimit parameter range of the curve(limitをはずす) MGCurve& MGBSumCurve::unlimit(){ m_g1->unlimit(); m_g2->unlimit(); m_g12->unlimit(); return *this; } //Unlimit parameter range of the curve to the end point direction //(終点方向にlimitをはずす) MGCurve& MGBSumCurve::unlimit_end(){ m_g1->unlimit_end(); m_g2->unlimit_end(); m_g12->unlimit_end(); return *this; } //Unlimit parameter range of the curve to the start point direction //(始点方向にlimitをはずす) MGCurve& MGBSumCurve::unlimit_start(){ m_g1->unlimit_start(); m_g2->unlimit_start(); m_g12->unlimit_start(); return *this; } // Output function. std::ostream& MGBSumCurve::out(std::ostream& ostrm) const{ ostrm<<"MGBSumCurve::"<(buf.ReadPointer()); m_g2=static_cast(buf.ReadPointer()); m_g12=static_cast(buf.ReadPointer()); } //メンバデータを書き込む関数 // ここでは処理対象となるデータメンバが無いので何も処理をしない。 void MGBSumCurve::WriteMembers(MGOfstream& buf) const{ MGCurve::WriteMembers(buf); buf.WritePointer(m_g1); buf.WritePointer(m_g2); buf.WritePointer(m_g12); } //Provide divide number of curve span for function intersect. int MGBSumCurve::intersect_dnum() const{ int n=m_g1->intersect_dnum(); int n2=m_g2->intersect_dnum(); if(nintersect_dnum(); if(n MGBSumCurve::oneD( const double g[4] //Plane expression(a,b,c,d) where ax+by+cz=d. )const{ std::unique_ptr g1=m_g1->oneD(g); std::unique_ptr g2=m_g2->oneD(g); std::unique_ptr g12=m_g12->oneD(g); return std::unique_ptr( new MGBSumCurve(g1.release(),g2.release(),g12.release())); } //Return minimum box that includes whole of the curve. //曲線部分を囲むボックスを返す。 MGBox* MGBSumCurve::compute_box() const{ MGBox* bx=new MGBox; (*bx)|=m_g1->box(); (*bx)|=m_g2->box(); (*bx)|=m_g12->box(); return bx; }