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