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