Commit | Line | Data |
---|---|---|
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 | 54 | static 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 |
68 | static 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 |
90 | static 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 |
209 | static 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 |
383 | static 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 |
500 | void 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 |
612 | void 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 |
632 | void 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 |
690 | void 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 |
750 | void 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 |
807 | void 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 |
866 | void 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 |
949 | void 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 | ||
1095 | void 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 |
1243 | void 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 | /*********************************************************************************/ |