Salome HOME
Merge from BR_V5_DEV 16Feb09
[modules/med.git] / src / INTERP_KERNEL / Geometric2D / Edge.hxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifndef __EDGE_HXX__
20 #define __EDGE_HXX__
21
22 #include "INTERPKERNELGEOMETRIC2DDefines.hxx"
23 #include "ComposedEdge.hxx"
24 #include "InterpKernelException.hxx"
25 #include "Bounds.hxx"
26 #include "Node.hxx"
27
28 #include <iostream>
29 #include <vector>
30 #include <list>
31 #include <map>
32
33 namespace INTERP_KERNEL
34 {
35   typedef enum
36     {
37       SEG         = 1,
38       ARC_CIRCLE  = 4,
39       ARC_PARABOL = 8
40     } TypeOfFunction;
41
42   typedef enum
43     {
44       CIRCLE  = 0 ,
45       PARABOL = 1
46     } TypeOfMod4QuadEdge;
47
48   typedef enum
49     {
50       START       = 5,
51       END         = 1,
52       INSIDE      = 2,
53       OUT_BEFORE  = 3,
54       OUT_AFTER   = 4
55     } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE
56   
57   typedef enum
58     {
59       FULL_IN_1    = 1,
60       FULL_ON_1    = 4,
61       FULL_OUT_1   = 2,
62       FULL_UNKNOWN = 3
63     } TypeOfEdgeLocInPolygon;
64
65   class INTERPKERNELGEOMETRIC2D_EXPORT MergePoints
66   {
67   public:
68     MergePoints();
69
70     //methods called during intersection edge-edge
71     void start1Replaced();
72     void end1Replaced();
73     void start1OnStart2();
74     void start1OnEnd2();
75     void end1OnStart2();
76     void end1OnEnd2();
77     //methods to be called during aggregation
78     bool isStart1(unsigned rk) const;
79     bool isEnd1(unsigned rk) const;
80     bool isStart2(unsigned rk) const;
81     bool isEnd2(unsigned rk) const;
82     void clear();
83     unsigned getNumberOfAssociations() const;
84   private:
85     unsigned _ass1Start1  : 1;
86     unsigned _ass1End1    : 1;
87     unsigned _ass1Start2  : 1;
88     unsigned _ass1End2    : 1;
89     unsigned _ass2Start1  : 1;
90     unsigned _ass2End1    : 1;
91     unsigned _ass2Start2  : 1;
92     unsigned _ass2End2    : 1;
93   };
94
95   /*!
96    * This class is in charge to store an intersection point as result of \b non oververlapping edge intersection.
97    * This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2.
98    */
99   class INTERPKERNELGEOMETRIC2D_EXPORT IntersectElement
100   {
101   public:
102     IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder);
103     IntersectElement(const IntersectElement& other);
104     //! The sort operator is done on the edge 1 \b not edge 2.
105     bool operator<(const IntersectElement& other) const;
106     IntersectElement& operator=(const IntersectElement& other);
107     double getVal1() const { return _chararct_val_for_e1; }
108     double getVal2() const { return _chararct_val_for_e2; }
109     //! idem operator< method except that the orientation is done on edge 2 \b not edge 1.
110     bool isLowerOnOther(const IntersectElement& other) const;
111     unsigned isOnExtrForAnEdgeAndInForOtherEdge() const;
112     void attachLoc() { _node->setLoc(_loc_of_node); }
113     bool isOnMergedExtremity() const;
114     bool isIncludedByBoth() const;
115     void setNode(Node *node) const;
116     void performMerging(MergePoints& commonNode) const;
117     Node *getNodeOnly() const { return _node; }
118     Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; }
119     ~IntersectElement();
120   private:
121     bool _1S;
122     bool _1E;
123     bool _2S;
124     bool _2E;
125     double _chararct_val_for_e1;
126     double _chararct_val_for_e2;
127     Node *_node;
128     TypeOfLocInPolygon _loc_of_node;
129     const Edge& _e1;
130     const Edge& _e2;
131   public:
132     static const unsigned LIMIT_ALONE = 22;
133     static const unsigned LIMIT_ON = 73;
134     static const unsigned NO_LIMIT = 19;
135   };
136
137   /*!
138    * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection.
139    */
140   class INTERPKERNELGEOMETRIC2D_EXPORT EdgeIntersector
141   {
142   protected:
143     //! All non symetric methods are relative to 'e1'.
144     EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { }
145   public:
146     virtual ~EdgeIntersector() { }
147     virtual bool keepOrder() const = 0;
148     //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called
149     virtual bool haveTheySameDirection() const = 0;
150     //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called
151     virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0;
152     //! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done.
153     bool intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode);
154     //! Should be called only once per association.
155     virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0;
156     //! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method.
157     virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0;
158   protected:
159     void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const;
160   protected:
161     const Edge& _e1;
162     const Edge& _e2;
163   };
164
165   class INTERPKERNELGEOMETRIC2D_EXPORT SameTypeEdgeIntersector : public EdgeIntersector
166   {
167   protected:
168     SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { }
169     bool keepOrder() const { return true; }
170   };
171
172   class INTERPKERNELGEOMETRIC2D_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector
173   {
174   protected:
175     CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { }
176     bool keepOrder() const { return _reverse; }
177     bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); }
178     const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; }
179     const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; }
180   protected:
181     //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done.
182     bool _reverse;
183   };
184
185   class EdgeLin;
186   class EdgeInfLin;
187   class EdgeArcCircle;
188
189   /*!
190    * Deal with an oriented edge of a polygon.
191    * An Edge is definied with a start node a end node and an equation of 1D curve.
192    * All other attributes are mutable because they don't impact these 3 invariant attributes.
193    * To be exact start and end node can change (adress) but their location remain
194    * the same (at precision).
195    */
196   class INTERPKERNELGEOMETRIC2D_EXPORT Edge
197   {
198   public:
199     Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); }
200     Edge(double sX, double sY, double eX, double eY);
201     TypeOfEdgeLocInPolygon getLoc() const { return _loc; }
202     void incrRef() const { _cnt++; }
203     bool decrRef();
204     void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); }
205     void declareOn() const;
206     void declareIn() const;
207     void declareOut() const;
208     const Bounds& getBounds() const { return _bounds; }
209     void fillXfigStreamForLoc(std::ostream& stream) const;
210     Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; }
211     Node *getStartNode() const { return _start; }
212     Node *getEndNode() const { return _end; }
213     void setEndNodeWithoutChange(Node *newEnd);
214     void setStartNodeWithoutChange(Node *newStart);
215     bool changeStartNodeWith(Node *otherStartNode) const;
216     bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector<Node *>& track) const;
217     bool changeEndNodeWith(Node *otherEndNode) const;
218     bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const;
219     void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const;
220     void getNormalVector(double *vectOutput) const;
221     static EdgeIntersector *buildIntersectorWith(const Edge *e1, const Edge *e2);
222     static Edge *buildFromXfigLine(std::istream& str);
223     static Edge *buildEdgeFrom(Node *start, Node *end);
224     template<TypeOfMod4QuadEdge type>
225     static Edge *buildEdgeFrom(Node *start, Node *middle, Node *end);
226     virtual void update(Node *m) = 0;
227     //! returns area between this and axe Ox delimited along Ox by _start and _end.
228     virtual double getAreaOfZone() const = 0;
229     //! apply a similiraty transformation on 'this'
230     virtual void applySimilarity(double xBary, double yBary, double dimChar);
231     //! return the length of arc. Value is always > 0. !
232     virtual double getCurveLength() const = 0;
233     virtual void getBarycenter(double *bary) const = 0;
234     virtual void getBarycenterOfZone(double *bary) const = 0;
235     //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned.
236     virtual Node *buildRepresentantOfMySelf() const = 0;
237     //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method.
238     virtual bool isIn(double characterVal) const = 0;
239     //! With the same magnitude as defined in 'isIn' method perform a compararison. Precondition : val1 and val2 are different and exactly INSIDE this.
240     virtual bool isLower(double val1, double val2) const = 0;
241     //! node is expected to lay on 'this'. It returns a characteristic magnitude usable by isIn method.
242     virtual double getCharactValue(const Node& node) const = 0;
243     //! retrieves the distance to this : The min distance from pt and any point of this.
244     virtual double getDistanceToPoint(const double *pt) const = 0;
245     //! return if node with coords 'coordOfNode' is on this (with precision).
246     virtual bool isNodeLyingOn(const double *coordOfNode) const = 0;
247     virtual TypeOfFunction getTypeOfFunc() const = 0;
248     virtual void dynCastFunction(const EdgeLin * &seg,
249                                  const EdgeArcCircle * &arcSeg) const = 0;
250     bool intersectWith(const Edge *other, MergePoints& commonNode,
251                        ComposedEdge& outVal1, ComposedEdge& outVal2) const;
252     static bool intersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode,
253                                     ComposedEdge& outValForF1, ComposedEdge& outValForF2);
254     static void interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2,
255                                  std::map<int, std::map<int,double> >& result);
256     virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0;
257   protected:
258     Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
259     virtual ~Edge();
260     static int combineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2);
261     static bool intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode,
262                           ComposedEdge& outValForF1, ComposedEdge& outValForF2);
263     //! The code 'code' is built by method combineCodes
264     static bool splitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code,
265                                      ComposedEdge& outVal1, ComposedEdge& outVal2);
266     virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0;
267   protected:
268     mutable unsigned char _cnt;
269     mutable TypeOfEdgeLocInPolygon _loc;
270     Bounds _bounds;
271     Node *_start;
272     Node *_end;
273   protected:
274     //In relation with max possible value of TypeOfLocInEdge.
275     static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8;
276   };
277 }
278
279 #endif