0024750: Replace instantiations of TCollection generic classes by NCollection templat...
[occt.git] / src / Bisector / Bisector_Inter.cxx
CommitLineData
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>
40static char name[100];
7fd59977 41static Standard_Boolean Affich = Standard_False;
873c119f 42static Standard_Integer nbint = 0;
43#endif
7fd59977 44#endif
45
46//===================================================================================
47// function :
48// putpose :
49//===================================================================================
50Bisector_Inter::Bisector_Inter()
51{
52}
53
54//===================================================================================
55// function :
56// putpose :
57//===================================================================================
58Bisector_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//===================================================================================
73static 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//===================================================================================
89void 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//===================================================================================
209void 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//===================================================================================
316void 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.
859a47c3 349 Bisector_FunctionInter Fint(Guide,Bis1,BisTemp);
350
351 math_BissecNewton aSolution(Tol);
352 aSolution.Perform(Fint, UMin, UMax, 20);
353
354 if (aSolution.IsDone())
355 USol = aSolution.Root();
356 else return;
7fd59977 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 372void 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}