0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / BRepMAT2d / BRepMAT2d_BisectingLocus.cxx
1 // Created on: 1993-07-13
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1993-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 <Bisector_Bisec.hxx>
19 #include <BRepMAT2d_BisectingLocus.hxx>
20 #include <BRepMAT2d_Explorer.hxx>
21 #include <Geom2d_Geometry.hxx>
22 #include <Geom2d_TrimmedCurve.hxx>
23 #include <gp_Pnt2d.hxx>
24 #include <MAT2d_BiInt.hxx>
25 #include <MAT2d_Circuit.hxx>
26 #include <MAT2d_CutCurve.hxx>
27 #include <MAT2d_Mat2d.hxx>
28 #include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
29 #include <MAT2d_Tool2d.hxx>
30 #include <MAT_Arc.hxx>
31 #include <MAT_BasicElt.hxx>
32 #include <MAT_Bisector.hxx>
33 #include <MAT_DataMapIteratorOfDataMapOfIntegerBasicElt.hxx>
34 #include <MAT_DataMapOfIntegerBasicElt.hxx>
35 #include <MAT_Graph.hxx>
36 #include <MAT_ListOfBisector.hxx>
37 #include <MAT_Node.hxx>
38 #include <Precision.hxx>
39 #include <Standard_OutOfRange.hxx>
40 #include <TColGeom2d_SequenceOfGeometry.hxx>
41 #include <Geom2d_Curve.hxx>
42
43 static void CutSketch (MAT2d_SequenceOfSequenceOfGeometry&    Figure,
44                        MAT2d_DataMapOfBiIntInteger&           NbSect);
45
46
47 //=============================================================================
48 //function : BRepMAT2d_BisectingLocus
49 //purpose  : Constructeur vide.
50 //=============================================================================
51 BRepMAT2d_BisectingLocus::BRepMAT2d_BisectingLocus()
52 {
53 }
54
55
56 //=============================================================================
57 //function : Compute
58 //purpose  : Calcul de la carte des lieux bisecteurs sur le contour defini par
59 //           <anExplo>.
60 //=============================================================================
61 void BRepMAT2d_BisectingLocus::Compute(BRepMAT2d_Explorer&        anExplo,
62                                        const Standard_Integer IndexLine,
63                                        const MAT_Side         aSide,
64                                        const GeomAbs_JoinType aJoinType,
65                                        const Standard_Boolean IsOpenResult)
66 {
67   MAT2d_Mat2d                        TheMAT( IsOpenResult );
68   Handle(MAT_ListOfBisector)         TheRoots = new MAT_ListOfBisector();
69   MAT2d_SequenceOfSequenceOfGeometry Figure;
70   Standard_Integer                   i;
71
72   nbSect.Clear();
73   nbContours = anExplo.NumberOfContours();
74
75   //---------------------------------
76   // Lecture des donnees de anExplo.
77   //---------------------------------
78   for (i = 1; i <= anExplo.NumberOfContours(); i++) {
79     TColGeom2d_SequenceOfGeometry      Line;
80     Figure.Append(Line);
81     for (anExplo.Init(i); anExplo.More(); anExplo.Next()) {
82       Figure.ChangeValue(i).Append(anExplo.Value());
83     }
84   }
85
86   //-----------------------
87   // Decoupage des courbes.
88   //-----------------------
89   CutSketch(Figure,nbSect);
90
91   //----------------------------------------------------------
92   // Construction du circuit sur lequel est calcule la carte.
93   //----------------------------------------------------------
94   Handle(MAT2d_Circuit) ACircuit = new MAT2d_Circuit(aJoinType, IsOpenResult);
95 //  Modified by Sergey KHROMOV - Wed Mar  6 17:43:47 2002 Begin
96 //   ACircuit->Perform(Figure,IndexLine,(aSide == MAT_Left));
97   ACircuit->Perform(Figure,anExplo.GetIsClosed(), IndexLine,(aSide == MAT_Left));
98 //  Modified by Sergey KHROMOV - Wed Mar  6 17:43:48 2002 End
99
100   // -----------------------
101   // Initialistion du Tool.
102   // -----------------------
103   theTool.Sense(aSide);
104   theTool.SetJoinType(aJoinType);
105   theTool.InitItems(ACircuit);
106
107   // --------------------------------------------
108   // Initialisation et execution de l algorithme.
109   // --------------------------------------------
110   if (IsOpenResult)
111     TheMAT.CreateMatOpen(theTool);
112   else
113     TheMAT.CreateMat(theTool);
114
115   isDone = TheMAT.IsDone(); if (!isDone) return;
116
117   // ----------------------------------------------------------------
118   // Recuperation du resultat de l algorithme et creation du graphe.
119   // ----------------------------------------------------------------
120   for (TheMAT.Init(); TheMAT.More(); TheMAT.Next()) {
121     TheRoots->BackAdd(TheMAT.Bisector());
122   }
123
124   theGraph = new MAT_Graph();
125   theGraph->Perform(TheMAT.SemiInfinite(),
126                     TheRoots, 
127                     theTool.NumberOfItems(), 
128                     TheMAT.NumberOfBisectors());
129
130   //-----------------------------------------------------------------------
131   // Fusion des elements de base doubles si plusieurs lignes dans Exploset.
132   //-----------------------------------------------------------------------
133   if (anExplo.NumberOfContours() > 1) {
134     MAT_DataMapOfIntegerBasicElt NewMap;
135     Standard_Integer             IndexLast  = 1;
136
137     //-----------------------------------------------------------------------
138     // Construction de NewMap dont les elements sont ordonnes suivant les
139     // lignes du contour et qui ne contient pas d element dupliques.
140     // em meme temps fusion des arcs dupliques et mise a jour des noeuds.
141     //-----------------------------------------------------------------------
142     for ( i = 1; i <= anExplo.NumberOfContours(); i++) {
143       RenumerationAndFusion(i,
144                             theTool.Circuit()->LineLength(i),
145                             IndexLast,
146                             NewMap);
147     }
148
149     //-----------------------------------------------------------------------
150     // Chargement dans le graph de la nouvelle map.
151     // et compactage de la map des Arcs (ie  Elimination des trous du a la
152     // fusion d arcs ).et  de celle des Nodes.
153     //-----------------------------------------------------------------------
154     theGraph->ChangeBasicElts(NewMap);    
155     theGraph->CompactArcs();
156     theGraph->CompactNodes();
157   }
158 }
159
160 //=============================================================================
161 //function : RenumerationAndFusion
162 //purpose  :
163 //=============================================================================
164 void BRepMAT2d_BisectingLocus::RenumerationAndFusion
165   (const Standard_Integer              ILine,
166    const Standard_Integer              LengthLine,
167          Standard_Integer&             IndexLast,
168          MAT_DataMapOfIntegerBasicElt& NewMap)
169 {
170   Standard_Integer IndFirst;
171   Standard_Integer i,j;
172   Standard_Integer GeomIndexArc1,GeomIndexArc2,GeomIndexArc3,GeomIndexArc4;
173   Standard_Boolean MergeArc1,MergeArc2;
174
175   for ( i = 1; i <= LengthLine; i++) {
176     const TColStd_SequenceOfInteger& S = theTool.Circuit()->RefToEqui(ILine,i);
177
178     IndFirst = S.Value(1);
179     NewMap.Bind(IndexLast,theGraph->ChangeBasicElt(IndFirst));
180     IndexLast++;
181
182     for(j = 2; j <= S.Length(); j++){
183       theGraph->FusionOfBasicElts(IndFirst,
184                                   S.Value(j),
185                                   MergeArc1,
186                                   GeomIndexArc1,
187                                   GeomIndexArc2,
188                                   MergeArc2,
189                                   GeomIndexArc3,
190                                   GeomIndexArc4);
191       if(MergeArc1) {
192         theTool.BisecFusion(GeomIndexArc1,GeomIndexArc2);
193       }
194       if(MergeArc2) {
195         theTool.BisecFusion(GeomIndexArc3,GeomIndexArc4);
196       }
197     }
198   }
199 }
200
201 //=============================================================================
202 //function : IsDone
203 //Purpose  : 
204 //=============================================================================
205 Standard_Boolean BRepMAT2d_BisectingLocus::IsDone() const
206 {
207   return isDone;
208 }
209
210 //=============================================================================
211 //function : Graph
212 //
213 //=============================================================================
214 Handle(MAT_Graph) BRepMAT2d_BisectingLocus::Graph() const
215 {
216   return theGraph;
217 }
218
219 //=============================================================================
220 //function : NumberOfContours
221 //
222 //=============================================================================
223 Standard_Integer BRepMAT2d_BisectingLocus::NumberOfContours () const
224 {
225   return nbContours;
226 }
227
228 //=============================================================================
229 //function : NumberOfElts
230 //
231 //=============================================================================
232 Standard_Integer BRepMAT2d_BisectingLocus::NumberOfElts 
233  (const Standard_Integer IndLine) const
234 {
235   return theTool.Circuit()->LineLength(IndLine);
236 }
237
238 //=============================================================================
239 //function : NumberOfSect
240 //
241 //=============================================================================
242 Standard_Integer BRepMAT2d_BisectingLocus::NumberOfSections
243 (const Standard_Integer IndLine,
244  const Standard_Integer Index  ) 
245      const
246 {
247   MAT2d_BiInt B(IndLine,Index);
248   return nbSect(B);
249 }
250
251 //=============================================================================
252 //function : BasicElt
253 //
254 //=============================================================================
255 Handle(MAT_BasicElt) BRepMAT2d_BisectingLocus::BasicElt 
256        (const Standard_Integer IndLine,
257         const Standard_Integer Index  ) 
258      const
259 {
260   Standard_Integer i;
261   Standard_Integer Ind = Index;
262
263   for (i = 1 ; i < IndLine ; i++){
264     Ind = Ind + theTool.Circuit()->LineLength(i);
265   }
266   return theGraph->BasicElt(Ind);
267 }
268
269
270 //=============================================================================
271 //function : GeomBis
272 //
273 //=============================================================================
274 Bisector_Bisec  BRepMAT2d_BisectingLocus::GeomBis (const Handle(MAT_Arc)&  anArc,
275                                                      Standard_Boolean& Reverse) 
276 const 
277 {
278   Reverse = Standard_False;
279
280   Handle(Geom2d_Curve) Bis (theTool.GeomBis(anArc->GeomIndex()).Value());
281
282   if (Bis->FirstParameter() <= -Precision::Infinite()) {
283     Reverse = Standard_True;
284   }
285   else if (Bis->LastParameter() < Precision::Infinite()) {
286     gp_Pnt2d PF    = Bis->Value(Bis->FirstParameter());
287     gp_Pnt2d PL    = Bis->Value(Bis->LastParameter());
288     gp_Pnt2d PNode = GeomElt(anArc->FirstNode());
289     if (PNode.SquareDistance(PF) > PNode.SquareDistance(PL)) 
290       Reverse = Standard_True;
291   }
292   return theTool.GeomBis(anArc->GeomIndex());
293 }
294
295 //=============================================================================
296 //function : GeomElt
297 //
298 //=============================================================================
299 Handle(Geom2d_Geometry)  BRepMAT2d_BisectingLocus::GeomElt
300                            (const Handle(MAT_BasicElt)& aBasicElt) const
301 {
302   return  theTool.GeomElt(aBasicElt->GeomIndex());
303 }
304
305
306 //=============================================================================
307 //function : GeomElt
308 //
309 //=============================================================================
310 gp_Pnt2d  BRepMAT2d_BisectingLocus::GeomElt(const Handle(MAT_Node)& aNode) const
311 {
312   return theTool.GeomPnt(aNode->GeomIndex());
313 }
314
315
316 //=============================================================================
317 //function : CutSketch
318 //
319 //=============================================================================
320 static void CutSketch (MAT2d_SequenceOfSequenceOfGeometry&    Figure,
321                        MAT2d_DataMapOfBiIntInteger&           NbSect)
322 {
323   MAT2d_CutCurve   Cuter;
324   Standard_Integer i,j,k,ico;
325   Standard_Integer ICurveInit;
326   Standard_Integer NbSection;
327
328   for ( i = 1; i <= Figure.Length(); i++) {
329     TColGeom2d_SequenceOfGeometry& Contour = Figure.ChangeValue(i);  
330     ICurveInit = 0;
331
332     for ( j = 1; j <= Contour.Length(); j++) {
333       ICurveInit++;
334       Cuter.Perform(Handle(Geom2d_Curve)::DownCast(Contour.ChangeValue(j)));
335       NbSection = 1;
336       if (!Cuter.UnModified()) {
337         ico    = j;
338         NbSection = Cuter.NbCurves();
339         for ( k = 1; k <= NbSection; k++) {
340           Contour.InsertAfter(j,Cuter.Value(k));
341           j++;
342         }
343         Contour.Remove(ico);
344         j--;
345       }
346       MAT2d_BiInt B(i,ICurveInit);
347       NbSect.Bind(B,NbSection);
348     }
349   }
350 }  
351