Commit | Line | Data |
---|---|---|
7fd59977 | 1 | // File: Bisector_Inter.cxx |
2 | // Created: Fri Jun 24 11:38:47 1994 | |
3 | // Author: Yves FRICAUD | |
4 | // <yfr@phobox> | |
5 | ||
6 | // Modified by skv - Mon May 5 15:06:39 2003 OCC616 | |
7 | ||
8 | #include <Bisector_Inter.ixx> | |
9 | #include <IntRes2d_Intersection.hxx> | |
10 | #include <Bisector_Curve.hxx> | |
11 | #include <Bisector_BisecAna.hxx> | |
12 | #include <Bisector_BisecCC.hxx> | |
13 | #include <Bisector_BisecPC.hxx> | |
14 | #include <Bisector_FunctionInter.hxx> | |
15 | #include <Geom2dInt_GInter.hxx> | |
16 | #include <Geom2d_TrimmedCurve.hxx> | |
17 | #include <Geom2dAdaptor_Curve.hxx> | |
18 | #include <Geom2d_Curve.hxx> | |
19 | #include <Geom2d_Line.hxx> | |
20 | #include <IntRes2d_Transition.hxx> | |
21 | #include <IntRes2d_IntersectionPoint.hxx> | |
22 | #include <Precision.hxx> | |
23 | #include <math_BissecNewton.hxx> | |
24 | #include <ElCLib.hxx> | |
25 | ||
26 | #ifdef DRAW | |
27 | #include <Draw_Appli.hxx> | |
28 | #include <DrawTrSurf_Curve2d.hxx> | |
29 | #include <Draw_Marker2D.hxx> | |
30 | #endif | |
31 | #ifdef DEB | |
32 | static Standard_Boolean Affich = Standard_False; | |
33 | #endif | |
34 | ||
35 | //=================================================================================== | |
36 | // function : | |
37 | // putpose : | |
38 | //=================================================================================== | |
39 | Bisector_Inter::Bisector_Inter() | |
40 | { | |
41 | } | |
42 | ||
43 | //=================================================================================== | |
44 | // function : | |
45 | // putpose : | |
46 | //=================================================================================== | |
47 | Bisector_Inter::Bisector_Inter(const Bisector_Bisec& C1, | |
48 | const IntRes2d_Domain& D1, | |
49 | const Bisector_Bisec& C2, | |
50 | const IntRes2d_Domain& D2, | |
51 | const Standard_Real TolConf, | |
52 | const Standard_Real Tol, | |
53 | const Standard_Boolean ComunElement) | |
54 | { | |
55 | Perform (C1,D1,C2,D2,TolConf,Tol,ComunElement); | |
56 | } | |
57 | ||
58 | //=================================================================================== | |
59 | // function : ConstructSegment | |
60 | // putpose : | |
61 | //=================================================================================== | |
62 | static Handle(Geom2d_Line) ConstructSegment(const gp_Pnt2d& PMin, | |
63 | const gp_Pnt2d& PMax, | |
64 | const Standard_Real UMin, | |
65 | // const Standard_Real UMax) | |
66 | const Standard_Real ) | |
67 | { | |
68 | gp_Dir2d Dir(PMax.X() - PMin.X(),PMax.Y() - PMin.Y()); | |
69 | Handle(Geom2d_Line) L = new Geom2d_Line (gp_Pnt2d(PMin.X() - UMin*Dir.X(), | |
70 | PMin.Y() - UMin*Dir.Y()),Dir); | |
71 | return L; | |
72 | } | |
73 | ||
74 | //=================================================================================== | |
75 | // function : Perform | |
76 | // putpose : | |
77 | //=================================================================================== | |
78 | void Bisector_Inter::Perform(const Bisector_Bisec& C1, | |
79 | const IntRes2d_Domain& D1, | |
80 | const Bisector_Bisec& C2, | |
81 | const IntRes2d_Domain& D2, | |
82 | const Standard_Real TolConf, | |
83 | const Standard_Real Tol, | |
84 | const Standard_Boolean ComunElement) | |
85 | { | |
86 | Handle(Bisector_Curve) Bis1 = Handle(Bisector_Curve)::DownCast( C1.Value()->BasisCurve()); | |
87 | Handle(Bisector_Curve) Bis2 = Handle(Bisector_Curve)::DownCast( C2.Value()->BasisCurve()); | |
88 | ||
89 | Handle(Geom2d_Curve)* SBis1 = new Handle(Geom2d_Curve) [Bis1->NbIntervals()+1]; | |
90 | Handle(Geom2d_Curve)* SBis2 = new Handle(Geom2d_Curve) [Bis2->NbIntervals()+1]; | |
91 | IntRes2d_Domain* SD1 = new IntRes2d_Domain [Bis1->NbIntervals()+1]; | |
92 | IntRes2d_Domain* SD2 = new IntRes2d_Domain [Bis2->NbIntervals()+1]; | |
93 | ||
94 | Standard_Integer NB1 = 0; Standard_Integer NB2 = 0; | |
95 | Standard_Real MinDomain,MaxDomain; | |
96 | Standard_Real UMin,UMax; | |
97 | gp_Pnt2d PMin,PMax; | |
98 | ||
99 | //------------------------------------------------------ | |
0d969553 | 100 | // Return Min Max domain1. |
7fd59977 | 101 | //------------------------------------------------------ |
102 | if (D1.HasFirstPoint()) {MinDomain = D1.FirstParameter();} | |
103 | else {MinDomain = RealFirst(); } | |
104 | ||
105 | if (D1.HasLastPoint()) {MaxDomain = D1.LastParameter();} | |
106 | else {MaxDomain = RealLast(); } | |
107 | ||
108 | //---------------------------------------------------------- | |
0d969553 Y |
109 | // Cutting the first curve by the intervals of |
110 | // continuity taking account of D1 | |
7fd59977 | 111 | //---------------------------------------------------------- |
112 | //for (Standard_Integer IB1 = 1; IB1 <= Bis1->NbIntervals(); IB1++) { | |
113 | Standard_Integer IB1; | |
114 | for ( IB1 = 1; IB1 <= Bis1->NbIntervals(); IB1++) { | |
115 | UMin = Bis1->IntervalFirst(IB1); | |
116 | UMax = Bis1->IntervalLast (IB1); | |
117 | if (UMax > MinDomain && UMin < MaxDomain) { | |
118 | UMin = Max (UMin,MinDomain); | |
119 | UMax = Min (UMax,MaxDomain); | |
120 | PMin = Bis1->Value(UMin); | |
121 | PMax = Bis1->Value(UMax); | |
122 | SD1 [IB1].SetValues(PMin,UMin,D1.FirstTolerance(), | |
123 | PMax,UMax,D1.LastTolerance()); | |
124 | ||
125 | if ((IB1 == 1 && Bis1->IsExtendAtStart()) || | |
126 | (IB1 == Bis1->NbIntervals() && Bis1->IsExtendAtEnd()) ){ | |
127 | //-------------------------------------------------------- | |
0d969553 | 128 | // Part corresponding to an extension is a segment. |
7fd59977 | 129 | //-------------------------------------------------------- |
130 | SBis1 [IB1] = ConstructSegment (PMin,PMax,UMin,UMax); | |
131 | } | |
132 | else { | |
133 | SBis1 [IB1] = Bis1; | |
134 | } | |
135 | NB1++; | |
136 | } | |
137 | } | |
138 | ||
139 | //------------------------------------------------------ | |
0d969553 | 140 | // Return Min Max domain2. |
7fd59977 | 141 | //------------------------------------------------------ |
142 | if (D2.HasFirstPoint()) {MinDomain = D2.FirstParameter();} | |
143 | else {MinDomain = RealFirst(); } | |
144 | ||
145 | if (D2.HasLastPoint()) {MaxDomain = D2.LastParameter();} | |
146 | else {MaxDomain = RealLast(); } | |
147 | ||
148 | //---------------------------------------------------------- | |
0d969553 Y |
149 | // Cut the second curve following the intervals of |
150 | // continuity taking account of D2 | |
7fd59977 | 151 | //---------------------------------------------------------- |
152 | //for (Standard_Integer IB2 = 1; IB2 <= Bis2->NbIntervals(); IB2++) { | |
153 | Standard_Integer IB2; | |
154 | for ( IB2 = 1; IB2 <= Bis2->NbIntervals(); IB2++) { | |
155 | UMin = Bis2->IntervalFirst(IB2); | |
156 | UMax = Bis2->IntervalLast (IB2); | |
157 | if (UMax > MinDomain && UMin < MaxDomain) { | |
158 | UMin = Max (UMin,MinDomain); | |
159 | UMax = Min (UMax,MaxDomain); | |
160 | PMin = Bis2->Value(UMin); | |
161 | PMax = Bis2->Value(UMax); | |
162 | SD2 [IB2].SetValues(PMin,UMin,D2.FirstTolerance(), | |
163 | PMax,UMax,D2.LastTolerance()); | |
164 | ||
165 | if ((IB2 == 1 && Bis2->IsExtendAtStart()) || | |
166 | (IB2 == Bis1->NbIntervals() && Bis2->IsExtendAtEnd()) ){ | |
167 | //-------------------------------------------------------- | |
0d969553 | 168 | // Part corresponding to an extension is a segment. |
7fd59977 | 169 | //-------------------------------------------------------- |
170 | SBis2 [IB2] = ConstructSegment (PMin,PMax,UMin,UMax); | |
171 | } | |
172 | else { | |
173 | SBis2 [IB2] = Bis2; | |
174 | } | |
175 | NB2++; | |
176 | } | |
177 | } | |
178 | ||
179 | //-------------------------------------------------------------- | |
0d969553 | 180 | // Loop on the intersections of parts of each curve. |
7fd59977 | 181 | //-------------------------------------------------------------- |
182 | for ( IB1 = 1; IB1 <= NB1; IB1++) { | |
183 | for ( IB2 = 1; IB2 <= NB2; IB2++) { | |
184 | SinglePerform(SBis1[IB1],SD1[IB1], | |
185 | SBis2[IB2],SD2[IB2],TolConf,Tol,ComunElement); | |
186 | } | |
187 | } | |
188 | delete [] SBis1; | |
189 | delete [] SBis2; | |
190 | delete [] SD1; | |
191 | delete [] SD2; | |
192 | } | |
193 | ||
194 | //=================================================================================== | |
195 | // function : SinglePerform | |
196 | // putpose : | |
197 | //=================================================================================== | |
198 | void Bisector_Inter::SinglePerform(const Handle(Geom2d_Curve)& CBis1, | |
199 | const IntRes2d_Domain& D1, | |
200 | const Handle(Geom2d_Curve)& CBis2, | |
201 | const IntRes2d_Domain& D2, | |
202 | const Standard_Real TolConf, | |
203 | const Standard_Real Tol, | |
204 | const Standard_Boolean ComunElement) | |
205 | { | |
206 | Handle(Geom2d_Curve) Bis1 = CBis1; | |
207 | Handle(Geom2d_Curve) Bis2 = CBis2; | |
208 | ||
209 | Handle(Standard_Type) Type1 = Bis1->DynamicType(); | |
210 | Handle(Standard_Type) Type2 = Bis2->DynamicType(); | |
211 | ||
212 | if (Type1 == STANDARD_TYPE(Bisector_BisecAna) || Type2 == STANDARD_TYPE(Bisector_BisecAna)) { | |
213 | Handle(Geom2d_Curve) C2Bis1,C2Bis2; | |
214 | if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) { | |
215 | C2Bis1 = Handle(Bisector_BisecAna)::DownCast(Bis1)->Geom2dCurve(); | |
216 | } | |
217 | else { | |
218 | C2Bis1 = Bis1; | |
219 | } | |
220 | if (Type2 == STANDARD_TYPE(Bisector_BisecAna)) { | |
221 | C2Bis2 = Handle(Bisector_BisecAna)::DownCast(Bis2)->Geom2dCurve(); | |
222 | } | |
223 | else { | |
224 | C2Bis2 = Bis2; | |
225 | } | |
226 | Type1 = C2Bis1->DynamicType(); | |
227 | Type2 = C2Bis2->DynamicType(); | |
228 | if (Type1 == STANDARD_TYPE(Geom2d_Line) && Type2 != STANDARD_TYPE(Geom2d_Line)) { | |
229 | TestBound(Handle(Geom2d_Line)::DownCast(C2Bis1), | |
230 | D1,C2Bis2,D2,TolConf,Standard_False); | |
231 | } | |
232 | else if (Type2 == STANDARD_TYPE(Geom2d_Line)&& Type1 != STANDARD_TYPE(Geom2d_Line)) { | |
233 | TestBound(Handle(Geom2d_Line)::DownCast(C2Bis2), | |
234 | D2,C2Bis1,D1,TolConf,Standard_True); | |
235 | } | |
236 | Geom2dInt_GInter Intersect; | |
237 | Geom2dAdaptor_Curve AC2Bis1(C2Bis1); | |
238 | Geom2dAdaptor_Curve AC2Bis2(C2Bis2); | |
239 | Intersect.Perform(AC2Bis1,D1,AC2Bis2,D2,TolConf,Tol); | |
240 | Append (Intersect,D1.FirstParameter(),D1.LastParameter(), | |
241 | D2.FirstParameter(),D2.LastParameter()); | |
242 | } | |
243 | else if (Type1 == STANDARD_TYPE(Bisector_BisecPC) || Type2 == STANDARD_TYPE(Bisector_BisecPC)) { | |
244 | Geom2dInt_GInter Intersect; | |
245 | Geom2dAdaptor_Curve ABis1(Bis1); | |
246 | Geom2dAdaptor_Curve ABis2(Bis2); | |
247 | Intersect.Perform(ABis1,D1,ABis2,D2,TolConf,Tol); | |
248 | Append (Intersect,D1.FirstParameter(),D1.LastParameter(), | |
249 | D2.FirstParameter(),D2.LastParameter()); | |
250 | } | |
251 | else if (ComunElement && | |
252 | Type1 == STANDARD_TYPE(Bisector_BisecCC) && Type2 == STANDARD_TYPE(Bisector_BisecCC)) { | |
253 | NeighbourPerform(Handle(Bisector_BisecCC)::DownCast(Bis1),D1, | |
254 | Handle(Bisector_BisecCC)::DownCast(Bis2),D2,Tol); | |
255 | } | |
256 | else { | |
0d969553 Y |
257 | // If we are here one of two bissectrices is a segment. |
258 | // If one of bissectrices is not a segment, it is tested if | |
259 | // its extremities are on the straight line. | |
7fd59977 | 260 | |
261 | if (Type1 == STANDARD_TYPE(Geom2d_Line) && Type2 != STANDARD_TYPE(Geom2d_Line)) { | |
262 | TestBound(Handle(Geom2d_Line)::DownCast(Bis1), | |
263 | D1,Bis2,D2,TolConf,Standard_False); | |
264 | } | |
265 | else if (Type2 == STANDARD_TYPE(Geom2d_Line)&& Type1 != STANDARD_TYPE(Geom2d_Line)) { | |
266 | TestBound(Handle(Geom2d_Line)::DownCast(Bis2), | |
267 | D2,Bis1,D1,TolConf,Standard_True); | |
268 | } | |
269 | Geom2dInt_GInter Intersect; | |
270 | Geom2dAdaptor_Curve ABis1(Bis1); | |
271 | Geom2dAdaptor_Curve ABis2(Bis2); | |
272 | Intersect.Perform(ABis1,D1,ABis2,D2,TolConf,Tol); | |
273 | Append (Intersect,D1.FirstParameter(),D1.LastParameter(), | |
274 | D2.FirstParameter(),D2.LastParameter()); | |
275 | } | |
276 | ||
277 | #ifdef DRAW | |
278 | if (Affich) { | |
279 | Handle(DrawTrSurf_Curve2d) dr; | |
280 | Draw_Color Couleur = Draw_bleu; | |
281 | ||
282 | dr = new DrawTrSurf_Curve2d(Bis1,Couleur,100); | |
283 | dout << dr; | |
284 | dr = new DrawTrSurf_Curve2d(Bis2,Couleur,100); | |
285 | dout << dr; | |
286 | if (IsDone() && !IsEmpty()) { | |
287 | for (Standard_Integer k = 1; k <= NbPoints(); k++) { | |
288 | gp_Pnt2d P = Point(k).Value(); | |
289 | Handle(Draw_Marker2D) drp = new Draw_Marker2D(P,Draw_Plus,Draw_vert); | |
290 | dout << drp; | |
291 | } | |
292 | } | |
293 | dout.Flush(); | |
294 | } | |
295 | #endif | |
296 | } | |
297 | ||
298 | //=================================================================================== | |
299 | // function : NeighbourPerform | |
0d969553 Y |
300 | // putpose : Find the intersection of 2 neighbor bissectrices curve/curve |
301 | // (ie Bis1 separates A and B and Bis2 separates B and C). | |
302 | // Bis1 is parameterized by B and Bis2 by C. | |
7fd59977 | 303 | // |
0d969553 Y |
304 | // Method : Bis2 is parameterized by B |
305 | // 2 bissectrices are thus parameterized by the same curve. | |
306 | // Let D1(u) = d(Bis1(u),B(u)) and D2(U) = d(Bis2(u),B(U)) | |
307 | // Parameter U0 for which D1(U0)-D2(U0) = 0 is found. | |
7fd59977 | 308 | //=================================================================================== |
309 | void Bisector_Inter::NeighbourPerform(const Handle(Bisector_BisecCC)& Bis1, | |
310 | const IntRes2d_Domain& D1, | |
311 | const Handle(Bisector_BisecCC)& Bis2, | |
312 | const IntRes2d_Domain& D2, | |
313 | const Standard_Real Tol) | |
314 | { | |
315 | Standard_Real USol,U1,U2,Dist; | |
316 | #ifndef DEB | |
317 | Standard_Real UMin =0.,UMax =0.; | |
318 | #else | |
319 | Standard_Real UMin,UMax; | |
320 | #endif | |
321 | Standard_Real Eps = Precision::PConfusion(); | |
322 | gp_Pnt2d PSol; | |
323 | ||
324 | Handle(Geom2d_Curve) Guide; | |
325 | Handle(Bisector_BisecCC) BisTemp; | |
326 | ||
0d969553 | 327 | // Change guiedline on Bis2. |
7fd59977 | 328 | BisTemp = Bis2->ChangeGuide(); |
329 | Guide = Bis2->Curve(2); | |
330 | #ifdef DEB | |
331 | gp_Pnt2d P2S = Bis2->ValueAndDist(D2.FirstParameter(),U1,UMax,Dist); | |
332 | gp_Pnt2d P2E = Bis2->ValueAndDist(D2.LastParameter() ,U1,UMin,Dist); | |
333 | #else | |
334 | Bis2->ValueAndDist(D2.FirstParameter(),U1,UMax,Dist); | |
335 | Bis2->ValueAndDist(D2.LastParameter() ,U1,UMin,Dist); | |
336 | #endif | |
0d969553 | 337 | // Calculate the domain of intersection on the guideline. |
7fd59977 | 338 | UMin = Max (D1.FirstParameter(),UMin); |
339 | UMax = Min (D1.LastParameter() ,UMax); | |
340 | ||
341 | done = Standard_True; | |
342 | ||
343 | if (UMin - Eps > UMax + Eps) {return;} | |
344 | ||
0d969553 | 345 | // Solution F = 0 to find the common point. |
7fd59977 | 346 | Bisector_FunctionInter Fint (Guide,Bis1,BisTemp); |
347 | math_BissecNewton Sol (Fint,UMin,UMax,Tol,20); | |
348 | if (Sol.IsDone()) { | |
349 | USol = Sol.Root(); | |
350 | } | |
351 | else { return; } | |
352 | ||
353 | PSol = BisTemp ->ValueAndDist(USol,U1,U2,Dist); | |
354 | ||
355 | IntRes2d_Transition Trans1,Trans2; | |
356 | IntRes2d_IntersectionPoint PointInterSol(PSol,USol,U2, | |
357 | Trans1,Trans2,Standard_False); | |
358 | Append (PointInterSol); | |
359 | } | |
360 | ||
361 | ||
362 | ||
0d969553 | 363 | //===================================================================================== |
7fd59977 | 364 | // function : TestBound |
0d969553 Y |
365 | // putpose : Test if the extremities of Bis2 are on the segment cooresponding to Bis1. |
366 | //===================================================================================== | |
7fd59977 | 367 | void Bisector_Inter::TestBound (const Handle(Geom2d_Line)& Bis1, |
368 | const IntRes2d_Domain& D1, | |
369 | const Handle(Geom2d_Curve)& Bis2, | |
370 | const IntRes2d_Domain& D2, | |
371 | const Standard_Real TolConf, | |
372 | const Standard_Boolean Reverse) | |
373 | { | |
374 | IntRes2d_Transition Trans1,Trans2; | |
375 | IntRes2d_IntersectionPoint PointInterSol; | |
376 | ||
377 | gp_Lin2d L1 = Bis1->Lin2d(); | |
378 | gp_Pnt2d PF = Bis2->Value(D2.FirstParameter()); | |
379 | gp_Pnt2d PL = Bis2->Value(D2.LastParameter()); | |
380 | // Modified by skv - Mon May 5 14:43:28 2003 OCC616 Begin | |
381 | // Standard_Real Tol = Min(TolConf,Precision::Confusion()); | |
382 | // Tol = 10*Tol; | |
383 | Standard_Real Tol = TolConf; | |
384 | // Modified by skv - Mon May 5 14:43:30 2003 OCC616 End | |
385 | ||
386 | Standard_Boolean BisecAlgo = Standard_False; | |
387 | if (Bis2->DynamicType() == STANDARD_TYPE(Bisector_BisecCC)) | |
388 | { | |
389 | BisecAlgo = Standard_True; | |
390 | // Modified by skv - Mon May 5 14:43:45 2003 OCC616 Begin | |
391 | // Tol = 1.e-5; | |
392 | // Modified by skv - Mon May 5 14:43:46 2003 OCC616 End | |
393 | } | |
394 | ||
395 | if (L1.Distance(PF) < Tol) { | |
396 | Standard_Real U1 = ElCLib::Parameter(L1,PF); | |
397 | // Modified by skv - Mon May 5 14:48:12 2003 OCC616 Begin | |
398 | // if ( D1.FirstParameter() - Tol <= U1 && | |
399 | // D1.LastParameter () + Tol >= U1 ) { | |
400 | if ( D1.FirstParameter() - D1.FirstTolerance() < U1 && | |
401 | D1.LastParameter () + D1.LastTolerance() > U1 ) { | |
402 | // Modified by skv - Mon May 5 14:48:14 2003 OCC616 End | |
403 | // PF est sur L1 | |
404 | if (BisecAlgo) | |
405 | PF = ElCLib::Value( U1 , L1 ); | |
406 | PointInterSol.SetValues (PF, U1, D2.FirstParameter(), | |
407 | Trans1, Trans2, Reverse); | |
408 | Append (PointInterSol); | |
409 | } | |
410 | } | |
411 | ||
412 | if (L1.Distance(PL) < Tol) { | |
413 | Standard_Real U1 = ElCLib::Parameter(L1,PL); | |
414 | // Modified by skv - Mon May 5 15:05:48 2003 OCC616 Begin | |
415 | // if ( D1.FirstParameter() - Tol <= U1 && | |
416 | // D1.LastParameter () + Tol >= U1 ) { | |
417 | if ( D1.FirstParameter() - D1.FirstTolerance() < U1 && | |
418 | D1.LastParameter () + D1.LastTolerance() > U1 ) { | |
419 | // Modified by skv - Mon May 5 15:05:49 2003 OCC616 End | |
420 | if (BisecAlgo) | |
421 | PL = ElCLib::Value( U1 , L1 ); | |
422 | PointInterSol.SetValues (PL, U1, D2.LastParameter(), | |
423 | Trans1, Trans2, Reverse); | |
424 | Append (PointInterSol); | |
425 | } | |
426 | } | |
427 | } |