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