Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-04-22 |
2 | // Created by: Herve LOUESSARD | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
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 | 65 | static 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 |
79 | static 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 |
101 | static 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 |
220 | static 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 |
394 | static 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 |
511 | void 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 |
631 | void 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 |
651 | void 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 |
709 | void 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 |
769 | void 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 |
825 | void 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 |
883 | void 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 |
966 | void 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 | ||
1111 | void 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 |
1258 | void 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 | /*********************************************************************************/ |