1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef __INTERPKERNELGEO2DEDGE_HXX__
21 #define __INTERPKERNELGEO2DEDGE_HXX__
23 #include "INTERPKERNELDefines.hxx"
24 #include "InterpKernelGeo2DComposedEdge.hxx"
25 #include "InterpKernelException.hxx"
26 #include "InterpKernelGeo2DBounds.hxx"
27 #include "InterpKernelGeo2DNode.hxx"
34 namespace INTERP_KERNEL
56 } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE
64 } TypeOfEdgeLocInPolygon;
66 class INTERPKERNEL_EXPORT MergePoints
71 //methods called during intersection edge-edge
72 void start1Replaced();
74 void start1OnStart2();
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;
84 unsigned getNumberOfAssociations() const;
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;
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.
100 class INTERPKERNEL_EXPORT IntersectElement
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; }
126 double _chararct_val_for_e1;
127 double _chararct_val_for_e2;
129 TypeOfLocInPolygon _loc_of_node;
133 static const unsigned LIMIT_ALONE = 22;
134 static const unsigned LIMIT_ON = 73;
135 static const unsigned NO_LIMIT = 19;
139 * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection.
141 class INTERPKERNEL_EXPORT EdgeIntersector
144 //! All non symetric methods are relative to 'e1'.
145 EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { }
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;
160 void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const;
166 class INTERPKERNEL_EXPORT SameTypeEdgeIntersector : public EdgeIntersector
169 SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { }
170 bool keepOrder() const { return true; }
173 class INTERPKERNEL_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector
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; }
182 //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done.
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).
197 class INTERPKERNEL_EXPORT Edge
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++; }
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;
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;
271 Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { }
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);
280 mutable unsigned char _cnt;
281 mutable TypeOfEdgeLocInPolygon _loc;
286 //In relation with max possible value of TypeOfLocInEdge.
287 static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8;