Commit | Line | Data |
---|---|---|
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 | 41 | namespace |
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 | 110 | struct 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 | //======================================================================= | |
132 | struct 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 | //======================================================================= | |
151 | struct 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 | //======================================================================= | |
239 | Standard_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 | //======================================================================= | |
305 | struct 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 | //======================================================================= | |
396 | struct 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 | 473 | Standard_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 | ||
622 | BRepExtrema_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 | //======================================================================= | |
639 | BRepExtrema_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 | ||
664 | BRepExtrema_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 | 690 | void 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 | 702 | void 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 | //======================================================================= | |
713 | struct 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 | //======================================================================= | |
784 | Standard_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 | 845 | Standard_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 | ||
997 | Standard_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 | 1010 | TopoDS_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 | ||
1030 | TopoDS_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 | ||
1050 | void 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 | ||
1067 | void 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 | ||
1084 | void 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 | 1101 | void 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 | ||
1118 | void 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 | } |