0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / Intf / Intf_Interference.cxx
1 // Created on: 1991-06-24
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1991-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 <gp_Pnt.hxx>
19 #include <gp_Pnt2d.hxx>
20 #include <Intf_Interference.hxx>
21 #include <Intf_SectionLine.hxx>
22 #include <Intf_SectionPoint.hxx>
23 #include <Intf_TangentZone.hxx>
24 #include <Standard_OutOfRange.hxx>
25
26 //=======================================================================
27 //function : Intf_Interference
28 //purpose  : Initialize for a deferred interference.
29 //=======================================================================
30 Intf_Interference::Intf_Interference (const Standard_Boolean Self)
31      : SelfIntf(Self)
32 {}
33
34
35 //=======================================================================
36 //function : SelfInterference
37 //purpose  : Reset interference before perform with a new...
38 //=======================================================================
39
40 void Intf_Interference::SelfInterference (const Standard_Boolean Self)
41 {
42   SelfIntf=Self;
43   mySPoins.Clear();
44   mySLines.Clear();
45   myTZones.Clear();
46 }
47
48
49 //=======================================================================
50 //function : Insert
51 //purpose  : Insert a tangent zone in the list of the interference
52 //=======================================================================
53
54 Standard_Boolean Intf_Interference::Insert(const Intf_TangentZone& LaZone)
55 {
56   if (myTZones.Length()<=0) return Standard_False;
57   Standard_Integer lzin=0;   // Index in the list of the zone of interest.
58   Standard_Integer lunp=0;   // Index of the 1st stop point in this zone.
59   Standard_Integer lotp=0;   // Index of the 2nd stop point in this zone.
60   Standard_Integer lunl=0;   // Index of the 1st point of the new zone.
61   Standard_Integer lotl=0;   // Index of the 2nd point of the new zone.
62   Standard_Boolean same=Standard_False;     // Search direction of the stop of the new zone.
63   Standard_Boolean Inserted=Standard_True;  // Has the insertion succeeded ?
64   Standard_Integer npcz=-1;  // Number of points in the current zone
65   Standard_Integer nplz=LaZone.NumberOfPoints(); // in the new zone
66
67 // Loop on TangentZone :
68   for (Standard_Integer Iz=1; Iz<=myTZones.Length(); Iz++) {
69
70 // Loop on edges of the TangentZone :
71     npcz=myTZones(Iz).NumberOfPoints();
72     Standard_Integer Ipz0, Ipz1, Ipz2;
73     for (Ipz1=1; Ipz1<=npcz; Ipz1++) {
74       Ipz0=Ipz1-1;
75       if (Ipz0<=0) Ipz0=npcz;
76       Ipz2=(Ipz1%npcz)+1;
77
78 // Loop on edges of the new TangentZone and search of the
79 // corresponding point or edge:
80       Standard_Integer Ilz1, Ilz2;
81       for (Ilz1=1; Ilz1<=nplz; Ilz1++) {
82         Ilz2=(Ilz1%nplz)+1;
83         
84         if ((myTZones(Iz).GetPoint(Ipz1)).IsEqual
85             (LaZone.GetPoint(Ilz1))) {
86           if ((myTZones(Iz).GetPoint(Ipz0)).IsEqual
87               (LaZone.GetPoint(Ilz2))) {
88             lzin=Iz;
89             lunp=Ipz0;
90             lotp=Ipz1;
91             lunl=Ilz1;
92             lotl=Ilz2;
93             same=Standard_False;
94             break;
95           }
96           else if ((myTZones(Iz).GetPoint(Ipz2)).IsEqual
97               (LaZone.GetPoint(Ilz2))) {
98             lzin=Iz;
99             lunp=Ipz1;
100             lotp=Ipz2;
101             lunl=Ilz1;
102             lotl=Ilz2;
103             same=Standard_True;
104             break;
105           }
106           else {
107             lzin=Iz;
108             lunp=Ipz1;
109             lunl=Ilz1;
110           }
111         }
112       }
113       if (lotp!=0) break;
114     }
115     if (lotp!=0) break;
116   }
117
118   Standard_Integer Ilc;
119   if (lotp!=0) {
120     for (Ilc=lotl+1; (((Ilc-1)%nplz)+1)!=lunl; Ilc++) {
121       myTZones(lzin).InsertBefore
122         (lotp, LaZone.GetPoint(((Ilc-1)%nplz)+1));
123       if (!same) lotp++;
124     }
125   }
126
127   else if (lunp>0) {
128     Standard_Boolean loop=Standard_False;
129     for (Ilc=lunl; ; Ilc++) {
130       myTZones(lzin).InsertBefore(lunp, 
131                                          LaZone.GetPoint((((Ilc-1)%nplz)+1)));
132       lunp++;
133       if (loop && (((Ilc-1)%nplz)+1)==lunl) break;
134       loop=Standard_True;
135     }
136   }
137
138   else {
139     Inserted =Standard_False;
140   }
141
142   if (Inserted) {
143     Intf_TangentZone theNew=myTZones(lzin);
144     myTZones.Remove(lzin);
145     if (!Insert(theNew))
146       myTZones.Append(theNew);
147   }
148   return Inserted;
149 }
150
151 //=======================================================================
152 //function : Insert
153 //purpose  : 
154 //=======================================================================
155
156 void Intf_Interference::Insert(const Intf_SectionPoint& pdeb,
157                                const Intf_SectionPoint& pfin) 
158 {
159   Standard_Boolean Inserted=Standard_False;
160   Standard_Integer TheLS=0;
161   Standard_Boolean Begin=Standard_False;
162   Intf_SectionPoint TheBout(pfin);
163   Standard_Integer ils, nd, nf;
164   
165   for (ils=1; ils<=mySLines.Length(); ils++) {
166     Intf_SectionLine& SL=mySLines(ils);
167     nd=SL.IsEnd(pdeb);
168     nf=SL.IsEnd(pfin);
169     if (nd==1) {
170       if (nf>1) SL.Close();
171       Inserted=Standard_True;
172       TheLS=ils;
173       Begin=Standard_True;
174       break;
175     }
176     else if (nd>1) {
177       if (nf==1) SL.Close();
178       Inserted=Standard_True;
179       TheLS=ils;
180       Begin=Standard_False;
181       break;
182     }
183     else if (nf==1) {
184       Inserted=Standard_True;
185       TheLS=ils;
186       Begin=Standard_True;
187       TheBout=pdeb;
188       break;
189     }
190     else if (nf>1) {
191       Inserted=Standard_True;
192       TheLS=ils;
193       Begin=Standard_False;
194       TheBout=pdeb;
195       break;
196     }
197   }
198   
199   if (!Inserted) {
200     Intf_SectionLine LaLS;
201     LaLS.Append(pdeb);
202     LaLS.Append(pfin);
203     mySLines.Append(LaLS);
204   }
205   else {
206     nd=0;
207     for (ils=1; ils<=mySLines.Length(); ils++) {
208       if (ils != TheLS) {
209         nd=mySLines(ils).IsEnd(TheBout);
210         if (nd==1) {
211           if (Begin) {
212             mySLines(TheLS).Reverse();
213           }
214           mySLines(ils).Prepend(mySLines(TheLS));
215           break;
216         }
217         else if (nd>1) {
218           if (!Begin) {
219             mySLines(TheLS).Reverse();
220           }
221           mySLines(ils).Append(mySLines(TheLS));
222           break;
223         }
224       }
225     }
226     if (nd>0) {
227       mySLines.Remove(TheLS);
228     }
229     else {
230       if (Begin)
231         mySLines(TheLS).Prepend(TheBout);
232       else
233         mySLines(TheLS).Append(TheBout);
234     }
235   }
236 }
237
238
239
240 //----------------------------------------------------
241 // 
242 //----------------------------------------------------
243 Standard_Boolean Intf_Interference::Contains
244   (const Intf_SectionPoint& LePnt) const
245 {
246   //-- LePnt.Dump(0);
247   for (Standard_Integer l=1; l<=mySLines.Length(); l++) {
248     if (mySLines(l).Contains(LePnt)) return Standard_True;
249   }
250   for (Standard_Integer t=1; t<=myTZones.Length(); t++) {
251     //-- myTZones(t).Dump(2);
252     if (myTZones(t).Contains(LePnt)) return Standard_True;
253   }
254   return Standard_False;
255 }
256
257
258 //----------------------------------------------------
259 // 
260 //----------------------------------------------------
261 void Intf_Interference::Dump() const
262 {
263   cout << "Mes SectionPoint :" << endl;
264   for (Standard_Integer p=1; p<=mySPoins.Length(); p++) {
265     mySPoins(p).Dump(2);
266   }
267   cout << "Mes SectionLine :" << endl;
268   for (Standard_Integer l=1; l<=mySLines.Length(); l++) {
269     mySLines(l).Dump(2);
270   }
271   cout << "Mes TangentZone :" << endl;
272   for (Standard_Integer t=1; t<=myTZones.Length(); t++) {
273     myTZones(t).Dump(2);
274   }
275 }