/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #ifndef _MGEdge_HH_ #define _MGEdge_HH_ #include "mg/Box.h" #include "mg/TrimmedCurve.h" #include "topo/Complex.h" #include "topo/CellNB.h" class MGStraight; class MGSurface; class MGPVertex; class MGBVertex; class MGLoop; class MGFace; // //Define MGEdge Class. /** @addtogroup TOPO * @{ */ ///MGEdge is an instance of MGCellNB, represents a boundary element of 2D manifold. ///MGEdge constitues an MGLoop that is a boundary of MGFace. ///MGEdge can be a parameter cell or a binder cell. The coordinates of a parameter cell ///MGEdge is (u,v) surface parameter, and the ones of binder cell MGEdge is ///(x,y,z) of the world. class MG_DLL_DECLR MGEdge: public MGCellNB{ public: ///Edgeのスケーリングを行い,Edgeを作成する。 ///Scaling of the Edge by a double. MG_DLL_DECLR friend MGEdge operator* (double s, const MGEdge& e); ///////// Constructor ///////// ///void constructor. MGEdge(); ///Copy constructor. MGEdge(const MGEdge& e, bool copy_boundary=true, bool no_binder=false); ///Fundamental constructor. ///Construct an edge from geometry of manifold dimension 1. ///The constructor takes the ownership of geo and MGPVertex* in boundaries. MGEdge( MGGeometry* geo, MGPVertex* boundaries[2], MGCellNB* binder ); ///Make an edge of a boundary that has active start and ///end vertex if the curve is not infinite straight line. ///The second form that input MGCurve* takes the ownership of the crv ///into the MGEdge, must not delete the object and the object must be ///newed one. MGEdge(const MGCurve& crv); explicit MGEdge(MGCurve* crv); ///Make an edge of a boundary(MGBoundary1D that has active start and ///end vertex). ///range is the parameter range of crv. ///The second form that input MGCurve* takes the ownership of the crv ///into the MGEdge, must not delete the object and the object must be ///newed one. MGEdge(const MGCurve& crv, const MGInterval& range); MGEdge(MGCurve* crv, const MGInterval& range); ///Make an edge with a binder of a boundary ///(MGBoundary1D that has active start and end vertex). MGEdge( const MGSurface&surf,/// neighbours() const; ///Test if the edge is a part of a surface perimeter. bool on_surface_perimeter() const{return surface_perimeter()>=0;}; bool on_surface_perimeter(const MGFace& f) const{return surface_perimeter(f)>=0;}; bool on_surface_perimeter(const MGSurface& sf) const{return surface_perimeter(sf)>=0;}; ///Return parameter space error of the cell. double parameter_error()const; ///Obtain the parameter of the binder edge's curve that represent ///the same point as sp. sp is a parameter value of this parameter edge. ///Let S() is the star(surface) of this edge, and fp() is the curve of this cell ///which is a boundary of S(). And fb() is the binder curve of this edge. ///Then S(fp(sp))=fb(param_bcell(sp)). ///This is a parameter edge and have the binder, and the parameter sp is a parameter ///of this cell's curve. If this does not have a binder, return -1. double param_bcell(double tp, const double* guess=0)const; ///This must be a parameter edge. ///Obtain the parameter of this parameter edge's curve that represent the same ///point as the binder edge's paramter tb. ///Let S() is the star(surface) of this edge, and fp() is the curve of this cell ///which is a boundary of S(). And fb() is the binder curve. ///Then S(fp(param_pcell(tb)))=fb(tb). ///This edge must have the binder edge, and the parameter tb is the parameter ///of the binder edge's curve. If this does not have a binder, return -1. double param_pcell(double tb, const double* guess=0)const; ///Obtain end parameter value of the edge. double param_e()const; ///Obtain start parameter value of the edge. double param_s()const; ///Obtain parameter span of this edge. double param_span()const{return param_e()-param_s();}; ///Obtain partner edges. ///Partners represent same world's(same cell's parameter) coordinates. ///Parameter edges' partners are parameter edges. ///Binder edges' partners are binder edges. ///The partners do not include this edge except when star cell is ///connected to the star cell itself(closed only by the star cell). std::vector partner_edges() const; ///Compute the parameter value of the closest point from the straight to ///this object. ///sl is the eye projection line whose direction is from yon to hither, and if ///sl had multiple intersection points, The closest point to the eye will be selected. MGPosition pick_closest(const MGStraight& sl)const; ///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 polygonize(double error); ///Get previous edge in the loop sequence. ///The pre_edge is the first neighbour edge. const MGEdge* pre_edge(bool at_start=true) const; MGEdge* pre_edge(bool at_start=true); ///Get parameter range of the edge. MGInterval range()const; ///Set binder cell edge to this parameter cell. ///This curve's coordinates are of parameter space of a face. And input crv's ///coordinates are world coordinate of the face. ///range is the parameter range of wcrv. ///Parameter range of the wcrv is from start to end of the wcrv when no range ///is specified. ///Function return value is the binder's pointer generated. MGEdge* set_binder_edge(const MGCurve& wcrv)const; MGEdge* set_binder_edge(const MGCurve& wcrv, const MGInterval& range)const; ///These forms give the ownership of wcrv to the edge. ///That is, wcrv must be newed one and users must not delete it. ///Others are same as above "set_binder_edge(const MGCurve& wcrv)" form. ///Function return value is the binder's pointer generated. MGEdge* set_binder_edge(MGCurve* wcrv)const; MGEdge* set_binder_edge(MGCurve* wcrv, const MGInterval& range)const; ///Set start point(boundary) data. ///If this is connected to other edges at end, the connectin will be freed. void set_end(double t); ///Parameter value of the start point. ///Set start point(boundary) data. ///If this is connected to other edges at start, the connectin will be freed. void set_start(double t);///Parameter value of the start point. ///Set only parameter range of this edge. ///Does not change the edge connection like set_start or set_end. void set_only_param_range(double ts, double te); ///Set binder relation to m_vertex[i]. ///i is 0 for the start of the edge, and is 1 for the end. void set_i_th_binder(int i, MGBVertex& binder)const; ///Obtain star surface. ///Star cell of this must be a face. If not, return null. ///If does not have star surface, returns null. const MGSurface* star_surface()const; ///Obtain the end point of the edge. MGPosition start_point()const{return eval(param_s());}; ///Get the perimeter number where this edge is on. ///If this is not on any perimeter, -1 will be returned. int surface_perimeter() const; int surface_perimeter(const MGSurface& sf) const; int surface_perimeter(const MGFace& face) const; ///Trim the loop. Result is from start to t1. void trim_end(double t){trim(t,false);}; ///Trim the loop. Result is from t1 to end. void trim_start(double t){trim(t,true);}; ///Get trimmed curve representation of the edge. MGTrimmedCurve trimmed_curve() const; ///Get the vertex at the start or end. const MGPVertex* vertex(int id)const{return m_vertex[id];}; const MGPVertex* vertex_start()const{return m_vertex[0];}; const MGPVertex* vertex_end()const{return m_vertex[1];}; MGPVertex* vertex(int id){return m_vertex[id];}; MGPVertex* vertex_start(){return m_vertex[0];}; MGPVertex* vertex_end(){return m_vertex[1];}; ///Return world curve pointer of this edge. That is, curve pointer ///of this edge's binder edge. ///May be null when no binder, or the binder does not have an extent. MGCurve* world_curve(); const MGCurve* world_curve() const; std::string whoami()const{return "Edge";}; protected: ///Read Object's member data. void ReadMembers(MGIfstream& buf); ///Write Object's Member Data void WriteMembers(MGOfstream& buf) const; private: MGPVertex* m_vertex[2]; ///<[0]:for start, [1] for end point. ///& cvec) const; ///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* make_binder_extent() const; ///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 make_extent() const; ///Negate the boundary. void negate_boundary(); ///Trim the edge at parameter t. ///When start=true, trim start, and the result is from t to end. ///When start=false, trim end, and the result is from start to t. void trim(double t, bool start); friend class MGFace; friend class MGLoop; }; /** @} */ // end of TOPO group #endif