0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / BRepExtrema / BRepExtrema_DistShapeShape.cxx
CommitLineData
b311480e 1// Created on: 1996-04-22
2// Created by: Herve LOUESSARD
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
92d1589b 17// Modified: Mps(10-04-97) portage WNT
92d1589b
A
18
19#include <BRepExtrema_DistShapeShape.hxx>
20
7fd59977 21#include <Standard_OStream.hxx>
22#include <TopTools_IndexedMapOfShape.hxx>
23#include <BRepBndLib.hxx>
24#include <Bnd_Box.hxx>
25#include <TopExp.hxx>
7fd59977 26#include <BRepExtrema_DistanceSS.hxx>
27#include <TopoDS.hxx>
7fd59977 28#include <TopoDS_Vertex.hxx>
29#include <TopoDS_Edge.hxx>
30#include <TopoDS_Face.hxx>
31#include <TopAbs_ShapeEnum.hxx>
32#include <Precision.hxx>
7fd59977 33#include <BRepExtrema_UnCompatibleShape.hxx>
34#include <BRep_Tool.hxx>
35#include <BRepClass3d_SolidClassifier.hxx>
762b6cec 36#include <NCollection_Vector.hxx>
0f05f211 37#include <OSD_Parallel.hxx>
92d1589b 38#include <StdFail_NotDone.hxx>
7fd59977 39
3c162495 40#include <algorithm>
762b6cec 41namespace
7fd59977 42{
7fd59977 43
762b6cec 44 static void Decomposition(const TopoDS_Shape& S,
45 TopTools_IndexedMapOfShape& MapV,
46 TopTools_IndexedMapOfShape& MapE,
47 TopTools_IndexedMapOfShape& MapF)
48 {
49 MapV.Clear();
50 MapE.Clear();
51 MapF.Clear();
52 TopExp::MapShapes(S,TopAbs_VERTEX,MapV);
53 TopExp::MapShapes(S,TopAbs_EDGE,MapE);
54 TopExp::MapShapes(S,TopAbs_FACE,MapF);
55 }
56
57 static void BoxCalculation(const TopTools_IndexedMapOfShape& Map,
0f05f211 58 Bnd_Array1OfBox& SBox)
762b6cec 59 {
60 for (Standard_Integer i = 1; i <= Map.Extent(); i++)
61 {
62 Bnd_Box box;
63 BRepBndLib::Add(Map(i), box);
0f05f211 64 SBox[i] = box;
762b6cec 65 }
66 }
67
b2fedee6 68 inline Standard_Real DistanceInitiale(const TopoDS_Vertex& V1,
69 const TopoDS_Vertex& V2)
92d1589b 70 {
762b6cec 71 return (BRep_Tool::Pnt(V1).Distance(BRep_Tool::Pnt(V2)));
92d1589b 72 }
762b6cec 73
74 //! Pair of objects to check extrema.
75 struct BRepExtrema_CheckPair
76 {
77 Standard_Integer Index1; //!< Index of the 1st sub-shape
78 Standard_Integer Index2; //!< Index of the 2nd sub-shape
79 Standard_Real Distance; //!< Distance between sub-shapes
80
81 //! Uninitialized constructor for collection.
d533dafb 82 BRepExtrema_CheckPair()
83 : Index1(0),
84 Index2(0),
85 Distance(0.0)
86 {
87 }
762b6cec 88
89 //! Creates new pair of sub-shapes.
90 BRepExtrema_CheckPair (Standard_Integer theIndex1,
91 Standard_Integer theIndex2,
92 Standard_Real theDistance)
93 : Index1 (theIndex1),
94 Index2 (theIndex2),
95 Distance (theDistance) {}
96 };
762b6cec 97
3c162495 98 // Used by std::sort function
99 static Standard_Boolean BRepExtrema_CheckPair_Comparator (const BRepExtrema_CheckPair& theLeft,
100 const BRepExtrema_CheckPair& theRight)
762b6cec 101 {
3c162495 102 return (theLeft.Distance < theRight.Distance);
762b6cec 103 }
3c162495 104}
7fd59977 105
106//=======================================================================
0f05f211 107//struct : IndexBand
7fd59977 108//purpose :
109//=======================================================================
0f05f211 110struct IndexBand
111{
112 IndexBand():
113 First(0),
114 Last(0)
115 {
116 }
117
118 IndexBand(Standard_Integer theFirtsIndex,
119 Standard_Integer theLastIndex):
120 First(theFirtsIndex),
121 Last(theLastIndex)
122 {
123 }
124 Standard_Integer First;
125 Standard_Integer Last;
126};
7fd59977 127
0f05f211 128//=======================================================================
129//struct : ThreadSolution
130//purpose :
131//=======================================================================
132struct ThreadSolution
7fd59977 133{
0f05f211 134 ThreadSolution(Standard_Integer theTaskNum):
135 Shape1(0, theTaskNum-1),
136 Shape2(0, theTaskNum-1),
137 Dist(0, theTaskNum-1)
138 {
139 Dist.Init(DBL_MAX);
140 }
82bee162 141
0f05f211 142 NCollection_Array1<BRepExtrema_SeqOfSolution> Shape1;
143 NCollection_Array1<BRepExtrema_SeqOfSolution> Shape2;
144 NCollection_Array1<Standard_Real> Dist;
145};
82bee162 146
0f05f211 147//=======================================================================
148//struct : VertexFunctor
149//purpose :
150//=======================================================================
151struct VertexFunctor
152{
153 VertexFunctor(NCollection_Array1<IndexBand>* theBandArray,
154 const Message_ProgressRange& theRange):
155 BandArray(theBandArray),
156 Solution(theBandArray->Size()),
157 Map1(NULL),
158 Map2(NULL),
159 Scope(theRange, "Vertices distances calculating", theBandArray->Size()),
160 Ranges(0, theBandArray->Size() - 1),
161 Eps(Precision::Confusion()),
162 StartDist(0.0)
762b6cec 163 {
0f05f211 164 for (Standard_Integer i = 0; i < theBandArray->Size(); ++i)
82bee162 165 {
0f05f211 166 Ranges.SetValue(i, Scope.Next());
82bee162 167 }
0f05f211 168 }
169
170 void operator() (const Standard_Integer theIndex) const
171 {
172 const Standard_Integer aCount2 = Map2->Extent();
173 const Standard_Integer aFirst = BandArray->Value(theIndex).First;
174 const Standard_Integer aLast = BandArray->Value(theIndex).Last;
175 Solution.Dist[theIndex] = StartDist;
176
177 Message_ProgressScope aScope(Ranges[theIndex], NULL, (double)aLast - aFirst);
178
179
180 for (Standard_Integer anIdx1 = aFirst; anIdx1 <= aLast; ++anIdx1)
762b6cec 181 {
0f05f211 182 if (!aScope.More())
4d19a2c5 183 {
0f05f211 184 break;
4d19a2c5 185 }
0f05f211 186 aScope.Next();
4d19a2c5 187
0f05f211 188 const TopoDS_Vertex& aVertex1 = TopoDS::Vertex(Map1->FindKey(anIdx1));
189 const gp_Pnt aPoint1 = BRep_Tool::Pnt(aVertex1);
190 for (Standard_Integer anIdx2 = 1; anIdx2 <= aCount2; ++anIdx2)
762b6cec 191 {
0f05f211 192 const TopoDS_Vertex& aVertex2 = TopoDS::Vertex(Map2->FindKey(anIdx2));
193 const gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex2);
194 const Standard_Real aDist = aPoint1.Distance(aPoint2);
195 {
196 if (aDist < Solution.Dist[theIndex] - Eps)
197 {
198 const BRepExtrema_SolutionElem Sol1(aDist, aPoint1, BRepExtrema_IsVertex, aVertex1);
199 const BRepExtrema_SolutionElem Sol2(aDist, aPoint2, BRepExtrema_IsVertex, aVertex2);
200
201 Solution.Shape1[theIndex].Clear();
202 Solution.Shape2[theIndex].Clear();
203 Solution.Shape1[theIndex].Append(Sol1);
204 Solution.Shape2[theIndex].Append(Sol2);
205
206 Solution.Dist[theIndex] = aDist;
207 }
208 else if (Abs(aDist - Solution.Dist[theIndex]) < Eps)
209 {
210 const BRepExtrema_SolutionElem Sol1(aDist, aPoint1, BRepExtrema_IsVertex, aVertex1);
211 const BRepExtrema_SolutionElem Sol2(aDist, aPoint2, BRepExtrema_IsVertex, aVertex2);
212 Solution.Shape1[theIndex].Append(Sol1);
213 Solution.Shape2[theIndex].Append(Sol2);
214
215 if (Solution.Dist[theIndex] > aDist)
216 {
217 Solution.Dist[theIndex] = aDist;
218 }
219 }
220 }
762b6cec 221 }
222 }
223 }
0f05f211 224
225 NCollection_Array1<IndexBand>* BandArray;
226 mutable ThreadSolution Solution;
227 const TopTools_IndexedMapOfShape* Map1;
228 const TopTools_IndexedMapOfShape* Map2;
229 Message_ProgressScope Scope;
230 NCollection_Array1<Message_ProgressRange> Ranges;
231 Standard_Real Eps;
232 Standard_Real StartDist;
233};
234
235//=======================================================================
236//function : DistanceVertVert
237//purpose :
238//=======================================================================
239Standard_Boolean BRepExtrema_DistShapeShape::DistanceVertVert(const TopTools_IndexedMapOfShape& theMap1,
240 const TopTools_IndexedMapOfShape& theMap2,
241 const Message_ProgressRange& theRange)
242{
243 const Standard_Integer aCount1 = theMap1.Extent();
244 const Standard_Integer aMinTaskSize = aCount1 < 10 ? aCount1 : 10;
245 const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
246 const Standard_Integer aNbThreads = aThreadPool->NbThreads();
247 Standard_Integer aNbTasks = aNbThreads;
248 Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aCount1 / aNbTasks);
249 if (aTaskSize < aMinTaskSize)
92d1589b 250 {
0f05f211 251 aTaskSize = aMinTaskSize;
252 aNbTasks = (Standard_Integer) Ceiling((double) aCount1 / aTaskSize);
253 }
254
255 Standard_Integer aFirstIndex(1);
256 NCollection_Array1<IndexBand> aBandArray(0, aNbTasks - 1);
257 Message_ProgressScope aDistScope(theRange, NULL, 1);
258
259 for (Standard_Integer anI = 0; anI < aBandArray.Size(); ++anI)
260 {
261 if (aCount1 < aFirstIndex + aTaskSize - 1)
82bee162 262 {
0f05f211 263 aTaskSize = aCount1 - aFirstIndex + 1;
82bee162 264 }
0f05f211 265 aBandArray.SetValue(anI, IndexBand(aFirstIndex, aFirstIndex + aTaskSize - 1));
266 aFirstIndex += aTaskSize;
267 }
268
269 VertexFunctor aFunctor(&aBandArray, aDistScope.Next());
270 aFunctor.Map1 = &theMap1;
271 aFunctor.Map2 = &theMap2;
272 aFunctor.StartDist = myDistRef;
273 aFunctor.Eps = myEps;
274
275 OSD_Parallel::For(0, aNbTasks, aFunctor, !myIsMultiThread);
276 if (!aDistScope.More())
277 {
278 return Standard_False;
279 }
280 for (Standard_Integer anI = 0; anI < aFunctor.Solution.Dist.Size(); ++anI)
281 {
282 Standard_Real aDist = aFunctor.Solution.Dist[anI];
283 if (aDist < myDistRef - myEps)
92d1589b 284 {
0f05f211 285 mySolutionsShape1.Clear();
286 mySolutionsShape2.Clear();
287 mySolutionsShape1.Append(aFunctor.Solution.Shape1[anI]);
288 mySolutionsShape2.Append(aFunctor.Solution.Shape2[anI]);
289 myDistRef = aDist;
762b6cec 290 }
0f05f211 291 else if (Abs(aDist - myDistRef) < myEps)
292 {
293 mySolutionsShape1.Append(aFunctor.Solution.Shape1[anI]);
294 mySolutionsShape2.Append(aFunctor.Solution.Shape2[anI]);
295 myDistRef = aDist;
296 }
297 }
298 return Standard_True;
299}
92d1589b 300
0f05f211 301//=======================================================================
302//struct : DistanceFunctor
303//purpose :
304//=======================================================================
305struct DistanceFunctor
306{
307 DistanceFunctor(NCollection_Array1<NCollection_Array1<BRepExtrema_CheckPair> >* theArrayOfArrays,
308 const Message_ProgressRange& theRange):
309 ArrayOfArrays(theArrayOfArrays),
310 Solution(ArrayOfArrays->Size()),
311 Map1(NULL),
312 Map2(NULL),
313 LBox1(NULL),
314 LBox2(NULL),
315 Scope(theRange, "Shapes distances calculating", theArrayOfArrays->Size()),
316 Ranges(0, theArrayOfArrays->Size() - 1),
317 Eps(Precision::Confusion()),
318 StartDist(0.0)
319 {
320 for (Standard_Integer i = 0; i < theArrayOfArrays->Size(); ++i)
321 {
322 Ranges.SetValue(i, Scope.Next());
323 }
324 }
762b6cec 325
0f05f211 326 void operator() (const Standard_Integer theIndex) const
327 {
328 Message_ProgressScope aScope(Ranges[theIndex], NULL, ArrayOfArrays->Value(theIndex).Size());
329 Solution.Dist[theIndex] = StartDist;
330 for (Standard_Integer i = 0; i < ArrayOfArrays->Value(theIndex).Size(); i++)
762b6cec 331 {
0f05f211 332 if (!aScope.More())
762b6cec 333 {
0f05f211 334 return;
335 }
336 aScope.Next();
337 const BRepExtrema_CheckPair& aPair = ArrayOfArrays->Value(theIndex).Value(i);
338 if (aPair.Distance > Solution.Dist[theIndex] + Eps)
339 {
340 break; // early search termination
341 }
342 const Bnd_Box& aBox1 = LBox1->Value(aPair.Index1);
343 const Bnd_Box& aBox2 = LBox2->Value(aPair.Index2);
344 const TopoDS_Shape& aShape1 = Map1->FindKey(aPair.Index1);
345 const TopoDS_Shape& aShape2 = Map2->FindKey(aPair.Index2);
346 BRepExtrema_DistanceSS aDistTool(aShape1, aShape2, aBox1, aBox2, Solution.Dist[theIndex], Eps);
347 const Standard_Real aDist = aDistTool.DistValue();
348 if (aDistTool.IsDone())
349 {
350 if (aDist < Solution.Dist[theIndex] - Eps)
351 {
352 Solution.Shape1[theIndex].Clear();
353 Solution.Shape2[theIndex].Clear();
762b6cec 354
0f05f211 355 BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
356 BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
762b6cec 357
0f05f211 358 Solution.Shape1[theIndex].Append(aSeq1);
359 Solution.Shape2[theIndex].Append(aSeq2);
762b6cec 360
0f05f211 361 Solution.Dist[theIndex] = aDistTool.DistValue();
362 }
363 else if (Abs(aDist - Solution.Dist[theIndex]) < Eps)
364 {
365 BRepExtrema_SeqOfSolution aSeq1 = aDistTool.Seq1Value();
366 BRepExtrema_SeqOfSolution aSeq2 = aDistTool.Seq2Value();
367
368 Solution.Shape1[theIndex].Append(aSeq1);
369 Solution.Shape2[theIndex].Append(aSeq2);
370 if (Solution.Dist[theIndex] > aDist)
371 {
372 Solution.Dist[theIndex] = aDist;
373 }
374 }
762b6cec 375 }
0f05f211 376 }
377 }
378
379 NCollection_Array1<NCollection_Array1<BRepExtrema_CheckPair> >* ArrayOfArrays;
380 mutable ThreadSolution Solution;
381 const TopTools_IndexedMapOfShape* Map1;
382 const TopTools_IndexedMapOfShape* Map2;
383 const Bnd_Array1OfBox* LBox1;
384 const Bnd_Array1OfBox* LBox2;
385 Message_ProgressScope Scope;
386 NCollection_Array1<Message_ProgressRange> Ranges;
387 Standard_Real Eps;
388 Standard_Real StartDist;
389};
390
391
392//=======================================================================
393//struct : DistancePairFunctor
394//purpose :
395//=======================================================================
396struct DistancePairFunctor
397{
398 DistancePairFunctor(NCollection_Array1<IndexBand>* theBandArray,
399 const Message_ProgressRange& theRange):
400 BandArray(theBandArray),
401 PairList(0, theBandArray->Size() - 1),
402 LBox1(NULL),
403 LBox2(NULL),
404 Scope(theRange, "Boxes distances calculating", theBandArray->Size()),
405 Ranges(0, theBandArray->Size() - 1),
406 DistRef(0),
407 Eps(Precision::Confusion())
408 {
409 for (Standard_Integer i = 0; i < theBandArray->Size(); ++i)
410 {
411 Ranges.SetValue(i, Scope.Next());
412 }
413 }
414
415 void operator() (const Standard_Integer theIndex) const
416 {
417 const Standard_Integer aFirst = BandArray->Value(theIndex).First;
418 const Standard_Integer aLast = BandArray->Value(theIndex).Last;
419
420 Message_ProgressScope aScope(Ranges[theIndex], NULL, (double) aLast - aFirst);
421
422 for (Standard_Integer anIdx1 = aFirst; anIdx1 <= aLast; ++anIdx1)
423 {
424 if (!aScope.More())
762b6cec 425 {
0f05f211 426 break;
427 }
428 aScope.Next();
762b6cec 429
0f05f211 430 for (Standard_Integer anIdx2 = 1; anIdx2 <= LBox2->Size(); ++anIdx2)
431 {
432 const Bnd_Box& aBox1 = LBox1->Value(anIdx1);
433 const Bnd_Box& aBox2 = LBox2->Value(anIdx2);
434 if (aBox1.IsVoid() || aBox2.IsVoid())
435 {
436 continue;
437 }
762b6cec 438
0f05f211 439 const Standard_Real aDist = aBox1.Distance(aBox2);
440 if (aDist - DistRef < Eps)
92d1589b 441 {
0f05f211 442 PairList[theIndex].Append(BRepExtrema_CheckPair(anIdx1, anIdx2, aDist));
7fd59977 443 }
eafb234b 444 }
7fd59977 445 }
446 }
0f05f211 447
448 Standard_Integer ListSize()
449 {
450 Standard_Integer aSize(0);
451 for (Standard_Integer anI = PairList.Lower(); anI <= PairList.Upper(); ++anI)
452 {
453 aSize += PairList[anI].Size();
454 }
455 return aSize;
456 }
457
458 NCollection_Array1<IndexBand>* BandArray;
459 mutable NCollection_Array1<NCollection_Vector<BRepExtrema_CheckPair> > PairList;
460 const Bnd_Array1OfBox* LBox1;
461 const Bnd_Array1OfBox* LBox2;
462 Message_ProgressScope Scope;
463 NCollection_Array1<Message_ProgressRange> Ranges;
464 Standard_Real DistRef;
465 Standard_Real Eps;
466};
7fd59977 467
92c1f972 468//=======================================================================
0f05f211 469//function : DistanceMapMap
92c1f972 470//purpose :
471//=======================================================================
472
0f05f211 473Standard_Boolean BRepExtrema_DistShapeShape::DistanceMapMap (const TopTools_IndexedMapOfShape& theMap1,
474 const TopTools_IndexedMapOfShape& theMap2,
475 const Bnd_Array1OfBox& theLBox1,
476 const Bnd_Array1OfBox& theLBox2,
477 const Message_ProgressRange& theRange)
92c1f972 478{
479 const Standard_Integer aCount1 = theMap1.Extent();
480 const Standard_Integer aCount2 = theMap2.Extent();
481
0f05f211 482 if (aCount1 == 0 || aCount2 == 0)
483 {
484 return Standard_True;
485 }
486
487 Message_ProgressScope aTwinScope(theRange, NULL, 1.0);
92c1f972 488
0f05f211 489 const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
490 const Standard_Integer aNbThreads = aThreadPool->NbThreads();
491 const Standard_Integer aMinPairTaskSize = aCount1 < 10 ? aCount1 : 10;
492 Standard_Integer aNbPairTasks = aNbThreads;
493 Standard_Integer aPairTaskSize = (Standard_Integer) Ceiling((double) aCount1 / aNbPairTasks);
494 if (aPairTaskSize < aMinPairTaskSize)
92c1f972 495 {
0f05f211 496 aPairTaskSize = aMinPairTaskSize;
497 aNbPairTasks = (Standard_Integer) Ceiling((double) aCount1 / aPairTaskSize);
498 }
499
500 Standard_Integer aFirstIndex(1);
501 NCollection_Array1<IndexBand> aBandArray(0, aNbPairTasks - 1);
502
503 for (Standard_Integer anI = 0; anI < aBandArray.Size(); ++anI)
504 {
505 if (aCount1 < aFirstIndex + aPairTaskSize - 1)
92c1f972 506 {
0f05f211 507 aPairTaskSize = aCount1 - aFirstIndex + 1;
92c1f972 508 }
0f05f211 509 aBandArray.SetValue(anI, IndexBand(aFirstIndex, aFirstIndex + aPairTaskSize - 1));
510 aFirstIndex += aPairTaskSize;
511 }
92c1f972 512
0f05f211 513 aTwinScope.Next(0.15);
514 DistancePairFunctor aPairFunctor(&aBandArray, aTwinScope.Next(0.15));
515 aPairFunctor.LBox1 = &theLBox1;
516 aPairFunctor.LBox2 = &theLBox2;
517 aPairFunctor.DistRef = myDistRef;
518 aPairFunctor.Eps = myEps;
92c1f972 519
0f05f211 520 OSD_Parallel::For(0, aNbPairTasks, aPairFunctor, !myIsMultiThread);
521 if (!aTwinScope.More())
522 {
523 return Standard_False;
524 }
525 Standard_Integer aListSize = aPairFunctor.ListSize();
526 if(aListSize == 0)
527 {
528 return Standard_True;
529 }
530 NCollection_Array1<BRepExtrema_CheckPair> aPairList(0, aListSize-1);
531 Standard_Integer aListIndex(0);
532 for (Standard_Integer anI = 0; anI < aPairFunctor.PairList.Size(); ++anI)
533 {
534 for (Standard_Integer aJ = 0; aJ < aPairFunctor.PairList[anI].Size(); ++aJ)
535 {
536 aPairList[aListIndex] = aPairFunctor.PairList[anI][aJ];
537 ++aListIndex;
538 }
539 }
92c1f972 540
0f05f211 541 std::stable_sort(aPairList.begin(), aPairList.end(), BRepExtrema_CheckPair_Comparator);
92c1f972 542
0f05f211 543 const Standard_Integer aMapSize = aPairList.Size();
544 Standard_Integer aNbTasks = aMapSize < aNbThreads ? aMapSize : aNbThreads;
545 Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aMapSize / aNbTasks);
546
547 NCollection_Array1<NCollection_Array1<BRepExtrema_CheckPair> > anArrayOfArray(0, aNbTasks - 1);
548 // Since aPairList is sorted in ascending order of distances between Bnd_Boxes,
549 // BRepExtrema_CheckPair are distributed to tasks one by one from smallest to largest,
550 // and not ranges, as for DistancePairFunctor.
551 // Since aMapSize may not be divisible entirely by the number of tasks,
552 // some tasks should receive one BRepExtrema_CheckPair less than the rest.
553 // aLastRowLimit defines the task number from which to start tasks containing
554 // fewer BRepExtrema_CheckPair
555 Standard_Integer aLastRowLimit = ((aMapSize % aNbTasks) == 0) ? aNbTasks : (aMapSize % aNbTasks);
556 for (Standard_Integer anI = 0; anI < aTaskSize; ++anI)
557 {
558 for (Standard_Integer aJ = 0; aJ < aNbTasks; ++aJ)
559 {
560 if (anI == 0)
561 {
562 Standard_Integer aVectorSize = aTaskSize;
563 if (aJ >= aLastRowLimit)
92c1f972 564 {
0f05f211 565 aVectorSize--;
92c1f972 566 }
0f05f211 567 anArrayOfArray[aJ].Resize(0, aVectorSize - 1, Standard_False);
568 }
569 if (anI < anArrayOfArray[aJ].Size())
570 {
571 anArrayOfArray[aJ][anI] = aPairList(anI*aNbTasks + aJ);
572 }
573 else
574 {
575 break;
576 }
577 }
578 }
579 DistanceFunctor aFunctor(&anArrayOfArray, aTwinScope.Next(0.85));
580 aFunctor.Map1 = &theMap1;
581 aFunctor.Map2 = &theMap2;
582 aFunctor.LBox1 = &theLBox1;
583 aFunctor.LBox2 = &theLBox2;
584 aFunctor.Eps = myEps;
585 aFunctor.StartDist = myDistRef;
586
587 OSD_Parallel::For(0, aNbTasks, aFunctor, !myIsMultiThread);
588 if (!aTwinScope.More())
589 {
590 return Standard_False;
591 }
592
593 for (Standard_Integer anI = 0; anI < aFunctor.Solution.Dist.Size(); ++anI)
594 {
595 Standard_Real aDist = aFunctor.Solution.Dist[anI];
596 if (aDist < myDistRef - myEps)
597 {
598 mySolutionsShape1.Clear();
599 mySolutionsShape2.Clear();
600 mySolutionsShape1.Append(aFunctor.Solution.Shape1[anI]);
601 mySolutionsShape2.Append(aFunctor.Solution.Shape2[anI]);
602 myDistRef = aDist;
603 }
604 else if (Abs(aDist - myDistRef) < myEps)
605 {
606 mySolutionsShape1.Append(aFunctor.Solution.Shape1[anI]);
607 mySolutionsShape2.Append(aFunctor.Solution.Shape2[anI]);
608 if (myDistRef > aDist)
609 {
610 myDistRef = aDist;
92c1f972 611 }
612 }
613 }
614 return Standard_True;
615}
616
7fd59977 617//=======================================================================
618//function : BRepExtrema_DistShapeShape
619//purpose :
620//=======================================================================
621
622BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape()
762b6cec 623: myDistRef (0.0),
624 myIsDone (Standard_False),
625 myInnerSol (Standard_False),
626 myEps (Precision::Confusion()),
627 myIsInitS1 (Standard_False),
628 myIsInitS2 (Standard_False),
629 myFlag (Extrema_ExtFlag_MINMAX),
0f05f211 630 myAlgo (Extrema_ExtAlgo_Grad),
631 myIsMultiThread(Standard_False)
7fd59977 632{
7fd59977 633}
634
635//=======================================================================
636//function : BRepExtrema_DistShapeShape
637//purpose :
638//=======================================================================
639BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
92d1589b
A
640 const TopoDS_Shape& Shape2,
641 const Extrema_ExtFlag F,
82bee162 642 const Extrema_ExtAlgo A,
643 const Message_ProgressRange& theRange)
762b6cec 644: myDistRef (0.0),
645 myIsDone (Standard_False),
646 myInnerSol (Standard_False),
647 myEps (Precision::Confusion()),
648 myIsInitS1 (Standard_False),
649 myIsInitS2 (Standard_False),
650 myFlag (F),
0f05f211 651 myAlgo (A),
652 myIsMultiThread(Standard_False)
7fd59977 653{
7fd59977 654 LoadS1(Shape1);
655 LoadS2(Shape2);
82bee162 656 Perform(theRange);
7fd59977 657}
658
659//=======================================================================
660//function : BRepExtrema_DistShapeShape
661//purpose :
662//=======================================================================
663
664BRepExtrema_DistShapeShape::BRepExtrema_DistShapeShape(const TopoDS_Shape& Shape1,
92d1589b
A
665 const TopoDS_Shape& Shape2,
666 const Standard_Real theDeflection,
667 const Extrema_ExtFlag F,
82bee162 668 const Extrema_ExtAlgo A,
669 const Message_ProgressRange& theRange)
762b6cec 670: myDistRef (0.0),
671 myIsDone (Standard_False),
672 myInnerSol (Standard_False),
673 myEps (theDeflection),
674 myIsInitS1 (Standard_False),
675 myIsInitS2 (Standard_False),
676 myFlag (F),
0f05f211 677 myAlgo (A),
678 myIsMultiThread(Standard_False)
7fd59977 679{
7fd59977 680 LoadS1(Shape1);
681 LoadS2(Shape2);
82bee162 682 Perform(theRange);
7fd59977 683}
684
7fd59977 685//=======================================================================
686//function : LoadS1
687//purpose :
688//=======================================================================
689
762b6cec 690void BRepExtrema_DistShapeShape::LoadS1 (const TopoDS_Shape& Shape1)
7fd59977 691{
692 myShape1 = Shape1;
762b6cec 693 myIsInitS1 = Standard_False;
694 Decomposition (Shape1, myMapV1, myMapE1, myMapF1);
7fd59977 695}
696
697//=======================================================================
698//function : LoadS2
699//purpose :
700//=======================================================================
701
762b6cec 702void BRepExtrema_DistShapeShape::LoadS2 (const TopoDS_Shape& Shape2)
7fd59977 703{
704 myShape2 = Shape2;
762b6cec 705 myIsInitS2 = Standard_False;
706 Decomposition (Shape2, myMapV2, myMapE2, myMapF2);
7fd59977 707}
708
0f05f211 709//=======================================================================
710//struct : TreatmentFunctor
711//purpose :
712//=======================================================================
713struct TreatmentFunctor
714{
715 TreatmentFunctor(NCollection_Array1<NCollection_Array1<TopoDS_Shape> >* theArrayOfArrays,
716 const Message_ProgressRange& theRange):
717 ArrayOfArrays(theArrayOfArrays),
718 SolutionsShape1(NULL),
719 SolutionsShape2(NULL),
720 Scope(theRange, "Search for the inner solid", theArrayOfArrays->Size()),
721 Ranges(0, theArrayOfArrays->Size() - 1),
722 DistRef(0),
723 InnerSol(NULL),
724 IsDone(NULL),
725 Mutex(NULL)
726 {
727 for (Standard_Integer i = 0; i < theArrayOfArrays->Size(); ++i)
728 {
729 Ranges.SetValue(i, Scope.Next());
730 }
731 }
732
733 void operator() (const Standard_Integer theIndex) const
734 {
735 const Standard_Real aTolerance = 0.001;
736 Message_ProgressScope aScope(Ranges[theIndex], NULL, ArrayOfArrays->Value(theIndex).Size());
737 BRepClass3d_SolidClassifier aClassifier(Shape);
738
739 for (Standard_Integer i = 0; i < ArrayOfArrays->Value(theIndex).Size(); i++)
740 {
741 if (!aScope.More())
742 {
743 break;
744 }
745 aScope.Next();
746 if (*IsDone)
747 {
748 break;
749 }
750
751 const TopoDS_Vertex& aVertex = TopoDS::Vertex(ArrayOfArrays->Value(theIndex).Value(i));
752 const gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
753 aClassifier.Perform(aPnt, aTolerance);
754 if (aClassifier.State() == TopAbs_IN)
755 {
756 Standard_Mutex::Sentry aLock(Mutex.get());
757 *InnerSol = Standard_True;
758 *DistRef = 0.;
759 *IsDone = Standard_True;
760 BRepExtrema_SolutionElem aSolElem(0, aPnt, BRepExtrema_IsVertex, aVertex);
761 SolutionsShape1->Append(aSolElem);
762 SolutionsShape2->Append(aSolElem);
763 break;
764 }
765 }
766 }
767
768 NCollection_Array1<NCollection_Array1<TopoDS_Shape> >* ArrayOfArrays;
769 BRepExtrema_SeqOfSolution* SolutionsShape1;
770 BRepExtrema_SeqOfSolution* SolutionsShape2;
771 TopoDS_Shape Shape;
772 Message_ProgressScope Scope;
773 NCollection_Array1<Message_ProgressRange> Ranges;
774 Standard_Real* DistRef;
775 volatile Standard_Boolean* InnerSol;
776 volatile Standard_Boolean* IsDone;
777 Handle(Standard_HMutex) Mutex;
778};
779
82bee162 780//=======================================================================
781//function : SolidTreatment
782//purpose :
783//=======================================================================
784Standard_Boolean BRepExtrema_DistShapeShape::SolidTreatment(const TopoDS_Shape& theShape,
0f05f211 785 const TopTools_IndexedMapOfShape& theVertexMap,
82bee162 786 const Message_ProgressRange& theRange)
787{
0f05f211 788 const Standard_Integer aMapSize = theVertexMap.Extent();
789 const Standard_Integer aMinTaskSize = 3;
790 const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
791 const Standard_Integer aNbThreads = aThreadPool->NbThreads();
792 Standard_Integer aNbTasks = aNbThreads * 10;
793 Standard_Integer aTaskSize = (Standard_Integer) Ceiling((double) aMapSize / aNbTasks);
794 if (aTaskSize < aMinTaskSize)
82bee162 795 {
0f05f211 796 aTaskSize = aMinTaskSize;
797 aNbTasks = (Standard_Integer) Ceiling((double) aMapSize / aTaskSize);
798 }
799
800 NCollection_Array1< NCollection_Array1<TopoDS_Shape> > anArrayOfArray(0, aNbTasks - 1);
801 for (Standard_Integer anI = 1; anI <= aMapSize; ++anI)
802 {
803 Standard_Integer aVectIndex = (anI - 1) / aTaskSize;
804 Standard_Integer aShapeIndex = (anI - 1) % aTaskSize;
805 if (aShapeIndex == 0)
82bee162 806 {
0f05f211 807 Standard_Integer aVectorSize = aTaskSize;
808 Standard_Integer aTailSize = aMapSize - aVectIndex * aTaskSize;
809 if (aTailSize < aTaskSize)
810 {
811 aVectorSize = aTailSize;
812 }
813 anArrayOfArray[aVectIndex].Resize(0, aVectorSize - 1, Standard_False);
82bee162 814 }
0f05f211 815 anArrayOfArray[aVectIndex][aShapeIndex] = theVertexMap(anI);
816 }
817
818 Message_ProgressScope aScope(theRange, "Solid treatment", aNbTasks);
819 TreatmentFunctor aFunctor(&anArrayOfArray, aScope.Next());
820 aFunctor.SolutionsShape1 = &mySolutionsShape1;
821 aFunctor.SolutionsShape2 = &mySolutionsShape2;
822 aFunctor.Shape = theShape;
823 aFunctor.DistRef = &myDistRef;
824 aFunctor.InnerSol = &myInnerSol;
825 aFunctor.IsDone = &myIsDone;
826 if (myIsMultiThread)
827 {
828 aFunctor.Mutex.reset(new Standard_HMutex());
829 }
830
831 OSD_Parallel::For(0, aNbTasks, aFunctor, !myIsMultiThread);
832
833 if (!aScope.More())
834 {
835 return Standard_False;
82bee162 836 }
837 return Standard_True;
838}
839
7fd59977 840//=======================================================================
841//function : Perform
842//purpose :
843//=======================================================================
844
82bee162 845Standard_Boolean BRepExtrema_DistShapeShape::Perform(const Message_ProgressRange& theRange)
7fd59977 846{
0f05f211 847 myIsDone = Standard_False;
848 myInnerSol = Standard_False;
92d1589b
A
849 mySolutionsShape1.Clear();
850 mySolutionsShape2.Clear();
851
0f05f211 852 if (myShape1.IsNull() || myShape2.IsNull())
7fd59977 853 return Standard_False;
854
92d1589b 855 // Treatment of solids
82bee162 856 Standard_Boolean anIsSolid1 = (myShape1.ShapeType() == TopAbs_SOLID) ||
0f05f211 857 (myShape1.ShapeType() == TopAbs_COMPSOLID);
82bee162 858 Standard_Boolean anIsSolid2 = (myShape2.ShapeType() == TopAbs_SOLID) ||
0f05f211 859 (myShape2.ShapeType() == TopAbs_COMPSOLID);
82bee162 860 Standard_Integer aRootStepsNum = 9; // By num of DistanceMapMap calls
0f05f211 861 aRootStepsNum = anIsSolid1 ? aRootStepsNum + 1 : aRootStepsNum;
862 aRootStepsNum = anIsSolid2 ? aRootStepsNum + 1 : aRootStepsNum;
82bee162 863 Message_ProgressScope aRootScope(theRange, "calculating distance", aRootStepsNum);
864
865 if (anIsSolid1)
92d1589b 866 {
82bee162 867 if (!SolidTreatment(myShape1, myMapV2, aRootScope.Next()))
1aeb969a 868 {
82bee162 869 return Standard_False;
1aeb969a 870 }
7fd59977 871 }
0f05f211 872
82bee162 873 if (anIsSolid2 && (!myInnerSol))
92d1589b 874 {
0f05f211 875 if (!SolidTreatment(myShape2, myMapV1, aRootScope.Next()))
1aeb969a 876 {
82bee162 877 return Standard_False;
1aeb969a 878 }
7fd59977 879 }
762b6cec 880
92d1589b
A
881 if (!myInnerSol)
882 {
762b6cec 883 if (!myIsInitS1) // rebuild cached data for 1st shape
884 {
0f05f211 885 if (!myMapV1.IsEmpty())
886 {
887 myBV1.Resize(1, myMapV1.Extent(), Standard_False);
888 }
889 if (!myMapE1.IsEmpty())
890 {
891 myBE1.Resize(1, myMapE1.Extent(), Standard_False);
892 }
893 if (!myMapF1.IsEmpty())
894 {
895 myBF1.Resize(1, myMapF1.Extent(), Standard_False);
896 }
762b6cec 897
898 BoxCalculation (myMapV1, myBV1);
899 BoxCalculation (myMapE1, myBE1);
900 BoxCalculation (myMapF1, myBF1);
901
902 myIsInitS1 = Standard_True;
903 }
904
905 if (!myIsInitS2) // rebuild cached data for 2nd shape
906 {
0f05f211 907 if (!myMapV2.IsEmpty())
908 {
909 myBV2.Resize(1, myMapV2.Extent(), Standard_False);
910 }
911 if (!myMapE2.IsEmpty())
912 {
913 myBE2.Resize(1, myMapE2.Extent(), Standard_False);
914 }
915 if (!myMapF2.IsEmpty())
916 {
917 myBF2.Resize(1, myMapF2.Extent(), Standard_False);
918 }
762b6cec 919
920 BoxCalculation (myMapV2, myBV2);
921 BoxCalculation (myMapE2, myBE2);
922 BoxCalculation (myMapF2, myBF2);
923
924 myIsInitS2 = Standard_True;
925 }
926
92d1589b
A
927 if (myMapV1.Extent() && myMapV2.Extent())
928 {
0f05f211 929 const TopoDS_Vertex& V1 = TopoDS::Vertex(myMapV1(1));
930 const TopoDS_Vertex& V2 = TopoDS::Vertex(myMapV2(1));
92d1589b 931 myDistRef = DistanceInitiale(V1, V2);
7fd59977 932 }
933 else
0f05f211 934 myDistRef = 1.e30; //szv:!!!
92d1589b 935
0f05f211 936 if (!DistanceVertVert(myMapV1, myMapV2, aRootScope.Next()))
82bee162 937 {
938 return Standard_False;
939 }
0f05f211 940 if (!DistanceMapMap(myMapV1, myMapE2, myBV1, myBE2, aRootScope.Next()))
82bee162 941 {
942 return Standard_False;
943 }
0f05f211 944 if (!DistanceMapMap(myMapE1, myMapV2, myBE1, myBV2, aRootScope.Next()))
82bee162 945 {
946 return Standard_False;
947 }
0f05f211 948 if (!DistanceMapMap(myMapV1, myMapF2, myBV1, myBF2, aRootScope.Next()))
82bee162 949 {
950 return Standard_False;
951 }
0f05f211 952 if (!DistanceMapMap(myMapF1, myMapV2, myBF1, myBV2, aRootScope.Next()))
82bee162 953 {
954 return Standard_False;
955 }
0f05f211 956 if (!DistanceMapMap(myMapE1, myMapE2, myBE1, myBE2, aRootScope.Next()))
82bee162 957 {
958 return Standard_False;
959 }
0f05f211 960 if (!DistanceMapMap(myMapE1, myMapF2, myBE1, myBF2, aRootScope.Next()))
82bee162 961 {
962 return Standard_False;
963 }
0f05f211 964 if (!DistanceMapMap(myMapF1, myMapE2, myBF1, myBE2, aRootScope.Next()))
82bee162 965 {
966 return Standard_False;
967 }
762b6cec 968
0f05f211 969 if (Abs(myDistRef) > myEps)
762b6cec 970 {
0f05f211 971 if (!DistanceMapMap(myMapF1, myMapF2, myBF1, myBF2, aRootScope.Next()))
82bee162 972 {
973 return Standard_False;
974 }
762b6cec 975 }
0f05f211 976
7fd59977 977 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:03 2001 Begin
92d1589b
A
978 Standard_Integer i = 1;
979 for (; i <= mySolutionsShape1.Length(); i++)
980 if (mySolutionsShape1.Value(i).Dist() > myDistRef + myEps)
981 {
982 mySolutionsShape1.Remove(i);
983 mySolutionsShape2.Remove(i);
7fd59977 984 }
985 // Modified by Sergey KHROMOV - Tue Mar 6 11:55:04 2001 End
0f05f211 986 myIsDone = (mySolutionsShape1.Length() > 0);
7fd59977 987 }
82bee162 988
7fd59977 989 return myIsDone;
990}
991
7fd59977 992//=======================================================================
993//function : Value
994//purpose :
995//=======================================================================
996
997Standard_Real BRepExtrema_DistShapeShape::Value() const
998{
92d1589b 999 if (!myIsDone)
9775fa61 1000 throw StdFail_NotDone("BRepExtrema_DistShapeShape::Value: There's no solution ");
7fd59977 1001
92d1589b 1002 return myDistRef;
7fd59977 1003}
1004
1005//=======================================================================
1006//function : SupportOnShape1
1007//purpose :
1008//=======================================================================
1009
92d1589b 1010TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape1(const Standard_Integer N) const
7fd59977 1011{
92d1589b 1012 if (!myIsDone)
9775fa61 1013 throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape1: There's no solution ");
92d1589b
A
1014
1015 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
1016 switch (sol.SupportKind())
1017 {
1018 case BRepExtrema_IsVertex : return sol.Vertex();
1019 case BRepExtrema_IsOnEdge : return sol.Edge();
1020 case BRepExtrema_IsInFace : return sol.Face();
1021 }
1022 return TopoDS_Shape();
7fd59977 1023}
1024
1025//=======================================================================
1026//function : SupportOnShape2
1027//purpose :
1028//=======================================================================
1029
1030TopoDS_Shape BRepExtrema_DistShapeShape::SupportOnShape2(const Standard_Integer N) const
1031{
92d1589b 1032 if (!myIsDone)
9775fa61 1033 throw StdFail_NotDone("BRepExtrema_DistShapeShape::SupportOnShape2: There's no solution ");
92d1589b
A
1034
1035 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
1036 switch (sol.SupportKind())
1037 {
1038 case BRepExtrema_IsVertex : return sol.Vertex();
1039 case BRepExtrema_IsOnEdge : return sol.Edge();
1040 case BRepExtrema_IsInFace : return sol.Face();
1041 }
1042 return TopoDS_Shape();
7fd59977 1043}
1044
1045//=======================================================================
1046//function : ParOnEdgeS1
1047//purpose :
1048//=======================================================================
1049
1050void BRepExtrema_DistShapeShape::ParOnEdgeS1(const Standard_Integer N, Standard_Real& t) const
1051{
92d1589b 1052 if (!myIsDone)
9775fa61 1053 throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS1: There's no solution");
92d1589b
A
1054
1055 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
1056 if (sol.SupportKind() != BRepExtrema_IsOnEdge)
9775fa61 1057 throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS1: ParOnEdgeS1 is impossible without EDGE");
92d1589b
A
1058
1059 sol.EdgeParameter(t);
7fd59977 1060}
1061
1062//=======================================================================
1063//function : ParOnEdgeS2
1064//purpose :
1065//=======================================================================
1066
1067void BRepExtrema_DistShapeShape::ParOnEdgeS2(const Standard_Integer N, Standard_Real& t) const
1068{
92d1589b 1069 if (!myIsDone)
9775fa61 1070 throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnEdgeS2: There's no solution");
92d1589b
A
1071
1072 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
1073 if (sol.SupportKind() != BRepExtrema_IsOnEdge)
9775fa61 1074 throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnEdgeS2: ParOnEdgeS2 is impossible without EDGE");
7fd59977 1075
92d1589b 1076 sol.EdgeParameter(t);
7fd59977 1077}
1078
1079//=======================================================================
1080//function : ParOnFaceS1
1081//purpose :
1082//=======================================================================
1083
1084void BRepExtrema_DistShapeShape::ParOnFaceS1(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
1085{
92d1589b 1086 if (!myIsDone)
9775fa61 1087 throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS1: There's no solution");
92d1589b
A
1088
1089 const BRepExtrema_SolutionElem &sol = mySolutionsShape1.Value(N);
1090 if (sol.SupportKind() != BRepExtrema_IsInFace)
9775fa61 1091 throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS1: ParOnFaceS1 is impossible without FACE");
7fd59977 1092
92d1589b 1093 sol.FaceParameter(u, v);
7fd59977 1094}
1095
92d1589b
A
1096//=======================================================================
1097//function : ParOnFaceS2
1098//purpose :
1099//=======================================================================
1100
7fd59977 1101void BRepExtrema_DistShapeShape::ParOnFaceS2(const Standard_Integer N, Standard_Real& u, Standard_Real& v) const
1102{
92d1589b 1103 if (!myIsDone)
9775fa61 1104 throw StdFail_NotDone("BRepExtrema_DistShapeShape::ParOnFaceS2: There's no solution");
7fd59977 1105
92d1589b
A
1106 const BRepExtrema_SolutionElem &sol = mySolutionsShape2.Value(N);
1107 if (sol.SupportKind() != BRepExtrema_IsInFace)
9775fa61 1108 throw BRepExtrema_UnCompatibleShape("BRepExtrema_DistShapeShape::ParOnFaceS2:ParOnFaceS2 is impossible without FACE ");
92d1589b
A
1109
1110 sol.FaceParameter(u, v);
7fd59977 1111}
1112
1113//=======================================================================
1114//function : Dump
1115//purpose :
1116//=======================================================================
1117
1118void BRepExtrema_DistShapeShape::Dump(Standard_OStream& o) const
1119{
1120 Standard_Integer i;
1121 Standard_Real r1,r2;
7fd59977 1122
04232180 1123 o<< "the distance value is : " << Value()<<std::endl;
1124 o<< "the number of solutions is :"<<NbSolution()<<std::endl;
1125 o<<std::endl;
92d1589b
A
1126 for (i=1;i<=NbSolution();i++)
1127 {
04232180 1128 o<<"solution number "<<i<<": "<< std::endl;
1129 o<<"the type of the solution on the first shape is " <<Standard_Integer( SupportTypeShape1(i)) <<std::endl;
1130 o<<"the type of the solution on the second shape is "<<Standard_Integer( SupportTypeShape2(i))<< std::endl;
1131 o<< "the coordinates of the point on the first shape are: "<<std::endl;
1132 o<<"X=" <<PointOnShape1(i).X()<<" Y=" <<PointOnShape1(i).Y()<<" Z="<<PointOnShape1(i).Z()<<std::endl;
1133 o<< "the coordinates of the point on the second shape are: "<<std::endl;
1134 o<<"X="<< PointOnShape2(i).X()<< " Y="<<PointOnShape2(i).Y()<<" Z="<< PointOnShape2(i).Z()<<std::endl;
7fd59977 1135
92d1589b
A
1136 switch (SupportTypeShape1(i))
1137 {
566f8441 1138 case BRepExtrema_IsVertex:
1139 break;
92d1589b
A
1140 case BRepExtrema_IsOnEdge:
1141 ParOnEdgeS1(i,r1);
04232180 1142 o << "parameter on the first edge : t= " << r1 << std::endl;
92d1589b
A
1143 break;
1144 case BRepExtrema_IsInFace:
1145 ParOnFaceS1(i,r1,r2);
04232180 1146 o << "parameters on the first face : u= " << r1 << " v=" << r2 << std::endl;
92d1589b
A
1147 break;
1148 }
1149 switch (SupportTypeShape2(i))
1150 {
566f8441 1151 case BRepExtrema_IsVertex:
1152 break;
92d1589b
A
1153 case BRepExtrema_IsOnEdge:
1154 ParOnEdgeS2(i,r1);
04232180 1155 o << "parameter on the second edge : t=" << r1 << std::endl;
92d1589b
A
1156 break;
1157 case BRepExtrema_IsInFace:
1158 ParOnFaceS2(i,r1,r2);
04232180 1159 o << "parameters on the second face : u= " << r1 << " v=" << r2 << std::endl;
92d1589b
A
1160 break;
1161 }
04232180 1162 o<<std::endl;
7fd59977 1163 }
1164}