0032539: Modeling Algorithms - Parallelize BRepExtrema_DistShapeShape algorithm
[occt.git] / src / BRepExtrema / BRepExtrema_DistanceSS.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.
7fd59977 16
92d1589b
A
17// Modified: Sergey ZERCHANINOV
18
19#include <BRepExtrema_DistanceSS.hxx>
7fd59977 20
7fd59977 21#include <TopTools_IndexedMapOfShape.hxx>
22#include <TopExp.hxx>
23#include <gp_Pnt.hxx>
24#include <gp_Pnt2d.hxx>
25#include <BRep_Tool.hxx>
26#include <BRepExtrema_SupportType.hxx>
7fd59977 27#include <Standard_Real.hxx>
28#include <BRepExtrema_SolutionElem.hxx>
29#include <BRepExtrema_SeqOfSolution.hxx>
30#include <Standard_Boolean.hxx>
31#include <Standard_Integer.hxx>
32#include <TopAbs_ShapeEnum.hxx>
33#include <TopoDS.hxx>
34#include <Bnd_Box.hxx>
35#include <BRepExtrema_ExtPC.hxx>
36#include <BRepExtrema_ExtPF.hxx>
92d1589b 37#include <Extrema_ExtFlag.hxx>
7fd59977 38#include <BRepExtrema_ExtCC.hxx>
39#include <BRepExtrema_ExtCF.hxx>
40#include <BRepExtrema_ExtFF.hxx>
41#include <BRepClass_FaceClassifier.hxx>
42#include <TopAbs.hxx>
43#include <Geom_Curve.hxx>
44#include <GeomAbs_Shape.hxx>
45#include <GeomAdaptor_Curve.hxx>
46#include <TColStd_Array1OfReal.hxx>
47#include <BRepBuilderAPI_MakeVertex.hxx>
48#include <BRepBuilderAPI_MakeEdge.hxx>
49#include <BRepBuilderAPI_MakeFace.hxx>
50#include <Geom_Surface.hxx>
51#include <GeomAPI_ProjectPointOnSurf.hxx>
52#include <GeomAPI_ProjectPointOnCurve.hxx>
53#include <Geom_RectangularTrimmedSurface.hxx>
54#include <Geom_TrimmedCurve.hxx>
55#include <BRepBndLib.hxx>
56#include <BRepTools.hxx>
57#include <TColgp_Array1OfPnt.hxx>
58
59
7fd59977 60/*********************************************************************************/
61
62//------------------------------------------------------------------------------
63// function: TRI_SOLUTION
64//------------------------------------------------------------------------------
92d1589b 65static Standard_Boolean TRI_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol, const gp_Pnt& Pt)
7fd59977 66{
0f05f211 67 for (BRepExtrema_SeqOfSolution::iterator anIt = SeqSol.begin(); anIt != SeqSol.end(); anIt++)
92d1589b 68 {
0f05f211 69 const Standard_Real dst = anIt->Point().Distance(Pt);
70 if (dst <= Precision::Confusion())
71 {
72 return Standard_False;
73 }
92d1589b
A
74 }
75 return Standard_True;
7fd59977 76}
77
78//------------------------------------------------------------------------------
79// function: MIN_SOLUTION
80//------------------------------------------------------------------------------
92d1589b
A
81static void MIN_SOLUTION (const BRepExtrema_SeqOfSolution& SeqSol1,
82 const BRepExtrema_SeqOfSolution& SeqSol2,
83 const Standard_Real DstRef,
84 const Standard_Real Eps,
85 BRepExtrema_SeqOfSolution& seqSol1,
86 BRepExtrema_SeqOfSolution& seqSol2)
7fd59977 87{
0f05f211 88 for (BRepExtrema_SeqOfSolution::iterator anIt1 = SeqSol1.begin(), anIt2 = SeqSol2.begin();
89 anIt1 != SeqSol1.end();
90 anIt1++, anIt2++)
92d1589b 91 {
0f05f211 92 const Standard_Real dst1 = anIt1->Dist();
92d1589b 93 if (fabs(dst1 - DstRef) < Eps)
0f05f211 94 {
95 seqSol1.Append(*anIt1);
96 seqSol2.Append(*anIt2);
97 }
92d1589b 98 }
7fd59977 99}
100
7fd59977 101//------------------------------------------------------------------------------
102// function: TRIM_INFINIT_EDGE
103//------------------------------------------------------------------------------
92d1589b
A
104static void TRIM_INFINIT_EDGE(const TopoDS_Edge& S1, const TopoDS_Edge& S2, TopoDS_Edge& aResEdge,
105 Standard_Boolean& bIsTrim1, Standard_Boolean& bIsTrim2)
7fd59977 106{
92d1589b 107 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
7fd59977 108 return;
109
110 aResEdge = S2;
111 Standard_Real aFirst1, aLast1, aFirst2, aLast2;
7fd59977 112 Handle(Geom_Curve) pCurv1 = BRep_Tool::Curve(S1, aFirst1, aLast1);
113 Handle(Geom_Curve) pCurv2 = BRep_Tool::Curve(S2, aFirst2, aLast2);
114
7fd59977 115 if (Precision::IsInfinite(aFirst1) &&
116 Precision::IsInfinite(aLast1) &&
117 Precision::IsInfinite(aFirst2) &&
118 Precision::IsInfinite(aLast2))
119 return;
7fd59977 120
1d47d8d0 121 Standard_Real Umin = 0., Umax = 0.;
92d1589b
A
122 Standard_Boolean bUmin, bUmax;
123 bUmin = bUmax = Standard_False;
124
125 Handle(Geom_Curve) pCurv;
126 if ( !pCurv1.IsNull() && (Precision::IsInfinite(aFirst1) || Precision::IsInfinite(aLast1)) )
127 {
128 pCurv = pCurv1;
129 bIsTrim1 = Standard_True;
130 if (!Precision::IsInfinite(aFirst1))
7fd59977 131 {
92d1589b
A
132 bUmin = Standard_True;
133 Umin = aFirst1;
7fd59977 134 }
92d1589b 135 else if (!Precision::IsInfinite(aLast1))
7fd59977 136 {
92d1589b
A
137 bUmax = Standard_True;
138 Umax = aLast1;
7fd59977 139 }
92d1589b
A
140 }
141 else if ( !pCurv2.IsNull() && (Precision::IsInfinite(aFirst2) || Precision::IsInfinite(aLast2)) )
142 {
143 pCurv = pCurv2;
144 bIsTrim2 = Standard_True;
145 if (!Precision::IsInfinite(aFirst2))
7fd59977 146 {
92d1589b
A
147 bUmin = Standard_True;
148 Umin = aFirst2;
149 }
150 else if (!Precision::IsInfinite(aLast2))
151 {
152 bUmax = Standard_True;
153 Umax = aLast2;
154 }
155 }
156 if (bIsTrim1 || bIsTrim2)
157 {
158 Bnd_Box aEdgeBox;
159 if (bIsTrim1)
160 BRepBndLib::Add(S2, aEdgeBox);
161 if (bIsTrim2)
162 BRepBndLib::Add(S1, aEdgeBox);
163 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
164 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
165
166 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
167 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
168 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
169 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
170 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
171 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
172 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
173 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
174
175 Standard_Real arrU[8];
176 GeomAPI_ProjectPointOnCurve aProj(aPnt0, pCurv);
177 /*szv:aProj.Perform(aPnt0);*/ arrU[0] = aProj.LowerDistanceParameter();
178 aProj.Perform(aPnt1); arrU[1] = aProj.LowerDistanceParameter();
179 aProj.Perform(aPnt2); arrU[2] = aProj.LowerDistanceParameter();
180 aProj.Perform(aPnt3); arrU[3] = aProj.LowerDistanceParameter();
181 aProj.Perform(aPnt4); arrU[4] = aProj.LowerDistanceParameter();
182 aProj.Perform(aPnt5); arrU[5] = aProj.LowerDistanceParameter();
183 aProj.Perform(aPnt6); arrU[6] = aProj.LowerDistanceParameter();
184 aProj.Perform(aPnt7); arrU[7] = aProj.LowerDistanceParameter();
185
186 if (!bUmin)
187 Umin = arrU[0];
7fd59977 188
92d1589b
A
189 if (!bUmax)
190 Umax = arrU[0];
7fd59977 191
92d1589b
A
192 Standard_Integer i = 0;
193 while (i < 8)
7fd59977 194 {
92d1589b 195 const Standard_Real aU = arrU[i++];
7fd59977 196 if (aU < Umin)
197 Umin = aU;
198 else if (aU > Umax)
199 Umax = aU;
7fd59977 200 }
201
92d1589b
A
202 Standard_Real tol = Precision::Confusion();
203 if (bIsTrim1)
204 tol = BRep_Tool::Tolerance(S1);
205 else if (bIsTrim2)
206 tol = BRep_Tool::Tolerance(S2);
7fd59977 207
92d1589b
A
208 const Standard_Real EpsU = GeomAdaptor_Curve(pCurv).Resolution(3.*tol);
209 if (fabs(Umin - Umax) < EpsU)
210 {
211 Umin -= EpsU;
212 Umax += EpsU;
7fd59977 213 }
92d1589b
A
214
215 Handle(Geom_Curve) result = new Geom_TrimmedCurve(pCurv, Umin, Umax);
216 aResEdge = BRepBuilderAPI_MakeEdge(result);
217 }
7fd59977 218}
219
220//------------------------------------------------------------------------------
221// function: TRIM_INFINIT_FACE
222//------------------------------------------------------------------------------
92d1589b
A
223static void TRIM_INFINIT_FACE(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
224 TopoDS_Face& aResFace, Standard_Boolean& bIsInfinit)
7fd59977 225{
226 bIsInfinit = Standard_False;
227
92d1589b
A
228 TopAbs_ShapeEnum Type1 = S1.ShapeType();
229 TopAbs_ShapeEnum Type2 = S2.ShapeType();
7fd59977 230
231 TopoDS_Edge aE;
232 TopoDS_Face aF;
233
234 if (Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE)
92d1589b
A
235 {
236 aE = TopoDS::Edge(S1);
237 if ( BRep_Tool::Degenerated(aE) )
238 return;
239 aF = TopoDS::Face(S2);
240 }
7fd59977 241 else if (Type2 == TopAbs_EDGE && Type1 == TopAbs_FACE)
92d1589b
A
242 {
243 aE = TopoDS::Edge(S2);
244 if ( BRep_Tool::Degenerated(aE) )
7fd59977 245 return;
92d1589b
A
246 aF = TopoDS::Face(S1);
247 }
248 else
249 {
250 bIsInfinit = Standard_False;
251 return;
252 }
7fd59977 253
7fd59977 254 aResFace = aF;
255 Handle(Geom_Surface) pSurf = BRep_Tool::Surface(aF);
256
92d1589b 257 const Standard_Boolean bRestrict = BRep_Tool::NaturalRestriction(aF);
7fd59977 258
92d1589b 259 Standard_Real U1, V1, U2, V2;
1d47d8d0 260 Standard_Real Umin = RealLast(), Umax = RealFirst(), Vmin = RealLast(), Vmax = RealFirst();
7fd59977 261 Standard_Boolean bUmin, bUmax, bVmin, bVmax;
262 bUmin = bUmax = bVmin = bVmax = Standard_False;
92d1589b 263 Standard_Boolean bIsTrim = Standard_False;
7fd59977 264
265 if (bRestrict)
92d1589b
A
266 {
267 pSurf->Bounds(U1, U2, V1, V2);
268 if (Precision::IsInfinite(U1))
269 bIsTrim = Standard_True;
270 else
7fd59977 271 {
92d1589b
A
272 Umin = U1;
273 bUmin = Standard_True;
274 }
7fd59977 275
92d1589b
A
276 if (Precision::IsInfinite(U2))
277 bIsTrim = Standard_True;
278 else
279 {
280 Umax = U2;
281 bUmax = Standard_True;
282 }
7fd59977 283
92d1589b
A
284 if (Precision::IsInfinite(V1))
285 bIsTrim = Standard_True;
286 else
7fd59977 287 {
92d1589b
A
288 Vmin = V1;
289 bVmin = Standard_True;
7fd59977 290 }
291
92d1589b
A
292 if (Precision::IsInfinite(V2))
293 bIsTrim = Standard_True;
294 else
7fd59977 295 {
92d1589b
A
296 Vmax = V2;
297 bVmax = Standard_True;
7fd59977 298 }
92d1589b 299 }
7fd59977 300 else
92d1589b
A
301 {
302 BRepTools::UVBounds(aF, U1, U2, V1, V2);
303 if (Precision::IsInfinite(U1) &&
304 Precision::IsInfinite(U2) &&
305 Precision::IsInfinite(V1) &&
306 Precision::IsInfinite(V2))
307 bIsTrim = Standard_True;
308 }
7fd59977 309
310 if (bIsTrim)
92d1589b
A
311 {
312 Bnd_Box aEdgeBox;
313 BRepBndLib::Add(aE, aEdgeBox);
314
315 if(aEdgeBox.IsWhole())
316 return;
7fd59977 317
92d1589b
A
318 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
319 aEdgeBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
320
321 const gp_Pnt aPnt0(Xmin, Ymin, Zmin);
322 const gp_Pnt aPnt1(Xmin, Ymax, Zmin);
323 const gp_Pnt aPnt2(Xmin, Ymax, Zmax);
324 const gp_Pnt aPnt3(Xmin, Ymin, Zmax);
325 const gp_Pnt aPnt4(Xmax, Ymax, Zmin);
326 const gp_Pnt aPnt5(Xmax, Ymax, Zmax);
327 const gp_Pnt aPnt6(Xmax, Ymin, Zmax);
328 const gp_Pnt aPnt7(Xmax, Ymin, Zmin);
329
330 Standard_Real arrU[8], arrV[8];
331 GeomAPI_ProjectPointOnSurf aProj(aPnt0, pSurf);
332 /*szv:aProj.Perform(aPnt0);*/ if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[0],arrV[0]);
333 aProj.Perform(aPnt1); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[1],arrV[1]);
334 aProj.Perform(aPnt2); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[2],arrV[2]);
335 aProj.Perform(aPnt3); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[3],arrV[3]);
336 aProj.Perform(aPnt4); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[4],arrV[4]);
337 aProj.Perform(aPnt5); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[5],arrV[5]);
338 aProj.Perform(aPnt6); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[6],arrV[6]);
339 aProj.Perform(aPnt7); if (aProj.IsDone()) aProj.LowerDistanceParameters(arrU[7],arrV[7]);
340
341 if (!bUmin)
342 Umin = arrU[0];
343 if (!bUmax)
344 Umax = arrU[0];
345 if (!bVmin)
346 Vmin = arrV[0];
347 if (!bVmax)
348 Vmax = arrV[0];
349
350 Standard_Integer i = 0;
351 while (i < 8)
7fd59977 352 {
92d1589b 353 const Standard_Real aU = arrU[i];
7fd59977 354 if (aU < Umin)
355 Umin = aU;
356 else if (aU > Umax)
357 Umax = aU;
358
92d1589b 359 const Standard_Real aV = arrV[i];
7fd59977 360 if (aV < Vmin)
361 Vmin = aV;
362 else if (aV > Vmax)
363 Vmax = aV;
ed0d16d8
S
364
365 i++;
7fd59977 366 }
367
92d1589b
A
368 GeomAdaptor_Surface aGAS(pSurf);
369 const Standard_Real tol = BRep_Tool::Tolerance(aF);
7fd59977 370
92d1589b
A
371 const Standard_Real EpsU = aGAS.UResolution(3.*tol);
372 if (fabs(Umin - Umax) < EpsU)
373 {
374 Umin -= EpsU;
375 Umax += EpsU;
376 }
7fd59977 377
92d1589b
A
378 const Standard_Real EpsV = aGAS.VResolution(3.*tol);
379 if (fabs(Vmin - Vmax) < EpsV)
380 {
381 Vmin -= EpsV;
382 Vmax += EpsV;
7fd59977 383 }
92d1589b
A
384
385 Handle(Geom_Surface) result = new Geom_RectangularTrimmedSurface(pSurf, Umin, Umax, Vmin, Vmax);
1c72dff6 386 aResFace = BRepBuilderAPI_MakeFace(result, Precision::Confusion());
92d1589b
A
387
388 bIsInfinit = Standard_True;
389 }
7fd59977 390 else
391 bIsInfinit = Standard_False;
392}
393
394//------------------------------------------------------------------------------
395// static function: PERFORM_C0
396//------------------------------------------------------------------------------
92d1589b
A
397static void PERFORM_C0(const TopoDS_Edge &S1, const TopoDS_Edge &S2,
398 BRepExtrema_SeqOfSolution& SeqSol1,
399 BRepExtrema_SeqOfSolution& SeqSol2,
400 const Standard_Real DstRef,
401 Standard_Real& mDstRef,
402 const Standard_Real Eps)
7fd59977 403{
92d1589b 404 if ( BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2) )
7fd59977 405 return;
92d1589b 406
7fd59977 407 Standard_Integer iE;
7fd59977 408 for (iE = 0; iE < 2; iE++)
92d1589b
A
409 {
410 TopoDS_Edge E, Eother;
411 if (iE == 0)
7fd59977 412 {
413 E = S1;
414 Eother = S2;
415 }
92d1589b 416 else
7fd59977 417 {
418 E = S2;
419 Eother = S1;
420 }
7fd59977 421
92d1589b
A
422 Standard_Real aFirst, aLast;
423 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(E, aFirst, aLast);
7fd59977 424
92d1589b
A
425 Standard_Real aFOther, aLOther;
426 Handle(Geom_Curve) pCurvOther = BRep_Tool::Curve(Eother, aFOther, aLOther);
427
428 if (pCurv->Continuity() == GeomAbs_C0)
7fd59977 429 {
92d1589b 430 const Standard_Real epsP = Precision::PConfusion();
7fd59977 431
92d1589b
A
432 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
433 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
7fd59977 434
92d1589b
A
435 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
436 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
7fd59977 437
92d1589b
A
438 GeomAdaptor_Curve aAdaptorCurveOther(pCurvOther, aFOther, aLOther);
439 const Standard_Integer nbIntervalsOther = aAdaptorCurveOther.NbIntervals(GeomAbs_C1);
440 TColStd_Array1OfReal arrInterOther(1,1+nbIntervalsOther);
441 aAdaptorCurveOther.Intervals(arrInterOther, GeomAbs_C1);
7fd59977 442
92d1589b
A
443 Standard_Real Udeb,Ufin;
444 BRep_Tool::Range(Eother,Udeb,Ufin);
7fd59977 445
92d1589b
A
446 gp_Pnt P1,Pt;
447 Standard_Integer i, ii;
448 BRepClass_FaceClassifier classifier;
449 for (i = 1; i <= arrInter.Length(); i++)
450 {
451 const Standard_Real aParameter = arrInter(i);
452 const gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
453 const TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
7fd59977 454
92d1589b
A
455 BRepExtrema_ExtPC Ext(V1,Eother);
456 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
457 if ( NbExtrema > 0 )
458 {
459 // Search minimum distance dstmin
460 Standard_Real Dstmin = Ext.SquareDistance(1);
461 for (ii = 2; ii <= NbExtrema; ii++)
462 {
463 const Standard_Real sDst = Ext.SquareDistance(ii);
464 if (sDst<Dstmin)
465 Dstmin=sDst;
466 }
467 Dstmin = sqrt(Dstmin);
468
469 if ((Dstmin < DstRef - Eps) || (fabs(Dstmin-DstRef) < Eps))
470 for (ii = 1; ii <= NbExtrema; ii++)
471 {
472 if (fabs(Dstmin-sqrt(Ext.SquareDistance(ii)))<Eps)
473 {
474 Pt=Ext.Point(ii);
475 if (TRI_SOLUTION(SeqSol2,Pt))
476 {
477 // Check if the parameter does not correspond to a vertex
478 const Standard_Real t = Ext.Parameter(ii);
479 if ((fabs(t-Udeb)>=epsP)&&(fabs(t-Ufin)>epsP))
480 {
481 if (mDstRef > Dstmin)
482 mDstRef=Dstmin;
483 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
484 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,Eother,t);
485 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
486 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
487 }
488 }
489 }
490 }
491 }
492 for (Standard_Integer i2 = 1; i2<=arrInterOther.Length(); i2++)
493 {
494 const Standard_Real aParameterOther = arrInterOther(i2);
495 const gp_Pnt aPntOther = aAdaptorCurveOther.Value(aParameterOther);
496 const Standard_Real Dst = aPnt.Distance(aPntOther);
497 if ((Dst < DstRef - Eps) || (fabs(Dst-DstRef) < Eps))
498 {
499 if (mDstRef > Dst)
500 mDstRef=Dst;
501 const BRepExtrema_SolutionElem Sol1(Dst,aPnt,BRepExtrema_IsOnEdge,E,aParameter);
502 const BRepExtrema_SolutionElem Sol2(Dst,aPntOther,BRepExtrema_IsOnEdge,Eother,aParameterOther);
503 SeqSol1.Append(iE == 0 ? Sol1 : Sol2);
504 SeqSol2.Append(iE == 0 ? Sol2 : Sol1);
505 }
506 }
507 }
508 }
509 }
7fd59977 510}
511
512/*********************************************************************************/
513
92d1589b
A
514void BRepExtrema_DistanceSS::Perform(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
515 const Bnd_Box& B1, const Bnd_Box& B2)
7fd59977 516{
92d1589b
A
517 SeqSolShape1.Clear();
518 SeqSolShape2.Clear();
519 myModif=Standard_False;
7fd59977 520
92d1589b
A
521 switch (S1.ShapeType())
522 {
523 case TopAbs_VERTEX :
524 {
525 TopoDS_Vertex V1 = TopoDS::Vertex(S1);
526 switch (S2.ShapeType())
527 {
528 case TopAbs_VERTEX :
529 {
530 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
531 Perform( V1, V2 );
532 break;
533 }
534 case TopAbs_EDGE :
535 {
536 TopoDS_Edge E2 = TopoDS::Edge(S2);
537 Perform( V1, E2, B1, B2 );
538 break;
539 }
540 case TopAbs_FACE :
541 {
542 TopoDS_Face F2 = TopoDS::Face(S2);
543 Perform( V1, F2, B1, B2 );
544 break;
545 }
566f8441 546 default:
547 break;
92d1589b
A
548 }
549 break;
550 }
7fd59977 551
92d1589b
A
552 case TopAbs_EDGE :
553 {
554 TopoDS_Edge E1 = TopoDS::Edge(S1);
555 switch (S2.ShapeType())
556 {
557 case TopAbs_VERTEX :
558 {
559 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
560 Perform( E1, V2, B1, B2 );
561 break;
562 }
563 case TopAbs_EDGE :
564 {
565 TopoDS_Edge E2 = TopoDS::Edge(S2);
566 TopoDS_Edge aTrimEdge;
567 Standard_Boolean bIsTrim1 = Standard_False;
568 Standard_Boolean bIsTrim2 = Standard_False;
569 TRIM_INFINIT_EDGE( E1, E2, aTrimEdge, bIsTrim1, bIsTrim2 );
570 if (bIsTrim1)
571 E1 = aTrimEdge;
572 if (bIsTrim2)
573 E2 = aTrimEdge;
574 Perform( E1, E2, B1, B2 );
575 break;
576 }
577 case TopAbs_FACE :
578 {
579 TopoDS_Face F2 = TopoDS::Face(S2);
580 TopoDS_Face aTrimFace;
581 Standard_Boolean bIsInfinit;
582 TRIM_INFINIT_FACE( E1, F2, aTrimFace, bIsInfinit );
583 if (bIsInfinit)
584 F2 = aTrimFace;
585 Perform( E1, F2, B1, B2 );
586 break;
587 }
566f8441 588 default:
589 break;
92d1589b
A
590 }
591 break;
592 }
7fd59977 593
92d1589b
A
594 case TopAbs_FACE :
595 {
596 TopoDS_Face F1 = TopoDS::Face(S1);
597 switch (S2.ShapeType())
598 {
599 case TopAbs_VERTEX :
600 {
601 TopoDS_Vertex V2 = TopoDS::Vertex(S2);
602 Perform( F1, V2, B1, B2 );
603 break;
604 }
605 case TopAbs_EDGE :
606 {
607 TopoDS_Edge E2 = TopoDS::Edge(S2);
608 TopoDS_Face aTrimFace;
609 Standard_Boolean bIsInfinit;
610 TRIM_INFINIT_FACE( F1, E2, aTrimFace, bIsInfinit );
611 if (bIsInfinit)
612 F1 = aTrimFace;
613 Perform( F1, E2, B1, B2 );
614 break;
615 }
616 case TopAbs_FACE :
617 {
618 TopoDS_Face F2 = TopoDS::Face(S2);
619 Perform( F1, F2, B1, B2 );
620 break;
621 }
566f8441 622 default:
623 break;
92d1589b
A
624 }
625 break;
626 }
566f8441 627 default:
628 break;
92d1589b 629 }
7fd59977 630}
631
632/*********************************************************************************/
633
92d1589b
A
634void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Vertex& S2)
635{
636 const gp_Pnt P1 = BRep_Tool::Pnt(S1);
637 const gp_Pnt P2 = BRep_Tool::Pnt(S2);
7fd59977 638
92d1589b
A
639 const Standard_Real Dst = P1.Distance(P2);
640 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
641 {
642 if (myDstRef > Dst)
643 myDstRef=Dst;
644 myModif=Standard_True;
645 const BRepExtrema_SolutionElem Sol1(Dst,P1,BRepExtrema_IsVertex,S1);
646 const BRepExtrema_SolutionElem Sol2(Dst,P2,BRepExtrema_IsVertex,S2);
647 SeqSolShape1.Append(Sol1);
648 SeqSolShape2.Append(Sol2);
649 }
7fd59977 650}
651
652/*********************************************************************************/
653
92d1589b
A
654void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Edge& S2,
655 const Bnd_Box& B1, const Bnd_Box& B2)
656{
657 if (BRep_Tool::Degenerated(S2))
658 return;
7fd59977 659
92d1589b
A
660 const Standard_Real Dst=B1.Distance(B2);
661 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
662 {
663 BRepExtrema_ExtPC Ext(S1,S2);
664 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
665 if ( NbExtrema > 0 )
666 {
667 // Search minimum distance Dstmin
668 Standard_Integer i;
669 Standard_Real Dstmin = Ext.SquareDistance(1);
670 for (i = 2; i <= NbExtrema; i++)
7fd59977 671 {
92d1589b
A
672 const Standard_Real sDst = Ext.SquareDistance(i);
673 if (sDst<Dstmin)
674 Dstmin=sDst;
7fd59977 675 }
92d1589b
A
676 Dstmin = sqrt(Dstmin);
677 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
678 {
679 Standard_Real Udeb,Ufin;
680 BRep_Tool::Range(S2,Udeb,Ufin);
7fd59977 681
92d1589b
A
682 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
683 const Standard_Real epsP=Precision::PConfusion();
684
685 for (i = 1; i <= NbExtrema; i++)
686 {
687 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
688 {
689 Pt=Ext.Point(i);
690 if (TRI_SOLUTION(SeqSolShape2,Pt))
691 {
692 // Check if the parameter does not correspond to a vertex
693 const Standard_Real t = Ext.Parameter(i);
694 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
695 {
696 if (myDstRef > Dstmin)
697 myDstRef=Dstmin;
698 myModif=Standard_True;
699 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
700 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsOnEdge,S2,t);
701 SeqSolShape1.Append(Sol1);
702 SeqSolShape2.Append(Sol2);
703 }
704 }
705 }
706 }
7fd59977 707 }
92d1589b 708 }
7fd59977 709 }
710}
711
6aeb8ed1
A
712void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1,const TopoDS_Vertex& S2,
713 const Bnd_Box& B1,const Bnd_Box& B2)
714{
715 if (BRep_Tool::Degenerated(S1))
716 return;
717
718 const Standard_Real Dst=B1.Distance(B2);
719 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
720 {
721 BRepExtrema_ExtPC Ext(S2,S1);
722 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
723 if ( NbExtrema > 0 )
724 {
725 // Search minimum distance Dstmin
726 Standard_Integer i;
727 Standard_Real Dstmin = Ext.SquareDistance(1);
728 for (i = 2; i <= NbExtrema; i++)
729 {
730 const Standard_Real sDst = Ext.SquareDistance(i);
731 if (sDst<Dstmin)
732 Dstmin=sDst;
733 }
734 Dstmin = sqrt(Dstmin);
735 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
736 {
737 Standard_Real Udeb,Ufin;
738 BRep_Tool::Range(S1,Udeb,Ufin);
739
aa17232c 740 gp_Pnt Pt, P2 = BRep_Tool::Pnt(S2);
6aeb8ed1
A
741 const Standard_Real epsP=Precision::PConfusion();
742
743 for (i = 1; i <= NbExtrema; i++)
744 {
745 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
746 {
747 Pt=Ext.Point(i);
748 if (TRI_SOLUTION(SeqSolShape1,Pt))
749 {
750 // Check if the parameter does not correspond to a vertex
751 const Standard_Real t = Ext.Parameter(i);
752 if ( (fabs(t-Udeb)>=epsP) && (fabs(t-Ufin)>epsP) )
753 {
754 if (myDstRef > Dstmin)
755 myDstRef=Dstmin;
756 myModif=Standard_True;
aa17232c
J
757 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsOnEdge,S1,t);
758 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
6aeb8ed1
A
759 SeqSolShape1.Append(Sol1);
760 SeqSolShape2.Append(Sol2);
761 }
762 }
763 }
764 }
765 }
766 }
767 }
768}
769
7fd59977 770/*********************************************************************************/
771
92d1589b
A
772void BRepExtrema_DistanceSS::Perform(const TopoDS_Vertex& S1, const TopoDS_Face& S2,
773 const Bnd_Box& B1, const Bnd_Box& B2)
7fd59977 774{
92d1589b
A
775 const Standard_Real Dst=B1.Distance(B2);
776 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
7fd59977 777 {
92d1589b
A
778 BRepExtrema_ExtPF Ext(S1,S2,myFlag,myAlgo);
779 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
780 if ( NbExtrema > 0 )
7fd59977 781 {
92d1589b 782 // Search minimum distance Dstmin
7fd59977 783 Standard_Integer i;
784 Standard_Real Dstmin = Ext.SquareDistance(1);
92d1589b
A
785 for (i = 2; i <= NbExtrema; i++)
786 {
787 const Standard_Real sDst = Ext.SquareDistance(i);
788 if (sDst<Dstmin)
789 Dstmin=sDst;
7fd59977 790 }
791 Dstmin = sqrt(Dstmin);
92d1589b 792 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
7fd59977 793 {
794 Standard_Real U,V;
92d1589b 795 gp_Pnt Pt,P1=BRep_Tool::Pnt(S1);
7fd59977 796 BRepClass_FaceClassifier classifier;
92d1589b 797 const Standard_Real tol = BRep_Tool::Tolerance(S2);
92d1589b
A
798
799 for (i = 1; i <= NbExtrema; i++)
7fd59977 800 {
92d1589b
A
801 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
802 {
7fd59977 803 Pt=Ext.Point(i);
92d1589b
A
804 if (TRI_SOLUTION(SeqSolShape2,Pt))
805 {
806 // Check if the parameter does not correspond to a vertex
7fd59977 807 Ext.Parameter(i,U,V);
92d1589b
A
808 const gp_Pnt2d PUV(U,V);
809 classifier.Perform(S2,PUV,tol);
7fd59977 810 if (classifier.State()==TopAbs_IN)
811 {
92d1589b
A
812 if (myDstRef > Dstmin)
813 myDstRef=Dstmin;
7fd59977 814 myModif=Standard_True;
92d1589b
A
815 const BRepExtrema_SolutionElem Sol1(Dstmin,P1,BRepExtrema_IsVertex,S1);
816 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt,BRepExtrema_IsInFace,S2,U,V);
7fd59977 817 SeqSolShape1.Append(Sol1);
92d1589b 818 SeqSolShape2.Append(Sol2);
7fd59977 819 }
820 }
821 }
822 }
92d1589b 823 }
7fd59977 824 }
825 }
826}
827
6aeb8ed1
A
828void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Vertex& S2,
829 const Bnd_Box& B1, const Bnd_Box& B2)
830{
831 const Standard_Real Dst=B1.Distance(B2);
832 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
833 {
834 BRepExtrema_ExtPF Ext(S2,S1,myFlag,myAlgo);
835 const Standard_Integer NbExtrema = Ext.IsDone()? Ext.NbExt() : 0;
836 if ( NbExtrema > 0 )
837 {
838 // Search minimum distance Dstmin
839 Standard_Integer i;
840 Standard_Real Dstmin = Ext.SquareDistance(1);
841 for (i = 2; i <= NbExtrema; i++)
842 {
843 const Standard_Real sDst = Ext.SquareDistance(i);
844 if (sDst<Dstmin)
845 Dstmin=sDst;
846 }
847 Dstmin = sqrt(Dstmin);
848 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
849 {
850 Standard_Real U,V;
46def2b5 851 gp_Pnt Pt,P2=BRep_Tool::Pnt(S2);
6aeb8ed1
A
852 BRepClass_FaceClassifier classifier;
853 const Standard_Real tol = BRep_Tool::Tolerance(S1);
6aeb8ed1
A
854
855 for (i = 1; i <= NbExtrema; i++)
856 {
857 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
858 {
859 Pt=Ext.Point(i);
860 if (TRI_SOLUTION(SeqSolShape1,Pt))
861 {
862 // Check if the parameter does not correspond to a vertex
863 Ext.Parameter(i,U,V);
864 const gp_Pnt2d PUV(U,V);
865 classifier.Perform(S1,PUV,tol);
866 if (classifier.State()==TopAbs_IN)
867 {
868 if (myDstRef > Dstmin)
869 myDstRef=Dstmin;
870 myModif=Standard_True;
46def2b5 871 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt,BRepExtrema_IsInFace,S1,U,V);
872 const BRepExtrema_SolutionElem Sol2(Dstmin,P2,BRepExtrema_IsVertex,S2);
6aeb8ed1
A
873 SeqSolShape1.Append(Sol1);
874 SeqSolShape2.Append(Sol2);
875 }
876 }
877 }
878 }
879 }
880 }
881 }
882}
883
7fd59977 884/*********************************************************************************/
885
92d1589b
A
886void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Edge& S2,
887 const Bnd_Box& B1, const Bnd_Box& B2)
7fd59977 888{
92d1589b
A
889 if (BRep_Tool::Degenerated(S1) || BRep_Tool::Degenerated(S2))
890 return;
891
892 const Standard_Real Dst=B1.Distance(B2);
893 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
7fd59977 894 {
92d1589b 895 const Standard_Real DstRef = myDstRef;
7fd59977 896
92d1589b
A
897 BRepExtrema_ExtCC Ext(S1,S2);
898 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
899 if ( NbExtrema > 0 )
900 {
901 // Search minimum distance Dstmin
902 Standard_Integer i;
903 Standard_Real Dstmin = Ext.SquareDistance(1);
904 for (i = 2; i <= NbExtrema; i++)
905 {
906 const Standard_Real sDst = Ext.SquareDistance(i);
907 if (sDst<Dstmin)
908 Dstmin=sDst;
909 }
910 Dstmin = sqrt(Dstmin);
911 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
912 {
913 Standard_Real Udeb1,Ufin1,Udeb2,Ufin2;
914 BRep_Tool::Range(S1,Udeb1,Ufin1);
915 BRep_Tool::Range(S2,Udeb2,Ufin2);
7fd59977 916
92d1589b
A
917 gp_Pnt Pt1,Pt2;
918 const Standard_Real epsP=Precision::PConfusion();
7fd59977 919
92d1589b
A
920 for (i=1;i<=NbExtrema;i++)
921 {
922 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
923 {
924 Pt1=Ext.PointOnE1(i);
925 Pt2=Ext.PointOnE2(i);
926 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
927 {
928 // Check if the parameters do not correspond to a vertex
929 const Standard_Real t1 = Ext.ParameterOnE1(i);
930 const Standard_Real t2 = Ext.ParameterOnE2(i);
931 if ((fabs(t1-Udeb1)>=epsP)&&(fabs(t1-Ufin1)>epsP)&&(fabs(t2-Udeb2)>=epsP)&&(fabs(t2-Ufin2)>epsP))
932 {
933 if (myDstRef > Dstmin)
934 myDstRef=Dstmin;
935 myModif=Standard_True;
936 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
937 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsOnEdge,S2,t2);
938 SeqSolShape1.Append(Sol1);
939 SeqSolShape2.Append(Sol2);
940 }
941 }
942 }
943 }
944 }
945 }
7fd59977 946
92d1589b
A
947 BRepExtrema_SeqOfSolution SeqSolution1;
948 BRepExtrema_SeqOfSolution SeqSolution2;
7fd59977 949
92d1589b
A
950 PERFORM_C0(S1, S2, SeqSolution1, SeqSolution2, DstRef, myDstRef, myEps);
951
952 BRepExtrema_SeqOfSolution seqSol1;
953 BRepExtrema_SeqOfSolution seqSol2;
954
955 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
956 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
957
958 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
959 {
960 SeqSolShape1.Append(seqSol1);
961 SeqSolShape2.Append(seqSol2);
962 myModif = Standard_True;
963 }
964 }
7fd59977 965}
966
967/*********************************************************************************/
968
92d1589b
A
969void BRepExtrema_DistanceSS::Perform(const TopoDS_Edge& S1, const TopoDS_Face& S2,
970 const Bnd_Box& B1, const Bnd_Box& B2)
7fd59977 971{
92d1589b
A
972 if (BRep_Tool::Degenerated(S1))
973 return;
974
975 const Standard_Real Dst=B1.Distance(B2);
976 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
977 {
978 BRepClass_FaceClassifier classifier;
7fd59977 979
92d1589b
A
980 BRepExtrema_ExtCF Ext(S1,S2);
981 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
982 if ( NbExtrema > 0 )
983 {
984 // Search minimum distance Dstmin
985 Standard_Integer i;
986 Standard_Real Dstmin = Ext.SquareDistance(1);
987 for (i = 2; i <= NbExtrema; i++)
988 {
989 const Standard_Real sDst = Ext.SquareDistance(i);
990 if (sDst<Dstmin)
991 Dstmin=sDst;
992 }
993 Dstmin = sqrt(Dstmin);
994 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
995 {
996 Standard_Real Udeb,Ufin,U,V;
997 BRep_Tool::Range(S1,Udeb,Ufin);
998 const Standard_Real tol=BRep_Tool::Tolerance(S2);
7fd59977 999
92d1589b
A
1000 gp_Pnt Pt1,Pt2;
1001 const Standard_Real epsP=Precision::PConfusion();
1002
1003 for (i = 1; i <= NbExtrema; i++)
1004 {
1005 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1006 {
1007 Pt1=Ext.PointOnEdge(i);
1008 Pt2=Ext.PointOnFace(i);
1009 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1010 {
1011 // Check if the parameter does not correspond to a vertex
1012 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1013 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1014 {
1015 Ext.ParameterOnFace(i,U,V);
1016 const gp_Pnt2d PUV(U,V);
1017 classifier.Perform(S2,PUV,tol);
1018 if (classifier.State()==TopAbs_IN)
1019 {
1020 if (myDstRef > Dstmin)
1021 myDstRef=Dstmin;
1022 myModif=Standard_True;
1023 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsOnEdge,S1,t1);
1024 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U,V);
1025 SeqSolShape1.Append(Sol1);
1026 SeqSolShape2.Append(Sol2);
1027 }
1028 }
1029 }
1030 }
1031 }
1032 }
1033 }
1034
1035 Standard_Real aFirst, aLast;
1036 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S1, aFirst, aLast);
1037 if (pCurv->Continuity() == GeomAbs_C0)
1038 {
1039 BRepExtrema_SeqOfSolution SeqSolution1;
1040 BRepExtrema_SeqOfSolution SeqSolution2;
1041
1042 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1043 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1044
1045 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1046 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1047
1048 gp_Pnt Pt;
1049 Standard_Real U,V;
1050 const Standard_Real tol = BRep_Tool::Tolerance(S2);
1051
1052 Standard_Integer i;
1053 for (i = 1; i <= arrInter.Length(); i++)
1054 {
1055 const Standard_Real aParameter = arrInter(i);
1056 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1057 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1058
1059 BRepExtrema_ExtPF ExtPF(V1,S2);
51740958 1060 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1061 if (NbExtremaPF > 0 )
92d1589b
A
1062 {
1063 // Search minimum distance Dstmin
1064 Standard_Integer ii;
1065 Standard_Real Dstmin = ExtPF.SquareDistance(1);
51740958 1066 for (ii = 2; ii <= NbExtremaPF; ii++)
92d1589b
A
1067 {
1068 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1069 if (sDst<Dstmin)
1070 Dstmin=sDst;
1071 }
1072 Dstmin = sqrt(Dstmin);
1073
1074 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1075 {
51740958 1076 for (ii = 1; ii <= NbExtremaPF; ii++)
92d1589b
A
1077 {
1078 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1079 {
1080 // Check if the parameter does not correspond to a vertex
1081 ExtPF.Parameter(ii,U,V);
1082 const gp_Pnt2d PUV(U,V);
1083 classifier.Perform(S2,PUV,tol);
1084 if (classifier.State()==TopAbs_IN)
1085 {
1086 if (myDstRef > Dstmin)
1087 myDstRef=Dstmin;
1088 myModif=Standard_True;
1089 const BRepExtrema_SolutionElem Sol1(Dstmin,aPnt,BRepExtrema_IsOnEdge,S1,aParameter);
1090 const BRepExtrema_SolutionElem Sol2(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S2,U,V);
1091 SeqSolution1.Append(Sol1);
1092 SeqSolution2.Append(Sol2);
1093 }
6aeb8ed1
A
1094 }
1095 }
1096 }
1097 }
1098 }
1099
1100 BRepExtrema_SeqOfSolution seqSol1;
1101 BRepExtrema_SeqOfSolution seqSol2;
6aeb8ed1
A
1102 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1103 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1104
1105 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1106 {
1107 SeqSolShape1.Append(seqSol1);
1108 SeqSolShape2.Append(seqSol2);
1109 }
1110 }
1111 }
1112}
1113
1114void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Edge& S2,
1115 const Bnd_Box& B1, const Bnd_Box& B2)
1116{
1117 if (BRep_Tool::Degenerated(S2))
1118 return;
1119
1120 const Standard_Real Dst=B1.Distance(B2);
1121 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1122 {
1123 BRepClass_FaceClassifier classifier;
1124
1125 BRepExtrema_ExtCF Ext(S2,S1);
1126 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1127 if ( NbExtrema > 0 )
1128 {
1129 // Search minimum distance Dstmin
1130 Standard_Integer i;
1131 Standard_Real Dstmin = Ext.SquareDistance(1);
1132 for (i = 2; i <= NbExtrema; i++)
1133 {
1134 const Standard_Real sDst = Ext.SquareDistance(i);
1135 if (sDst<Dstmin)
1136 Dstmin=sDst;
1137 }
1138 Dstmin = sqrt(Dstmin);
1139 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1140 {
1141 Standard_Real Udeb,Ufin,U,V;
1142 BRep_Tool::Range(S2,Udeb,Ufin);
1143 const Standard_Real tol=BRep_Tool::Tolerance(S1);
1144
1145 gp_Pnt Pt1,Pt2;
1146 const Standard_Real epsP=Precision::PConfusion();
1147
1148 for (i = 1; i <= NbExtrema; i++)
1149 {
1150 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1151 {
1152 Pt1=Ext.PointOnEdge(i);
1153 Pt2=Ext.PointOnFace(i);
1154 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1155 {
1156 // Check if the parameter does not correspond to a vertex
1157 const Standard_Real t1 = Ext.ParameterOnEdge(i);
1158 if ((fabs(t1-Udeb)>=epsP)&&(fabs(t1-Ufin)>epsP))
1159 {
1160 Ext.ParameterOnFace(i,U,V);
1161 const gp_Pnt2d PUV(U,V);
1162 classifier.Perform(S1,PUV,tol);
1163 if (classifier.State()==TopAbs_IN)
1164 {
1165 if (myDstRef > Dstmin)
1166 myDstRef=Dstmin;
1167 myModif=Standard_True;
1168 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt1,BRepExtrema_IsOnEdge,S2,t1);
1169 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt2,BRepExtrema_IsInFace,S1,U,V);
1170 SeqSolShape1.Append(Sol1);
1171 SeqSolShape2.Append(Sol2);
1172 }
1173 }
1174 }
1175 }
1176 }
1177 }
1178 }
1179
1180 Standard_Real aFirst, aLast;
1181 Handle(Geom_Curve) pCurv = BRep_Tool::Curve(S2, aFirst, aLast);
1182 if (pCurv->Continuity() == GeomAbs_C0)
1183 {
1184 BRepExtrema_SeqOfSolution SeqSolution1;
1185 BRepExtrema_SeqOfSolution SeqSolution2;
1186
1187 GeomAdaptor_Curve aAdaptorCurve(pCurv, aFirst, aLast);
1188 const Standard_Integer nbIntervals = aAdaptorCurve.NbIntervals(GeomAbs_C1);
1189
1190 TColStd_Array1OfReal arrInter(1,1+nbIntervals);
1191 aAdaptorCurve.Intervals(arrInter, GeomAbs_C1);
1192
1193 gp_Pnt Pt;
1194 Standard_Real U,V;
1195 const Standard_Real tol = BRep_Tool::Tolerance(S1);
1196
1197 Standard_Integer i;
1198 for (i = 1; i <= arrInter.Length(); i++)
1199 {
1200 const Standard_Real aParameter = arrInter(i);
1201 gp_Pnt aPnt = aAdaptorCurve.Value(aParameter);
1202 TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(aPnt);
1203
1204 BRepExtrema_ExtPF ExtPF(V1,S1);
51740958 1205 const Standard_Integer NbExtremaPF = ExtPF.IsDone()? ExtPF.NbExt() : 0;
1206 if (NbExtremaPF > 0 )
6aeb8ed1
A
1207 {
1208 // Search minimum distance Dstmin
1209 Standard_Integer ii;
1210 Standard_Real Dstmin = ExtPF.SquareDistance(1);
51740958 1211 for (ii = 2; ii <= NbExtremaPF; ii++)
6aeb8ed1
A
1212 {
1213 const Standard_Real sDst = ExtPF.SquareDistance(ii);
1214 if (sDst<Dstmin)
1215 Dstmin=sDst;
1216 }
1217 Dstmin = sqrt(Dstmin);
1218
1219 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1220 {
51740958 1221 for (ii = 1; ii <= NbExtremaPF; ii++)
6aeb8ed1
A
1222 {
1223 if (fabs(Dstmin-sqrt(ExtPF.SquareDistance(ii)))<myEps)
1224 {
1225 // Check if the parameter does not correspond to a vertex
1226 ExtPF.Parameter(ii,U,V);
1227 const gp_Pnt2d PUV(U,V);
1228 classifier.Perform(S1,PUV,tol);
1229 if (classifier.State()==TopAbs_IN)
1230 {
1231 if (myDstRef > Dstmin)
1232 myDstRef=Dstmin;
1233 myModif=Standard_True;
1234 const BRepExtrema_SolutionElem Sol2(Dstmin,aPnt,BRepExtrema_IsOnEdge,S2,aParameter);
1235 const BRepExtrema_SolutionElem Sol1(Dstmin,ExtPF.Point(ii),BRepExtrema_IsInFace,S1,U,V);
1236 SeqSolution1.Append(Sol1);
1237 SeqSolution2.Append(Sol2);
1238 }
92d1589b
A
1239 }
1240 }
1241 }
1242 }
1243 }
1244
1245 BRepExtrema_SeqOfSolution seqSol1;
1246 BRepExtrema_SeqOfSolution seqSol2;
92d1589b
A
1247 if (SeqSolution1.Length() > 0 && SeqSolution2.Length() > 0)
1248 MIN_SOLUTION(SeqSolution1, SeqSolution2, myDstRef, myEps, seqSol1, seqSol2);
1249
1250 if (!seqSol1.IsEmpty() && !seqSol2.IsEmpty())
1251 {
1252 SeqSolShape1.Append(seqSol1);
1253 SeqSolShape2.Append(seqSol2);
1254 }
1255 }
1256 }
7fd59977 1257}
1258
1259/*********************************************************************************/
1260
92d1589b
A
1261void BRepExtrema_DistanceSS::Perform(const TopoDS_Face& S1, const TopoDS_Face& S2,
1262 const Bnd_Box& B1, const Bnd_Box& B2)
1263{
1264 const Standard_Real Dst=B1.Distance(B2);
1265 if ((Dst < myDstRef - myEps) || (fabs(Dst-myDstRef) < myEps))
1266 {
1267 BRepExtrema_ExtFF Ext(S1,S2);
1268 const Standard_Integer NbExtrema = Ext.IsDone()? (Ext.IsParallel()? 0 : Ext.NbExt()) : 0;
1269 if ( NbExtrema > 0 )
1270 {
1271 // Search minimum distance Dstmin
1272 Standard_Integer i;
1273 Standard_Real Dstmin = Ext.SquareDistance(1);
1274 for (i = 2; i <= NbExtrema; i++)
1275 {
1276 const Standard_Real sDst = Ext.SquareDistance(i);
1277 if (sDst<Dstmin)
1278 Dstmin=sDst;
1279 }
1280 Dstmin = sqrt(Dstmin);
1281 if ((Dstmin < myDstRef - myEps) || (fabs(Dstmin-myDstRef) < myEps))
1282 {
1283 const Standard_Real tol1=BRep_Tool::Tolerance(S1);
1284 const Standard_Real tol2=BRep_Tool::Tolerance(S2);
1285
1286 gp_Pnt Pt1,Pt2;
1287 gp_Pnt2d PUV;
1288 Standard_Real U1,V1,U2,V2;
1289 BRepClass_FaceClassifier classifier;
92d1589b
A
1290
1291 for (i = 1; i <= NbExtrema; i++)
1292 {
1293 if (fabs(Dstmin-sqrt(Ext.SquareDistance(i)))<myEps)
1294 {
1295 Pt1=Ext.PointOnFace1(i);
1296 Pt2=Ext.PointOnFace2(i);
1297 if (TRI_SOLUTION(SeqSolShape1,Pt1) || TRI_SOLUTION(SeqSolShape2,Pt2))
1298 {
1299 // Check if the parameter does not correspond to a vertex
1300 Ext.ParameterOnFace1(i,U1,V1);
1301 PUV.SetCoord(U1,V1);
1302 classifier.Perform(S1,PUV,tol1);
1303 if (classifier.State()==TopAbs_IN)
1304 {
1305 Ext.ParameterOnFace2(i,U2,V2);
1306 PUV.SetCoord(U2,V2);
1307 classifier.Perform(S2,PUV,tol2);
1308 if (classifier.State()==TopAbs_IN)
1309 {
1310 if (myDstRef > Dstmin)
1311 myDstRef=Dstmin;
1312 myModif=Standard_True;
1313 const BRepExtrema_SolutionElem Sol1(Dstmin,Pt1,BRepExtrema_IsInFace,S1,U1,V1);
1314 const BRepExtrema_SolutionElem Sol2(Dstmin,Pt2,BRepExtrema_IsInFace,S2,U2,V2);
1315 SeqSolShape1.Append(Sol1);
1316 SeqSolShape2.Append(Sol2);
1317 }
1318 }
1319 }
1320 }
1321 }
1322 }
1323 }
1324 }
7fd59977 1325}
1326
1327/*********************************************************************************/