0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / BRepMAT2d / BRepMAT2d_LinkTopoBilo.cxx
1 // Created on: 1994-10-07
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRepMAT2d_BisectingLocus.hxx>
19 #include <BRepMAT2d_DataMapOfShapeSequenceOfBasicElt.hxx>
20 #include <BRepMAT2d_Explorer.hxx>
21 #include <BRepMAT2d_LinkTopoBilo.hxx>
22 #include <BRepTools_WireExplorer.hxx>
23 #include <Geom2d_CartesianPoint.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Geometry.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <MAT_BasicElt.hxx>
28 #include <MAT_Graph.hxx>
29 #include <MAT_SequenceOfBasicElt.hxx>
30 #include <Precision.hxx>
31 #include <Standard_ConstructionError.hxx>
32 #include <Standard_Type.hxx>
33 #include <TColGeom2d_SequenceOfCurve.hxx>
34 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
35 #include <TColStd_DataMapOfIntegerInteger.hxx>
36 #include <TopAbs.hxx>
37 #include <TopExp.hxx>
38 #include <TopExp_Explorer.hxx>
39 #include <TopoDS.hxx>
40 #include <TopoDS_Shape.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Wire.hxx>
43 #include <TopTools_SequenceOfShape.hxx>
44
45 //=======================================================================
46 //function : BRepMAT2d_LinkTopoBilo
47 //purpose  : 
48 //=======================================================================
49 BRepMAT2d_LinkTopoBilo::BRepMAT2d_LinkTopoBilo()
50 {
51 }
52
53
54 //=======================================================================
55 //function : BRepMAT2d_LinkTopoBilo
56 //purpose  : 
57 //=======================================================================
58
59 BRepMAT2d_LinkTopoBilo::BRepMAT2d_LinkTopoBilo(
60    const BRepMAT2d_Explorer&       Explo,
61    const BRepMAT2d_BisectingLocus& BiLo)
62 {
63   Perform (Explo,BiLo);
64 }
65
66
67 //=======================================================================
68 //function : Perform
69 //purpose  : 
70 //=======================================================================
71
72 void BRepMAT2d_LinkTopoBilo::Perform(const BRepMAT2d_Explorer&       Explo, 
73                                      const BRepMAT2d_BisectingLocus& BiLo)
74 {
75   myMap.Clear();
76   myBEShape.Clear();
77
78   TopoDS_Shape     S          = Explo.Shape();
79   Standard_Integer IndContour = 1;
80
81   if (S.ShapeType() == TopAbs_FACE) {
82     TopExp_Explorer  Exp (S,TopAbs_WIRE);
83     
84     while (Exp.More()) {
85       LinkToWire(TopoDS::Wire (Exp.Current()),Explo,IndContour,BiLo);
86       Exp.Next();
87       IndContour++;
88     }
89   }
90   else {
91     throw Standard_ConstructionError("BRepMAT2d_LinkTopoBilo::Perform");
92   }
93   
94 }
95
96
97 //=======================================================================
98 //function : Init
99 //purpose  : 
100 //=======================================================================
101
102 void BRepMAT2d_LinkTopoBilo::Init(const TopoDS_Shape& S)
103 {
104   isEmpty = Standard_False;
105   current = 1;
106   if (myMap.IsBound(S)) myKey = S; else isEmpty = Standard_True;
107 }
108
109
110 //=======================================================================
111 //function : More
112 //purpose  : 
113 //=======================================================================
114
115 Standard_Boolean  BRepMAT2d_LinkTopoBilo::More()
116 {
117   if (isEmpty) return Standard_False;
118   return (current <=  myMap(myKey).Length());
119 }
120
121
122 //=======================================================================
123 //function : Next
124 //purpose  : 
125 //=======================================================================
126
127 void BRepMAT2d_LinkTopoBilo::Next()
128 {
129   current++;
130 }
131
132
133 //=======================================================================
134 //function : Value
135 //purpose  : 
136 //=======================================================================
137
138 Handle(MAT_BasicElt) BRepMAT2d_LinkTopoBilo::Value() const 
139 {
140   return myMap(myKey).Value(current);
141 }
142
143 //=======================================================================
144 //function : GeneratingShape
145 //purpose  : 
146 //=======================================================================
147
148 TopoDS_Shape  BRepMAT2d_LinkTopoBilo::GeneratingShape
149 (const Handle(MAT_BasicElt)& BE) const
150 {
151   return myBEShape(BE);
152 }
153
154 static void LinkToContour(const BRepMAT2d_Explorer&              Explo,
155                           const Standard_Integer                 IndC,
156                           const BRepMAT2d_BisectingLocus&        BiLo,
157                                 TColStd_DataMapOfIntegerInteger& Link);
158
159 //=======================================================================
160 //function : LinkToWire
161 //purpose  : 
162 //=======================================================================
163
164 void BRepMAT2d_LinkTopoBilo::LinkToWire(const TopoDS_Wire&              W,
165                                         const BRepMAT2d_Explorer&       Explo, 
166                                         const Standard_Integer          IndC,
167                                         const BRepMAT2d_BisectingLocus& BiLo)
168 {
169   BRepTools_WireExplorer       TheExp (W);
170   Standard_Integer             KC;
171   TopoDS_Vertex                VF,VL;
172   TopoDS_Shape                 S;
173   Handle(MAT_BasicElt)         BE;
174   Handle(Standard_Type)        Type;
175   TopTools_SequenceOfShape     TopoSeq;
176   MAT_SequenceOfBasicElt EmptySeq;
177
178   TColStd_DataMapIteratorOfDataMapOfIntegerInteger Ite;
179   TColStd_DataMapOfIntegerInteger LinkBECont;
180
181
182   for (;TheExp.More();TheExp.Next()) {
183     TopoSeq.Append(TheExp.Current());
184   }
185   
186   //-----------------------------------------------------
187   // Construction Links BasicElt => Curve of contour IndC.
188   //-----------------------------------------------------
189   LinkToContour(Explo,IndC,BiLo,LinkBECont);
190   
191
192   //---------------------------------------------------------------
193   // Iteration on BasicElts. The associated index is the same for
194   // the curves of the contour and the edges.               .
195   //---------------------------------------------------------------
196   for (Ite.Initialize(LinkBECont); Ite.More(); Ite.Next()) {
197     BE     = BiLo.Graph()->BasicElt(Ite.Key());    
198     Type   = BiLo.GeomElt(BE)->DynamicType();
199     KC     = Ite.Value();
200     S      = TopoSeq.Value(Abs(KC));
201
202     if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {
203       if (S.Orientation() == TopAbs_REVERSED) {
204         TopExp::Vertices(TopoDS::Edge(S),VL,VF);
205       }
206       else {
207         TopExp::Vertices(TopoDS::Edge(S),VF,VL);
208       }
209       if (KC > 0) S = VL; else S = VF;
210     }
211     if (!myMap.IsBound(S)) {       
212       myMap.Bind(S,EmptySeq);
213     }
214     myMap(S).Append(BE);
215
216     if (KC < 0) 
217       myBEShape.Bind(BE, S.Oriented(TopAbs::Reverse(S.Orientation())));
218     else
219       myBEShape.Bind(BE, S);
220   }
221 }
222
223
224 //=======================================================================
225 //function : LinkToContour
226 //purpose  : Association to each basicElt of the curre of the initial
227 //           contour from which it comes.
228 //=======================================================================
229
230 void LinkToContour (const BRepMAT2d_Explorer&              Explo,
231                     const Standard_Integer                 IndC,
232                     const BRepMAT2d_BisectingLocus&        BiLo,
233                     TColStd_DataMapOfIntegerInteger&       Link)
234 {
235   Handle (MAT_BasicElt)    BE;
236   Handle (Geom2d_Geometry) GeomBE;
237   Handle (Standard_Type)   Type;
238   Standard_Boolean         DirectSense   = Standard_True;
239   Standard_Boolean         LastPoint     = Standard_False;
240   Standard_Integer         NbSect,ISect;     
241
242   //---------------------------------------------------
243   // NbSect : number of sections on the current curve.
244   // ISect  : Counter on sections.
245   //---------------------------------------------------
246
247   const TColGeom2d_SequenceOfCurve&  Cont = Explo.Contour(IndC);
248   
249   //------------------------------------------------------------------
250   //Initialization of the explorer on the first curve of the contour.
251   //------------------------------------------------------------------
252   Standard_Integer         IndOnCont     =  1;   
253   Standard_Integer         PrecIndOnCont = -1;
254   NbSect = BiLo.NumberOfSections(IndC,1);
255   ISect  = 0;
256
257   //------------------------------------------------------------------
258   // Parsing of base elements associated to contour IndC.
259   // Rq : the base elements are ordered.
260   //------------------------------------------------------------------
261   for (Standard_Integer i = 1; i <= BiLo.NumberOfElts(IndC); i++) {
262
263     BE     = BiLo.BasicElt(IndC,i);
264     GeomBE = BiLo.GeomElt (BE);
265     Type   = GeomBE->DynamicType();
266
267     if (Type != STANDARD_TYPE(Geom2d_CartesianPoint)) {
268       ISect++;
269       //----------------------------------------------------------------
270       // The base element is a curve associated with the current curve.
271       //----------------------------------------------------------------
272       if (DirectSense) {
273         Link.Bind(BE->Index(),  IndOnCont);
274       }
275       else {
276         Link.Bind(BE->Index(), -IndOnCont);
277       }
278     }
279     else {      
280       //-----------------------------------------------------------------
281       // The base element is a point associated with the previous curve.
282       //-----------------------------------------------------------------
283       if (DirectSense || LastPoint) {
284         Link.Bind(BE->Index(),  PrecIndOnCont);
285       }
286       else {
287         Link.Bind(BE->Index(), -PrecIndOnCont);
288       }
289     }
290
291     PrecIndOnCont = IndOnCont;
292     //----------------------------------------------------------------------
293     // Passage to the next curve in Explo, when all parts 
294     // of curves corresponding to the initial curve have been parsed.
295     //---------------------------------------------------------------------
296     if (Type != STANDARD_TYPE(Geom2d_CartesianPoint) && ISect == NbSect) {
297       if (IndOnCont < Cont.Length() && DirectSense) {
298         IndOnCont++;  
299         NbSect = BiLo.NumberOfSections(IndC,IndOnCont);
300         ISect  = 0;
301       }
302       else {
303         //-----------------------------------------------------
304         // For open lines restart in the other direction.
305         //-----------------------------------------------------
306         if (!DirectSense) {
307           IndOnCont--;
308           if (IndOnCont != 0) NbSect = BiLo.NumberOfSections(IndC,IndOnCont);
309           LastPoint = Standard_False;
310         }
311         else {
312           LastPoint = Standard_True;
313         }
314         ISect       = 0;
315         DirectSense = Standard_False;
316       }
317     }
318   }
319 }