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