0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / ShapeAnalysis / ShapeAnalysis_WireVertex.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 //szv#4 S4163
15 #include <ShapeAnalysis_WireVertex.ixx>
16
17 #include <BRep_Tool.hxx>
18 #include <Geom_Curve.hxx>
19
20 #include <Precision.hxx>
21
22 #include <TopoDS_Edge.hxx>
23 #include <TopoDS_Vertex.hxx>
24
25 #include <ShapeAnalysis_Curve.hxx>
26 #include <ShapeAnalysis_Edge.hxx>
27
28 #include <gp_Pnt.hxx> //ied_modif_for_compil_Nov-19-1998
29
30 //=======================================================================
31 //function : ShapeAnalysis_WireVertex
32 //purpose  : 
33 //=======================================================================
34
35 ShapeAnalysis_WireVertex::ShapeAnalysis_WireVertex()
36 {
37   myDone = Standard_False;
38   myPreci = Precision::Confusion();
39 }
40
41 //=======================================================================
42 //function : Init
43 //purpose  : 
44 //=======================================================================
45
46  void ShapeAnalysis_WireVertex::Init(const TopoDS_Wire& wire, const Standard_Real preci)
47 {
48   Init (new ShapeExtend_WireData (wire), preci);
49 }
50   
51 //=======================================================================
52 //function : Init
53 //purpose  : 
54 //=======================================================================
55
56  void ShapeAnalysis_WireVertex::Init(const Handle(ShapeExtend_WireData)& sbwd, const Standard_Real /*preci*/)
57 {
58   Standard_Integer nb = sbwd->NbEdges();
59   if (nb == 0) return;
60   myDone = Standard_False;
61   myWire = sbwd;
62   myStat = new TColStd_HArray1OfInteger (1,nb);  myStat->Init(0);
63   myPos  = new TColgp_HArray1OfXYZ (1,nb);
64   myUPre = new TColStd_HArray1OfReal (1,nb);     myUPre->Init(0.0);
65   myUFol = new TColStd_HArray1OfReal (1,nb);     myUFol->Init(0.0);
66 }
67
68 //=======================================================================
69 //function : Load
70 //purpose  : 
71 //=======================================================================
72
73  void ShapeAnalysis_WireVertex::Load(const TopoDS_Wire& wire) 
74 {
75   Init (wire, myPreci);
76 }
77
78 //=======================================================================
79 //function : Load
80 //purpose  : 
81 //=======================================================================
82
83  void ShapeAnalysis_WireVertex::Load(const Handle(ShapeExtend_WireData)& sbwd) 
84 {
85   Init (sbwd, myPreci);
86 }
87
88 //=======================================================================
89 //function : SetPrecision
90 //purpose  : 
91 //=======================================================================
92
93  void ShapeAnalysis_WireVertex::SetPrecision(const Standard_Real preci) 
94 {
95   myPreci = preci;
96   myDone = Standard_False;
97 }
98
99 //=======================================================================
100 //function : Analyze
101 //purpose  : 
102 //=======================================================================
103
104  void ShapeAnalysis_WireVertex::Analyze() 
105 {
106   if (myStat.IsNull()) return;
107   myDone = Standard_True;
108   //  Analyse des vertex qui se suivent
109   Handle(Geom_Curve) c1, c2;
110   Standard_Real cf, cl, upre, ufol;
111   Standard_Integer i, j, nb = myStat->Length(), stat;
112   ShapeAnalysis_Edge EA;
113   for (i = 1; i <= nb; i ++) {
114     stat = -1;  // au depart
115
116     j = (i == nb ? 1 : i+1);
117     TopoDS_Edge   E1 = myWire->Edge (i);
118     TopoDS_Edge   E2 = myWire->Edge (j);
119     TopoDS_Vertex V1 = EA.LastVertex (myWire->Edge (i));
120     TopoDS_Vertex V2 = EA.FirstVertex (myWire->Edge (j));
121     gp_Pnt PV1 = BRep_Tool::Pnt (V1);
122     gp_Pnt PV2 = BRep_Tool::Pnt (V2);
123     Standard_Real tol1 = BRep_Tool::Tolerance (V1);
124     Standard_Real tol2 = BRep_Tool::Tolerance (V2);
125     EA.Curve3d (myWire->Edge (i),c1,cf,upre);
126     EA.Curve3d (myWire->Edge (j),c2,ufol,cl);
127     if (c1.IsNull() || c2.IsNull()) continue;  // on ne peut rien faire ...
128     gp_Pnt P1 = c1->Value (upre);
129     gp_Pnt P2 = c2->Value (ufol);
130
131     //   Est-ce que le jeu de vertex convient ? (meme si V1 == V2, on verifie)
132     Standard_Real d1 = PV1.Distance (P1);
133     Standard_Real d2 = PV2.Distance (P2);
134     Standard_Real dd = PV1.Distance (PV2);
135     if (d1 <= tol1 && d2 <= tol2 && dd <= (tol1+tol2)) stat = 1;
136     else if (d1 <= myPreci && d2 <= myPreci && dd <= myPreci) stat = 2;
137     myStat->SetValue (i,-1);  // par defaut
138     if (stat > 0)  {  if (V1 == V2) stat = 0;  }
139     if (stat >= 0) {  myStat->SetValue (i,stat);  continue;  }
140     //    Restent les autres cas !
141
142     //    Une edge se termine sur l autre : il faudra simplement relimiter
143     //    Projection calculee sur une demi-edge (pour eviter les pbs de couture)
144     gp_Pnt PJ1,PJ2;
145     Standard_Real U1,U2;
146     Standard_Real dj1 = ShapeAnalysis_Curve().Project (c1,P2,myPreci,PJ1,U1,(cf+upre)/2,upre);
147     Standard_Real dj2 = ShapeAnalysis_Curve().Project (c2,P1,myPreci,PJ2,U2,ufol,(ufol+cl)/2);
148     if (dj1 <= myPreci)       {  SetStart (i,PJ1.XYZ(),U1);  continue;  }
149     else if (dj2 <= myPreci)  {  SetEnd   (i,PJ2.XYZ(),U2);  continue;  }
150
151     //    Restent a verifier les intersections et prolongations !
152   }
153 }
154
155 //=======================================================================
156 //function : SetSameVertex
157 //purpose  : 
158 //=======================================================================
159
160  void ShapeAnalysis_WireVertex::SetSameVertex(const Standard_Integer num) 
161 {
162   myStat->SetValue (num,0);
163 }
164
165 //=======================================================================
166 //function : SetSameCoords
167 //purpose  : 
168 //=======================================================================
169
170  void ShapeAnalysis_WireVertex::SetSameCoords(const Standard_Integer num) 
171 {
172   myStat->SetValue (num,1);
173 }
174
175 //=======================================================================
176 //function : SetClose
177 //purpose  : 
178 //=======================================================================
179
180  void ShapeAnalysis_WireVertex::SetClose(const Standard_Integer num) 
181 {
182   myStat->SetValue (num,2);
183 }
184
185 //=======================================================================
186 //function : SetEnd
187 //purpose  : 
188 //=======================================================================
189
190  void ShapeAnalysis_WireVertex::SetEnd(const Standard_Integer num,const gp_XYZ& pos,const Standard_Real ufol) 
191 {
192   myStat->SetValue (num,3);
193   myPos->SetValue  (num,pos);
194   myUFol->SetValue (num,ufol);
195 }
196
197 //=======================================================================
198 //function : SetStart
199 //purpose  : 
200 //=======================================================================
201
202  void ShapeAnalysis_WireVertex::SetStart(const Standard_Integer num,const gp_XYZ& pos,const Standard_Real upre) 
203 {
204   myStat->SetValue (num,4);
205   myPos->SetValue  (num,pos);
206   myUFol->SetValue (num,upre);
207 }
208
209 //=======================================================================
210 //function : SetInters
211 //purpose  : 
212 //=======================================================================
213
214  void ShapeAnalysis_WireVertex::SetInters(const Standard_Integer num, const gp_XYZ& pos,
215                                           const Standard_Real upre, const Standard_Real ufol) 
216 {
217   myStat->SetValue (num,5);
218   myPos->SetValue  (num,pos);
219   myUPre->SetValue (num,upre);
220   myUFol->SetValue (num,ufol);
221 }
222
223 //=======================================================================
224 //function : SetDisjoined
225 //purpose  : 
226 //=======================================================================
227
228  void ShapeAnalysis_WireVertex::SetDisjoined(const Standard_Integer num) 
229 {
230   myStat->SetValue (num,-1);
231 }
232
233 //=======================================================================
234 //function : IsDone
235 //purpose  : 
236 //=======================================================================
237
238  Standard_Boolean ShapeAnalysis_WireVertex::IsDone() const
239 {
240   return myDone;
241 }
242
243 //=======================================================================
244 //function : Precision
245 //purpose  : 
246 //=======================================================================
247
248  Standard_Real ShapeAnalysis_WireVertex::Precision() const
249 {
250   return myPreci;
251 }
252
253 //=======================================================================
254 //function : NbEdges
255 //purpose  : 
256 //=======================================================================
257
258  Standard_Integer ShapeAnalysis_WireVertex::NbEdges() const
259 {
260   return myWire->NbEdges();
261 }
262
263 //=======================================================================
264 //function : WireData
265 //purpose  : 
266 //=======================================================================
267
268 const Handle(ShapeExtend_WireData)& ShapeAnalysis_WireVertex::WireData() const
269 {
270   return myWire;
271 }
272
273 //=======================================================================
274 //function : Status
275 //purpose  : 
276 //=======================================================================
277
278  Standard_Integer ShapeAnalysis_WireVertex::Status(const Standard_Integer num) const
279 {
280   return myStat->Value(num);
281 }
282
283 //=======================================================================
284 //function : Position
285 //purpose  : 
286 //=======================================================================
287
288  gp_XYZ ShapeAnalysis_WireVertex::Position(const Standard_Integer num) const
289 {
290   return myPos->Value(num);
291 }
292
293 //=======================================================================
294 //function : UPrevious
295 //purpose  : 
296 //=======================================================================
297
298 //szv#4:S4163:12Mar99 was bug: returned Integer
299  Standard_Real ShapeAnalysis_WireVertex::UPrevious(const Standard_Integer num) const
300 {
301   return myUPre->Value(num);
302 }
303
304 //=======================================================================
305 //function : UFollowing
306 //purpose  : 
307 //=======================================================================
308
309 //szv#4:S4163:12Mar99 was bug: returned Integer
310  Standard_Real ShapeAnalysis_WireVertex::UFollowing(const Standard_Integer num) const
311 {
312   return myUFol->Value(num);
313 }
314
315 //=======================================================================
316 //function : Data
317 //purpose  : 
318 //=======================================================================
319
320  Standard_Integer ShapeAnalysis_WireVertex::Data(const Standard_Integer num, gp_XYZ& pos,
321                                                  Standard_Real& upre, Standard_Real& ufol) const
322 {
323   pos  = myPos->Value(num);
324   upre = myUPre->Value(num);
325   ufol = myUFol->Value(num);
326   return myStat->Value(num);
327 }
328
329 //=======================================================================
330 //function : NextStatus
331 //purpose  : 
332 //=======================================================================
333
334  Standard_Integer ShapeAnalysis_WireVertex::NextStatus(const Standard_Integer stat,
335                                                        const Standard_Integer num) const
336 {
337   //szv#4:S4163:12Mar99 optimized
338   if (!myStat.IsNull()) {
339     Standard_Integer i,nb = myStat->Length();
340     for (i = num+1; i <= nb; i ++) if (myStat->Value(i) == stat) return i;
341   }
342   return 0;
343 }
344
345 //=======================================================================
346 //function : NextCriter
347 //purpose  : 
348 //=======================================================================
349
350  Standard_Integer ShapeAnalysis_WireVertex::NextCriter(const Standard_Integer crit,
351                                                        const Standard_Integer num) const
352 {
353   //szv#4:S4163:12Mar99 optimized
354   if (!myStat.IsNull()) {
355     Standard_Integer i,nb = myStat->Length();
356     for (i = num+1; i <= nb; i ++) {
357       Standard_Integer stat = myStat->Value(i);
358       if ((crit == -1 && stat < 0) ||
359           (crit == 0 && stat == 0) ||
360           (crit == 1 && stat >  0) ||
361           (crit == 2 && (stat >= 0 && stat <= 2)) ||
362           (crit == 3 && (stat == 1 || stat == 2)) ||
363           (crit == 4 && stat >  2)) return i;
364     }
365   }
366   return 0;
367 }