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