/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Straight.h" #include "mg/LBRep.h" #include "mg/SurfCurve.h" #include "mg/Tolerance.h" #include "topo/PVertex.h" #include "topo/Edge.h" #include "topo/Face.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //Test if this edge's start point(when start=true) and edge2 is connected //and their directions are the same. //When start=false, this edge's end point is tested. bool MGEdge::is_connected_and_same_direction( bool start, const MGEdge& edge2 )const{ const MGPVertex* pv1; const MGPVertex* pv2; if(start){ pv1=vertex_start(); pv2=edge2.vertex_end(); }else{ pv1=vertex_end(); pv2=edge2.vertex_start(); } return pv1->binder()==pv2->binder(); } //Make a binder cell of this parameter cell. //Returned is the binder pointer generated by new. //The binder has no geometry, only has binder and parameter cell relationship. MGCellNB* MGEdge::make_binder() const{ MGCellNB* cell=binder(); if(cell) return cell; MGEdge* bedge=new MGEdge(); set_binder(*bedge); return bedge; } //Make this cell's binder cell's extent expression. //Returned is a MGGeometry pointer generated by new. //When this cell does not have star cell, null pointer will be returned. //make_binder_extent() only makes the expression, and does nothing to //the topology structure. MGGeometry* MGEdge::make_binder_extent() const{ const MGSurface* srf=face()->surface(); return new MGSurfCurve(*srf,trimmed_curve()); } //Make a binder associated with the world curve rep. //Returned is the binder edge pointer. //If the parameter edge already had the binder, //make_binder_with_curve() only returns the pointer. //*** This edge must be a parameter edge of a loop that is a boundary of a face. MGEdge* MGEdge::make_binder_with_curve()const{ assert(face()); assert(face()->surface()); const MGSurface* srf=face()->surface(); MGEdge* bedg=binder_edge(); if(bedg) if(bedg->base_curve()) return bedg; //If binder edge did not have curve representation. MGSurfCurve srfcrv(*srf,trimmed_curve());//std::cout<eval(t0), deriE=bcrv->eval(t1); if((deriS.is_zero_vector() && deriE.is_zero_vector()) || (deriS.parallel(deriE) && deriS%deriE<0.)){ delete bcrv; bcrv=new MGStraight(P1,P0); } }*/ if(bedg) bedg->set_extent(bcrv); else //Generate binder edge. bedg=set_binder_edge(bcrv); (*bedg).set_start(t0); (*bedg).set_end(t1); (*bedg).m_equal_to_binder=1;//bedg is equal_direction to this. return bedg; } //Make sure that this has an extent expression. //When this did not have an extent, make the extent from the partner //member's parameter expression and the star cell. //This must be a binder cell that has partner members that are //boundaries. When this is not the case or this had an extent already, //it does nothing. void MGEdge::make_extent() const{ if(extent()) return; if(!is_bcell()) return; const MGEdge* pedge=member_partner_edge(0); assert(pedge->face()); assert(pedge->face()->surface()); const MGSurface* srf=pedge->face()->surface(); MGCurve* bcrv; //If binder edge did not have curve representation. bcrv=new MGSurfCurve(*srf,pedge->trimmed_curve()); MGEdge* thisE=const_cast(this); thisE->set_extent(bcrv); } //Obtain the i-th member partner edge. This must be a binder edge. const MGEdge* MGEdge::member_partner_edge(int i)const{ return static_cast(member_partner(i)); } //Approximate the parameter edge by a polyline and replace this edge //expression by the polyline. Polyline approximation is so done that //the correspoinding binder edge can be appximated by the polyline connecting //each binder edge's point that corresponds to the each this edge's point. //(1) This must be a parameter cell edge. //(2) This edge must be a member of a loop which is a boundary of a face. //(3) If this edge did not have a binder edge, polygonize generates the binder edge. //(The tolerance used to generate the binder is MGTolerance::line_zero(), // not input error.) //Input error is tolerance allowed between the polygon and the original curve. void MGEdge::polygonize(double error){ const MGSurface* srf = face()->surface(); MGLBRep* Bcrv; MGEdge* bedge = binder_edge(); double errorSave = MGTolerance::set_line_zero(error); if(bedge){ if(!bedge->base_curve()){ Bcrv = new MGLBRep(MGSurfCurve(*srf,trimmed_curve()), 2); }else{ Bcrv = new MGLBRep(bedge->trimmed_curve(), 2); } bedge->set_extent(Bcrv); }else{ Bcrv = new MGLBRep(MGSurfCurve(*srf,trimmed_curve()), 2); set_binder_edge(Bcrv); bedge = binder_edge(); } MGTolerance::set_line_zero(errorSave); MGLBRep* nBcrv = dynamic_cast(bedge->curve_limitted()); double t0,t1; if(equal_direction_to_binder()){ t0 = param_s(); t1 = param_e();} else{ t1 = param_s(); t0 = param_e();} nBcrv->change_range(t0, t1); //Now nBcrv is the same direction as this parameter edge, and has //the same parameter range. //Change Bcrv to original parameter edge's polyline expression. MGCurve* originalC=base_curve(); int n = nBcrv->bdim(); MGBPointSeq coef(n,2); const MGKnotVector& t = nBcrv->knot_vector(); for(int i = 0; i < n; i++) coef.store_at(i, originalC->eval(t[i+1])); nBcrv->line_bcoef() = coef; set_extent(nBcrv); }