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