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