0025334: BRepOffsetAPI_MakeOffset algorithm crashes on some customer's shape
[occt.git] / src / MAT2d / MAT2d_Tool2d.cxx
CommitLineData
b311480e 1// Created on: 1993-07-12
2// Created by: Yves FRICAUD
3// Copyright (c) 1993-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#define Debug(expr) cout<<" MAT2d_Tool2d.cxx : expr :"<<expr<<endl;
18
19#ifdef DRAW
20#include <DBRep.hxx>
21#include <DrawTrSurf.hxx>
22#include <stdio.h>
23#endif
24
25#ifdef DRAW
26#include <Draw_Appli.hxx>
27#include <DrawTrSurf_Curve2d.hxx>
28#include <GCE2d_MakeSegment.hxx>
29#include <DrawTrSurf.hxx>
30#endif
31
32#include <MAT2d_Tool2d.ixx>
33#include <MAT2d_MiniPath.hxx>
34#include <MAT2d_Connexion.hxx>
35#include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
36#include <MAT_Edge.hxx>
37#include <Bisector_Curve.hxx>
38#include <Bisector_BisecAna.hxx>
39#include <Bisector_BisecCC.hxx>
40#include <Bisector_Bisec.hxx>
41#include <Bisector_Inter.hxx>
42#include <IntRes2d_Domain.hxx>
43#include <Extrema_ExtPC2d.hxx>
44#include <Geom2dInt_GInter.hxx>
45#include <IntRes2d_IntersectionPoint.hxx>
46#include <IntRes2d_IntersectionSegment.hxx>
47#include <Geom2d_Geometry.hxx>
48#include <Geom2d_Point.hxx>
49#include <Geom2d_Line.hxx>
50#include <Geom2d_Circle.hxx>
51#include <Geom2d_Curve.hxx>
52#include <Geom2d_Parabola.hxx>
53#include <Geom2d_Hyperbola.hxx>
54#include <Geom2d_Ellipse.hxx>
55#include <Geom2d_CartesianPoint.hxx>
56#include <Geom2d_TrimmedCurve.hxx>
57#include <Geom2dAdaptor_Curve.hxx>
58#include <gp_Lin2d.hxx>
59#include <gp_Hypr2d.hxx>
60#include <gp_Parab2d.hxx>
61#include <gp_Elips2d.hxx>
62#include <gp_Circ2d.hxx>
63#include <gp_Vec2d.hxx>
64#include <TColStd_Array1OfReal.hxx>
65#include <ElCLib.hxx>
66#include <StdFail_NotDone.hxx>
67#include <Standard_NotImplemented.hxx>
68#include <Precision.hxx>
69
70#ifdef DRAW
71 static Handle(DrawTrSurf_Curve2d) draw;
72#endif
73#ifdef DEB
74 static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
75 const Standard_Integer Indice);
76 static Standard_Boolean Store = Standard_False;
77#endif
78
79//=====================================================================
80// static functions
81//=====================================================================
82static IntRes2d_Domain Domain
83 (const Handle(Geom2d_TrimmedCurve)& Bisector1,
84 const Standard_Real Tolerance);
85
86static Handle(Standard_Type) Type (const Handle(Geom2d_Geometry)& acurve);
87
88static Standard_Boolean AreNeighbours(const Standard_Integer IEdge1,
89 const Standard_Integer IEdge2,
90 const Standard_Integer NbEdge);
91
92static void SetTrim(Bisector_Bisec& Bis , Handle(Geom2d_Curve)& Line1);
93
94static Standard_Real MAT2d_TOLCONF = 1.e-7;
95
96//============================================================================
97//function :
98//purpose :
99//============================================================================
100MAT2d_Tool2d::MAT2d_Tool2d()
101{
102 theDirection = 1.;
c19dd45e 103 theJoinType = GeomAbs_Arc; //default
7fd59977 104 theNumberOfBisectors = 0;
105 theNumberOfVecs = 0;
106 theNumberOfPnts = 0;
107}
108
109//=============================================================================
110//function : InitItems
111//purpose :
112//=============================================================================
113void MAT2d_Tool2d::InitItems(const Handle(MAT2d_Circuit)& EquiCircuit)
114{
115 theGeomBisectors.Clear();
116 theGeomPnts.Clear();
117 theGeomVecs.Clear();
118 theLinesLength.Clear();
119 theNumberOfBisectors = 0;
120 theNumberOfVecs = 0;
121 theNumberOfPnts = 0;
122
123 theCircuit = EquiCircuit;
124}
125
126//=============================================================================
127//function : Sense
128//purpose :
129//=============================================================================
130void MAT2d_Tool2d::Sense(const MAT_Side aside)
131{
132 if(aside == MAT_Left) theDirection = 1.;
133 else theDirection = -1.;
134}
135
c19dd45e 136//=============================================================================
137//function : SetJoinType
138//purpose :
139//=============================================================================
140void MAT2d_Tool2d::SetJoinType(const GeomAbs_JoinType aJoinType)
141{
142 theJoinType = aJoinType;
143}
144
7fd59977 145//=============================================================================
146//function : NumberOfItems
147//purpose :
148//=============================================================================
149Standard_Integer MAT2d_Tool2d::NumberOfItems() const
150{
151 return theCircuit->NumberOfItems();
152}
153
154//=============================================================================
155//function : ToleranceOfConfusion
156//purpose :
157//=============================================================================
158Standard_Real MAT2d_Tool2d::ToleranceOfConfusion() const
159{
160 return 2*MAT2d_TOLCONF;
161}
162
163//=============================================================================
164//function : FirstPoint
165//purpose :
166//=============================================================================
167Standard_Integer MAT2d_Tool2d::FirstPoint(const Standard_Integer anitem,
168 Standard_Real& dist )
169{
170 Handle(Geom2d_Curve) curve;
171 Handle(Geom2d_Point) point;
172 theNumberOfPnts++;
173
174 if (theCircuit->ConnexionOn(anitem)){
175 gp_Pnt2d P1 = theCircuit->Connexion(anitem)->PointOnFirst();
176 gp_Pnt2d P2 = theCircuit->Connexion(anitem)->PointOnSecond();
177 theGeomPnts.Bind(theNumberOfPnts,gp_Pnt2d((P1.X() + P2.X())*0.5,
178 (P1.Y() + P2.Y())*0.5));
179 dist = P1.Distance(P2)*0.5;
180 return theNumberOfPnts;
181 }
182
183 Handle(Standard_Type) type;
184 type = theCircuit->Value(anitem)->DynamicType();
185 dist = 0.;
186
187 if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
188 curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
189 theGeomPnts.Bind(theNumberOfPnts,curve->Value(curve->FirstParameter()));
190 }
191 else{
192 point = Handle(Geom2d_Point)::DownCast(theCircuit->Value(anitem));
193 theGeomPnts.Bind(theNumberOfPnts,point->Pnt2d());
194 }
195 return theNumberOfPnts;
196}
197
198//=============================================================================
199//function : TangentBefore
200//purpose :
201//=============================================================================
0e0f7a7c 202Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem,
203 const Standard_Boolean IsOpenResult)
7fd59977 204{
205 Standard_Integer item;
206 Handle(Geom2d_Curve) curve;
207 theNumberOfVecs++;
0e0f7a7c 208
209 if (!IsOpenResult)
210 item = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
211 else
212 item = (anitem == theCircuit->NumberOfItems()) ? (anitem - 1) : (anitem + 1);
7fd59977 213 if (theCircuit->ConnexionOn(item)){
214 Standard_Real x1,y1,x2,y2;
215 theCircuit->Connexion(item)->PointOnFirst().Coord(x1,y1);
216 theCircuit->Connexion(item)->PointOnSecond().Coord(x2,y2);
217 theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x2-x1),(y2-y1)));
218 return theNumberOfVecs;
219 }
220
221 Handle(Standard_Type) type;
222 type = theCircuit->Value(anitem)->DynamicType();
223 if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
224 curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
225 theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->LastParameter(),1));
226 }
227 else {
228 curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
0e0f7a7c 229 Standard_Real param = (IsOpenResult && anitem == theCircuit->NumberOfItems())?
230 curve->LastParameter() : curve->FirstParameter();
231 theGeomVecs.Bind(theNumberOfVecs,curve->DN(param,1));
7fd59977 232 }
233
234 return theNumberOfVecs;
235}
236
237//=============================================================================
238//function : TangentAfter
239//purpose :
240//=============================================================================
0e0f7a7c 241Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem,
242 const Standard_Boolean IsOpenResult)
7fd59977 243{
244 Standard_Integer item;
245 Handle(Geom2d_Curve) curve;
246 gp_Vec2d thevector;
247 theNumberOfVecs++;
248
249 if (theCircuit->ConnexionOn(anitem)){
250 Standard_Real x1,y1,x2,y2;
251 theCircuit->Connexion(anitem)->PointOnFirst().Coord(x1,y1);
252 theCircuit->Connexion(anitem)->PointOnSecond().Coord(x2,y2);
253 theGeomVecs.Bind(theNumberOfVecs,gp_Vec2d((x1-x2),(y1-y2)));
254 return theNumberOfVecs;
255 }
256
257 Handle(Standard_Type) type;
258 type = theCircuit->Value(anitem)->DynamicType();
259 if ( type != STANDARD_TYPE(Geom2d_CartesianPoint)){
260 curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(anitem));
261 thevector = curve->DN(curve->FirstParameter(),1);
262 }
263 else {
0e0f7a7c 264 if (!IsOpenResult)
265 item = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
266 else
267 item = (anitem == 1) ? 2 : (anitem - 1);
7fd59977 268 curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
0e0f7a7c 269 Standard_Real param = (IsOpenResult && anitem == 1)?
270 curve->FirstParameter() : curve->LastParameter();
271 thevector = curve->DN(param,1);
7fd59977 272 }
273 theGeomVecs.Bind(theNumberOfVecs,thevector.Reversed());
274 return theNumberOfVecs;
275}
276
277//=============================================================================
278//function : Tangent
279//purpose :
280//=============================================================================
281Standard_Integer MAT2d_Tool2d::Tangent(const Standard_Integer bisector)
282{
283 theNumberOfVecs++;
284 theGeomVecs.Bind(theNumberOfVecs,GeomBis(bisector).Value()
285 ->DN(GeomBis(bisector).Value()
286 ->LastParameter(),1));
287 return theNumberOfVecs;
288}
289
290//=============================================================================
291//function : CreateBisector
292//purpose :
293//=============================================================================
294void MAT2d_Tool2d::CreateBisector(const Handle(MAT_Bisector)& abisector)
295{
296 Handle(Geom2d_Point) point1,point2;
297 Handle(Geom2d_Geometry) elt1,elt2;
298 Bisector_Bisec bisector;
299 Standard_Real tolerance = MAT2d_TOLCONF ;
300
301 Standard_Integer edge1number = abisector->FirstEdge()->EdgeNumber();
302 Standard_Integer edge2number = abisector->SecondEdge()->EdgeNumber();
303 Standard_Boolean ontheline = AreNeighbours(edge1number,
304 edge2number,
305 NumberOfItems());
306 Standard_Boolean InitialNeighbour = ontheline;
307
308 if(theCircuit->ConnexionOn(edge2number)) ontheline = Standard_False;
309
310 elt1 = theCircuit->Value(edge1number);
311 elt2 = theCircuit->Value(edge2number);
312
313 Handle(Standard_Type) type1;
314 type1 = theCircuit->Value(edge1number)->DynamicType();
315 Handle(Standard_Type) type2;
316 type2 = theCircuit->Value(edge2number)->DynamicType();
317 Handle(Geom2d_Curve) item1;
318 Handle(Geom2d_Curve) item2;
319
320 if ( type1 != STANDARD_TYPE(Geom2d_CartesianPoint)){
321 item1 = Handle(Geom2d_Curve)::DownCast(elt1);
322 }
323
324 if ( type2 != STANDARD_TYPE(Geom2d_CartesianPoint)){
325 item2 = Handle(Geom2d_Curve)::DownCast(elt2);
326 }
327
328#ifdef DEB
329 Standard_Boolean Affich = Standard_False;
330 if (Affich) {
331 cout<<endl;
332 cout<<"BISECTOR number : "<<theNumberOfBisectors+1<<endl;
333 cout<<" Item 1 : "<<endl;
334 cout<<edge1number<<endl;
335 cout<<endl;
336// elt1->Dump(1,1);
337 cout<<endl;
338 cout<<" Item 2 : "<<endl;
339 cout<<edge2number<<endl;
340 cout<<endl;
341// elt2->Dump(1,1);
342 cout<<endl;
343 }
344#endif
345
346 if(type1 != STANDARD_TYPE(Geom2d_CartesianPoint) &&
347 type2 != STANDARD_TYPE(Geom2d_CartesianPoint)) {
348 bisector.Perform(item1,item2,
349 GeomPnt (abisector->IssuePoint()),
350 GeomVec (abisector->FirstVector()),
351 GeomVec (abisector->SecondVector()),
352 theDirection,tolerance,ontheline);
353 }
354 else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint) &&
355 type2 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
356 point1 = Handle(Geom2d_Point)::DownCast(elt1);
357 point2 = Handle(Geom2d_Point)::DownCast(elt2);
358 bisector.Perform(point1,point2,
359 GeomPnt (abisector->IssuePoint()),
360 GeomVec (abisector->FirstVector()),
361 GeomVec (abisector->SecondVector()),
362 theDirection,tolerance,ontheline);
363 }
364 else if(type1 == STANDARD_TYPE(Geom2d_CartesianPoint)) {
365 point1 = Handle(Geom2d_Point)::DownCast(elt1);
366 bisector.Perform(point1,item2,
367 GeomPnt (abisector->IssuePoint()),
368 GeomVec (abisector->FirstVector()),
369 GeomVec (abisector->SecondVector()),
370 theDirection,tolerance,ontheline);
371 }
372 else {
373 point2 = Handle(Geom2d_Point)::DownCast(elt2);
374 bisector.Perform(item1,point2,
375 GeomPnt (abisector->IssuePoint()),
376 GeomVec (abisector->FirstVector()),
377 GeomVec (abisector->SecondVector()),
378 theDirection,tolerance,ontheline);
379 }
380
381 //------------------------------
382 // Restriction de la bisectrice.
383 //-----------------------------
384 TrimBisec(bisector,edge1number,InitialNeighbour,1);
385 TrimBisec(bisector,edge2number,InitialNeighbour,2);
386
387 theNumberOfBisectors++;
388 theGeomBisectors.Bind(theNumberOfBisectors,bisector);
389
390 abisector->BisectorNumber(theNumberOfBisectors);
391 abisector->Sense(1);
392
393#ifdef DEB
394 Standard_Boolean AffichDraw = Standard_False;
395 if (AffichDraw) Dump(abisector->BisectorNumber(),1);
396 if (Store) {
397 Handle(Standard_Type) Type1 = Type(bisector.Value()->BasisCurve());
398 Handle(Geom2d_Curve) BasisCurve;
399 if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) {
400 BasisCurve = Handle(Bisector_BisecAna)
401 ::DownCast(bisector.Value()->BasisCurve())->Geom2dCurve();
402#ifdef DRAW
403 char *name = new char[100];
404 sprintf(name,"BISSEC_%d",abisector->BisectorNumber());
405 DrawTrSurf::Set(name,BasisCurve);
406 delete [] name;
407#endif
408 }
409 }
410#endif
411}
412
413//=============================================================================
414//function : TrimBisec
415//purpose : Restriction de la bisectrice.
416// Restriction des bissectrice separant deux elements lies par une
417// connexion ou l un au moins des elements est un cercle.
418// Cette restriction est necessaire a la logique de l algorithme.
419//=============================================================================
420void MAT2d_Tool2d::TrimBisec ( Bisector_Bisec& B1,
421 const Standard_Integer IndexEdge,
422 const Standard_Boolean InitialNeighbour,
423 const Standard_Integer StartOrEnd ) const
424{
425 Handle(Geom2d_Curve) Curve;
426 Handle(Geom2d_TrimmedCurve) LineSupportDomain,Line;
427 Handle(Geom2d_Line) Line1,Line2;
428
429 //gp_Vec2d Tan1,Tan2;
430 gp_Pnt2d Ori; //PEdge;
96a95605 431 Standard_Integer INext;
7fd59977 432 INext = (IndexEdge == theCircuit->NumberOfItems()) ? 1 : (IndexEdge + 1);
433
434 Handle(Standard_Type) EdgeType = theCircuit->Value(IndexEdge)->DynamicType();
435
436 if (EdgeType != STANDARD_TYPE(Geom2d_CartesianPoint)) {
437 if(!InitialNeighbour) {
438 Curve = Handle(Geom2d_TrimmedCurve)
439 ::DownCast(theCircuit->Value(IndexEdge))->BasisCurve();
440 EdgeType = Curve->DynamicType();
441 //-------------------------------------------------------------------
442 // si l edge est liee a sa voisine precedente par une connexion.
443 //-------------------------------------------------------------------
444 if (theCircuit->ConnexionOn(IndexEdge) && StartOrEnd == 1){
445 if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) {
446 Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location();
447 gp_Pnt2d P2 = theCircuit->Connexion(IndexEdge)->PointOnFirst();
448 Line1 = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(),
449 P2.Y() - Ori.Y()));
450 }
451 }
452 //-----------------------------------------------------------------------
453 // Si l edge est liee a sa voisine suivante par une connexion.
454 //-----------------------------------------------------------------------
455 if (theCircuit->ConnexionOn(INext) && StartOrEnd == 2){
456 if (EdgeType == STANDARD_TYPE(Geom2d_Circle)) {
457 Ori = Handle(Geom2d_Circle)::DownCast(Curve)->Location();
458 gp_Pnt2d P2 = theCircuit->Connexion(INext)->PointOnSecond();
459 Line2 = new Geom2d_Line (Ori,gp_Dir2d(P2.X() - Ori.X(),
460 P2.Y() - Ori.Y()));
461 }
462 }
463 if (Line1.IsNull() && Line2.IsNull()) return;
464
465 //-----------------------------------------------------------------------
466 // Restriction de la bisectrice par les demi-droites liees aux connexions
467 // si elles existent.
468 //-----------------------------------------------------------------------
469 if (!Line1.IsNull()) {
470 Line = new Geom2d_TrimmedCurve(Line1,0.,Precision::Infinite());
471 SetTrim(B1,Line);
472 }
473 if (!Line2.IsNull()) {
474 Line = new Geom2d_TrimmedCurve(Line2,0.,Precision::Infinite());
475 SetTrim(B1,Line);
476 }
477 }
478 }
479}
480
481//=============================================================================
482//function : TrimBisector
483//purpose :
484//=============================================================================
485Standard_Boolean MAT2d_Tool2d::TrimBisector
486 (const Handle(MAT_Bisector)& abisector)
487{
488 Standard_Real param = abisector->FirstParameter();
489
490#ifdef DEB
491 Standard_Boolean Affich = Standard_False;
492 if (Affich) cout<<"TRIM de "<<abisector->BisectorNumber()<<endl;
493#endif
494
495 Handle(Geom2d_TrimmedCurve)
496 bisector = Handle(Geom2d_TrimmedCurve)
497 ::DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
498
499 if(bisector->BasisCurve()->IsPeriodic() && param == Precision::Infinite()) {
c6541a0c 500 param = bisector->FirstParameter() + 2*M_PI;
7fd59977 501 }
502 if (param > bisector->BasisCurve()->LastParameter()) {
503 param = bisector->BasisCurve()->LastParameter();
504 }
505 if(bisector->FirstParameter() == param) return Standard_False;
506
507 bisector->SetTrim(bisector->FirstParameter(),param);
508 return Standard_True;
509}
510
511//=============================================================================
512//function : TrimBisector
513//purpose :
514//=============================================================================
515Standard_Boolean MAT2d_Tool2d::TrimBisector
516 (const Handle(MAT_Bisector)& abisector,
517 const Standard_Integer apoint)
518{
519 Standard_Real Param;
520 Handle(Geom2d_TrimmedCurve)
521 Bisector = Handle(Geom2d_TrimmedCurve)::
522 DownCast(ChangeGeomBis(abisector->BisectorNumber()).ChangeValue());
523
524 Handle(Bisector_Curve) Bis = Handle(Bisector_Curve)::
525 DownCast(Bisector->BasisCurve());
526
527// Param = ParameterOnCurve(Bisector,theGeomPnts.Value(apoint));
528 Param = Bis->Parameter(GeomPnt (apoint));
529
530 if (Bisector->BasisCurve()->IsPeriodic()) {
c6541a0c 531 if (Bisector->FirstParameter() > Param) Param = Param + 2*M_PI;
7fd59977 532 }
533 if(Bisector->FirstParameter() >= Param)return Standard_False;
534 if(Bisector->LastParameter() < Param)return Standard_False;
535 Bisector->SetTrim(Bisector->FirstParameter(),Param);
536
537#ifdef DEB
538 Standard_Boolean Affich = Standard_False;
539 if (Affich) MAT2d_DrawCurve(Bisector,2);
540#endif
541
542 return Standard_True;
543}
544
545//=============================================================================
546//function : Projection
547//purpose :
548//=============================================================================
549Standard_Boolean MAT2d_Tool2d::Projection (const Standard_Integer IEdge ,
550 const gp_Pnt2d& PCom ,
551 Standard_Real& Distance)
552 const
553{
554 gp_Pnt2d PEdge;
555 Handle(Geom2d_Geometry) Elt = theCircuit->Value(IEdge);
556 Handle(Standard_Type) Type = Elt->DynamicType();
557 Handle(Geom2d_TrimmedCurve) Curve;
558 Standard_Integer INext;
7fd59977 559 Standard_Real Eps = MAT2d_TOLCONF;//*10.;
560
561 if (Type == STANDARD_TYPE(Geom2d_CartesianPoint)) {
562 PEdge = Handle(Geom2d_Point)::DownCast(Elt)->Pnt2d();
563 Distance = PCom.Distance(PEdge);
564 }
565 else {
566 Distance = Precision::Infinite();
567 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Elt);
568 //-----------------------------------------------------------------------
569 // Calcul des parametres MinMax sur l edge si celui ci est lies a ses
570 // voisins par des connexions la courbe de calcul est limitee par
571 // celles_ci.
572 //-----------------------------------------------------------------------
573 Standard_Real ParamMin = Curve->FirstParameter();
574 Standard_Real ParamMax = Curve->LastParameter();
575 if (theCircuit->ConnexionOn(IEdge)) {
576 ParamMin = theCircuit->Connexion(IEdge)->ParameterOnSecond();
577 }
578 INext = (IEdge == theCircuit->NumberOfItems()) ? 1 : (IEdge + 1);
579 if (theCircuit->ConnexionOn(INext)) {
580 ParamMax = theCircuit->Connexion(INext)->ParameterOnFirst();
581 if (Curve->BasisCurve()->IsPeriodic()){
c6541a0c 582 ElCLib::AdjustPeriodic(0.,2*M_PI,Eps,ParamMin,ParamMax);
7fd59977 583 }
584 }
585 //---------------------------------------------------------------------
586 // Constuction de la courbe pour les extremas et ajustement des bornes.
587 //---------------------------------------------------------------------
588 Geom2dAdaptor_Curve C1(Curve);
589 GeomAbs_CurveType TypeC1 = C1.GetType();
590 if (TypeC1 == GeomAbs_Circle) {
591 Standard_Real R = C1.Circle().Radius();
592 Standard_Real EpsCirc = Eps;
593 if ( R < 1.) EpsCirc = Eps/R;
c6541a0c 594 if (!((ParamMax - ParamMin + 2*EpsCirc) < 2*M_PI)) {
7fd59977 595 ParamMax = ParamMax + EpsCirc; ParamMin = ParamMin - EpsCirc;
596 }
597 }
598 else {
599 ParamMax = ParamMax + Eps; ParamMin = ParamMin - Eps;
600 }
601 //-----------------------------------------------------
602 // Calcul des extremas et stockage minimum de distance.
603 //-----------------------------------------------------
604 Extrema_ExtPC2d Extremas(PCom,C1,ParamMin,ParamMax);
605 if (Extremas.IsDone()){
606 if (Extremas.NbExt() == 0 ) return Standard_False; // Pas de solution!
607 for (Standard_Integer i = 1; i <= Extremas.NbExt(); i++) {
608 if (Extremas.SquareDistance(i) < Distance * Distance) {
7fd59977 609 Distance = sqrt (Extremas.SquareDistance(i));
610 }
611 }
612 }
613 else {
614 if (TypeC1 == GeomAbs_Circle) {
615 Distance = C1.Circle().Radius();
616 }
617 }
618 }
619 return Standard_True;
620}
621
622//=============================================================================
623//function : IsSameDistance
624// purpose :
625//=============================================================================
626Standard_Boolean MAT2d_Tool2d::IsSameDistance (
627 const Handle(MAT_Bisector)& BisectorOne,
628 const Handle(MAT_Bisector)& BisectorTwo,
629 const gp_Pnt2d& PCom,
630 Standard_Real& Distance) const
631{
632 TColStd_Array1OfReal Dist(1,4);
633 Standard_Integer IEdge1,IEdge2,IEdge3,IEdge4;
634
635 IEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
636 IEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
637 IEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
638 IEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
639
640 Projection(IEdge1,PCom,Dist(1));
641 Projection(IEdge2,PCom,Dist(2));
642
643 if (IEdge3 == IEdge1) Dist(3) = Dist(1);
644 else if (IEdge3 == IEdge2) Dist(3) = Dist(2);
645 else Projection(IEdge3,PCom,Dist(3));
646
647 if (IEdge4 == IEdge1) Dist(4) = Dist(1);
648 else if (IEdge4 == IEdge2) Dist(4) = Dist(2);
649 else Projection(IEdge4,PCom,Dist(4));
650
651#ifdef DEB
652 Standard_Boolean Affich = Standard_False;
653 if (Affich)
654 for (Standard_Integer j = 1; j <= 4;j++){
655 cout <<"Distance number : "<<j<<" is :"<< Dist(j)<<endl;
656 }
657#endif
658
659 Standard_Real EpsDist = MAT2d_TOLCONF*100. ;
660 Distance = Dist(1);
661 for (Standard_Integer i = 1; i <= 4; i++){
c19dd45e 662 if (theJoinType == GeomAbs_Intersection &&
663 Precision::IsInfinite(Dist(i)))
664 continue;
7fd59977 665 if (Abs(Dist(i) - Distance) > EpsDist) {
666 Distance = Precision::Infinite();
667 return Standard_False;
668 }
669 }
670 return Standard_True;
671}
672
673//=============================================================================
674//function : IntersectBisector
675//purpose :
676//=============================================================================
677Standard_Real MAT2d_Tool2d::IntersectBisector (
678 const Handle(MAT_Bisector)& BisectorOne,
679 const Handle(MAT_Bisector)& BisectorTwo,
680 Standard_Integer& IntPnt)
681{
682 Standard_Real Tolerance = MAT2d_TOLCONF;
683 Standard_Real Param1,Param2;
684 Standard_Real Parama,Paramb;
1d47d8d0 685 Standard_Real Distance = 0.,DistanceMini;
7fd59977 686 Standard_Boolean SolutionValide;
687 gp_Pnt2d PointSolution;
688
689 Handle(Geom2d_TrimmedCurve)
690 Bisector1 = Handle(Geom2d_TrimmedCurve)
691 ::DownCast(ChangeGeomBis(BisectorOne->BisectorNumber()).ChangeValue());
692
693 Handle(Geom2d_TrimmedCurve)
694 Bisector2 = Handle(Geom2d_TrimmedCurve)
695 ::DownCast(ChangeGeomBis(BisectorTwo->BisectorNumber()).ChangeValue());
696
697 if(Bisector1.IsNull() || Bisector2.IsNull()) return Precision::Infinite();
698
699 //-------------------------------------------------------------------------
700 // Si les deux bissectrices separent des elements consecutifs et qu elles
701 // sont issues des connexions C1 et C2.
702 // Si C1 est la reverse de C2 ,alors les deux bissectrices sont issues
703 // du meme point. Dans ce cas l intersection n est pas validee.
704 //-------------------------------------------------------------------------
705 Standard_Integer IS1 = BisectorOne->SecondEdge()->EdgeNumber();
706 Standard_Integer IS2 = BisectorTwo->SecondEdge()->EdgeNumber();
707 Standard_Integer IF1 = BisectorOne->FirstEdge() ->EdgeNumber();
708 Standard_Integer IF2 = BisectorTwo->FirstEdge() ->EdgeNumber();
709
710 if (AreNeighbours(IF1,IS1,NumberOfItems()) &&
711 AreNeighbours(IF2,IS2,NumberOfItems()) &&
712 theCircuit->ConnexionOn(IS2) &&
713 theCircuit->ConnexionOn(IS1) ) {
714 Handle(MAT2d_Connexion) C1,C2;
715 C1 = theCircuit->Connexion(IS1);
716 C2 = theCircuit->Connexion(IS2);
717 if (C2->IndexFirstLine() == C1->IndexSecondLine() &&
718 C1->IndexFirstLine() == C2->IndexSecondLine() )
719 return Precision::Infinite();
720 }
721
722 // -----------------------------------------
723 // Construction des domaines d intersection.
724 // -----------------------------------------
725 IntRes2d_Domain Domain1 = Domain(Bisector1,Tolerance);
726 IntRes2d_Domain Domain2 = Domain(Bisector2,Tolerance);
727
728 if (Domain1.LastParameter() - Domain1.FirstParameter() < Tolerance)
729 return Precision::Infinite();
730 if (Domain2.LastParameter() - Domain2.FirstParameter() < Tolerance)
731 return Precision::Infinite();
732
733#ifdef DEB
734 Standard_Boolean Affich = Standard_False;
735 if (Affich) {
736 cout<<endl;
737 cout<<"INTERSECTION de "<<BisectorOne->BisectorNumber()<<
738 " et de "<<BisectorTwo->BisectorNumber()<<endl;
739 cout<<" Bisector 1 : "<<endl;
740// (Bisector1->BasisCurve())->Dump(-1,1);
741 cout<<endl;
742 Debug(Domain1.FirstParameter());
743 Debug(Domain1.LastParameter());
744 cout<<"-----------------"<<endl;
745 cout<<" Bisector 2 : "<<endl;
746// (Bisector2->BasisCurve())->Dump(-1,1);
747 cout<<endl;
748 Debug(Domain2.FirstParameter());
749 Debug(Domain2.LastParameter());
750 cout<<"-----------------"<<endl;
751 }
752#endif
753
754// -------------------------
755// Calcul de l intersection.
756// -------------------------
757
758 Bisector_Inter Intersect;
759 Intersect.Perform (GeomBis(BisectorOne->BisectorNumber()),Domain1,
760 GeomBis(BisectorTwo->BisectorNumber()),Domain2,
761 Tolerance,Tolerance,Standard_True);
762
763// Geom2dInt_GInter Intersect;
764// Intersect.Perform(Bisector1,Domain1,Bisector2,Domain2,Tolerance,Tolerance);
765
766// -------------------------------------------------------------------------
767// Exploitation du resultat de l intersection et selection du point solution
768// equidistant des deux edges et le plus proche en parametre de l origine
769// des bissectrices.
770// -------------------------------------------------------------------------
771
772 if(!Intersect.IsDone()) return Precision::Infinite();
773
774 if(Intersect.IsEmpty()) return Precision::Infinite();
775
776 DistanceMini = Precision::Infinite();
777 Param1 = Precision::Infinite();
778 Param2 = Precision::Infinite();
779 SolutionValide = Standard_False;
780
781 if(Intersect.NbSegments() >= 1) {
782 Standard_Real MaxSegmentLength = 10.*Tolerance;
783 for (Standard_Integer i=1;i<=Intersect.NbSegments();i++) {
784 IntRes2d_IntersectionSegment Segment = Intersect.Segment(i);
785 Standard_Boolean PointRetenu = Standard_False;
786 gp_Pnt2d PointOnSegment;
787 // ----------------------------------------------------------------
788 // Si les segments sont petits, recherche des points sur le segment
789 // equidistants des edges.
790 // ----------------------------------------------------------------
791 if ((Segment.HasFirstPoint() && Segment.HasLastPoint())) {
792 gp_Pnt2d P1,P2;
793 Standard_Real SegmentLength;
794 P1 = Segment.FirstPoint().Value();
795 P2 = Segment.LastPoint().Value();
796 SegmentLength = P1.Distance(P2);
797 if (SegmentLength <= Tolerance) {
798 PointOnSegment = P1;
799 if(IsSameDistance(BisectorOne,BisectorTwo,
800 PointOnSegment,Distance))
801 PointRetenu = Standard_True;
802 }
803 else if (SegmentLength <= MaxSegmentLength) {
804 gp_Dir2d Dir(P2.X()-P1.X(),P2.Y()-P1.Y());
805 Standard_Real Dist = 0.;
806 while (Dist <= SegmentLength + Tolerance){
807 PointOnSegment = P1.Translated(Dist*Dir);
808 if(IsSameDistance(BisectorOne,BisectorTwo,
809 PointOnSegment,Distance)) {
810 PointRetenu = Standard_True;
811 break;
812 }
813 Dist = Dist + Tolerance;
814 }
815 }
816 }
817
818 // ----------------------------------------------------------------
819 // Sauvegarde du point equidistant des edges de plus petit
820 // parametre sur les bissectrices.
821 // ----------------------------------------------------------------
822 if(PointRetenu) {
823 Parama = Handle(Bisector_Curve)::DownCast(Bisector1->BasisCurve())
824 ->Parameter(PointOnSegment);
825 Paramb = Handle(Bisector_Curve)::DownCast(Bisector2->BasisCurve())
826 ->Parameter(PointOnSegment);
827 if(Parama < Param1 && Paramb < Param2) {
828 Param1 = Parama;
829 Param2 = Paramb;
830 DistanceMini = Distance;
831 PointSolution = PointOnSegment;
832 SolutionValide = Standard_True;
833 }
834 }
835 }
836 }
837
838 if(Intersect.NbPoints() != 1) {
839 for(Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
840 if(IsSameDistance(BisectorOne,BisectorTwo,
841 Intersect.Point(i).Value(),Distance) &&
842 Distance > Tolerance ) {
843 Parama = Intersect.Point(i).ParamOnFirst();
844 Paramb = Intersect.Point(i).ParamOnSecond();
845 if (Parama < Param1 && Paramb < Param2) {
846 Param1 = Parama;
847 Param2 = Paramb;
848 DistanceMini = Distance;
849 PointSolution = Intersect.Point(i).Value();
850 SolutionValide = Standard_True;
851 }
852 }
853 }
854 }
855 else {
856 PointSolution = Intersect.Point(1).Value();
857 Param1 = Intersect.Point(1).ParamOnFirst();
858 Param2 = Intersect.Point(1).ParamOnSecond();
859 SolutionValide = IsSameDistance(BisectorOne,BisectorTwo,
860 PointSolution,DistanceMini);
861 }
862
863 if (!SolutionValide) return Precision::Infinite();
864 theNumberOfPnts++;
865 theGeomPnts.Bind(theNumberOfPnts,PointSolution);
866 IntPnt = theNumberOfPnts;
867
868 //-----------------------------------------------------------------------
869 // Si le point d intersection est quasi confondue avec une des extremites
870 // de l une ou l autre des bisectrices, l intersection n est pas validee.
871 //
872 // SAUF si une des bisectrices est issue d une connexion et que les
873 // edges separes par les bissectrices sont des voisines sur le contour
874 // initiales.
875 // en effet le milieu de la connexion P qui est l origine d une des
876 // bissectrices peut etre sur l autre bissectrice.
877 // P est donc point d intersection
878 // et la bissectrice issue de la connexion est de longueur nulle.
879 // (ex : un rectangle dans un rectangle ou la connexion est entre un coin
880 // et un cote).
881 //-----------------------------------------------------------------------
882
883 Standard_Integer IndexEdge1,IndexEdge2,IndexEdge3,IndexEdge4;
884 Standard_Boolean ExtremiteControle = Standard_True;
885
886 IndexEdge1 = BisectorOne->FirstEdge() ->EdgeNumber();
887 IndexEdge2 = BisectorOne->SecondEdge()->EdgeNumber();
888 IndexEdge3 = BisectorTwo->FirstEdge() ->EdgeNumber();
889 IndexEdge4 = BisectorTwo->SecondEdge()->EdgeNumber();
890
891 if (theCircuit->ConnexionOn(IndexEdge2)){
892 // --------------------------------------
893 // BisectorOne est issue d une connexion.
894 // --------------------------------------
895 if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) &&
896 AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) &&
897 IndexEdge2 == IndexEdge3 ){
898 ExtremiteControle = Standard_False;
899 Param1 = Param1 + Tolerance;
900 }
901 }
902
903 if (theCircuit->ConnexionOn(IndexEdge4)){
904 // --------------------------------------
905 // BisectorTwo est issue d une connexion.
906 // --------------------------------------
907 if (AreNeighbours(IndexEdge1,IndexEdge2,NumberOfItems()) &&
908 AreNeighbours(IndexEdge3,IndexEdge4,NumberOfItems()) &&
909 IndexEdge2 == IndexEdge3 ){
910 ExtremiteControle = Standard_False;
911 Param2 = Param2 + Tolerance;
912 }
913 }
914
915 if (ExtremiteControle) {
916 if(Bisector1->StartPoint().Distance(PointSolution) < Tolerance ||
917 Bisector2->StartPoint().Distance(PointSolution) < Tolerance )
918 return Precision::Infinite();
919 }
920
921 if(BisectorOne->SecondParameter() < Precision::Infinite() &&
922 BisectorOne->SecondParameter() < Param1*(1. - Tolerance ))
923 return Precision::Infinite();
924
925 if(BisectorTwo->FirstParameter() < Precision::Infinite() &&
926 BisectorTwo->FirstParameter() < Param2*(1.- Tolerance))
927 return Precision::Infinite();
928
929 BisectorOne->SecondParameter(Param1);
930 BisectorTwo->FirstParameter (Param2);
931
932#ifdef DEB
933 if (Affich) {
934 cout<<" coordonnees : "<<GeomPnt (IntPnt).X()<<" "
935 <<GeomPnt (IntPnt).Y()<<endl;
936 cout<<" parametres : "<<Param1<<" "<<Param2<<endl;
937 cout<<" distancemini : "<<DistanceMini<<endl;
938 }
939#endif
940
941 return DistanceMini;
942}
943
944//=============================================================================
945//function : Distance
946//purpose :
947//=============================================================================
948Standard_Real MAT2d_Tool2d::Distance(const Handle(MAT_Bisector)& Bis,
949 const Standard_Real Param1,
950 const Standard_Real Param2) const
951{
952 Standard_Real Dist = Precision::Infinite();
953
954 if (Param1 != Precision::Infinite() && Param2 != Precision::Infinite()) {
955 gp_Pnt2d P1 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param1);
956 gp_Pnt2d P2 = GeomBis(Bis->BisectorNumber()).Value()->Value(Param2);
957 Dist = P1.Distance(P2);
958 }
959 return Dist;
960}
961
962//=============================================================================
963//function : Dump
964//purpose :
965//=============================================================================
966#ifndef DEB
967void MAT2d_Tool2d::Dump(const Standard_Integer ,
968 const Standard_Integer ) const
969{
970 Standard_NotImplemented::Raise();
971#else
972void MAT2d_Tool2d::Dump(const Standard_Integer bisector,
973 const Standard_Integer) const
974{
975 if(bisector == -1) return;
976 if(bisector > theNumberOfBisectors) return;
977
978 Handle(Geom2d_Curve) thebisector = GeomBis(bisector).Value();
979
980 MAT2d_DrawCurve(thebisector,3);
981
982#endif
983}
984
985
986//=============================================================================
987//function : GeomBis
988//purpose :
989//=============================================================================
990const Bisector_Bisec& MAT2d_Tool2d::GeomBis (const Standard_Integer Index)
991 const
992{
993 return theGeomBisectors.Find(Index);
994}
995
996//=============================================================================
997//function : ChangeGeomBis
998//purpose :
999//=============================================================================
1000Bisector_Bisec& MAT2d_Tool2d::ChangeGeomBis(const Standard_Integer Index)
1001{
1002 return theGeomBisectors.ChangeFind(Index);
1003}
1004
1005
1006//=============================================================================
1007//function : GeomElt
1008//purpose :
1009//=============================================================================
1010Handle(Geom2d_Geometry) MAT2d_Tool2d::GeomElt(const Standard_Integer Index)
1011 const
1012{
1013 return theCircuit->Value(Index);
1014}
1015
1016
1017//=============================================================================
1018//function : GeomPnt
1019//purpose :
1020//=============================================================================
1021const gp_Pnt2d& MAT2d_Tool2d::GeomPnt(const Standard_Integer Index) const
1022{
1023 return theGeomPnts.Find(Index);
1024}
1025
1026//=============================================================================
1027//function : GeomVec
1028//purpose :
1029//=============================================================================
1030const gp_Vec2d& MAT2d_Tool2d::GeomVec(const Standard_Integer Index)const
1031{
1032 return theGeomVecs.Find(Index);
1033}
1034
1035//=============================================================================
1036//function : Circuit
1037//purpose :
1038//=============================================================================
1039Handle(MAT2d_Circuit) MAT2d_Tool2d::Circuit()const
1040{
1041 return theCircuit;
1042}
1043
1044//=============================================================================
1045//function : BisecFusion
1046//purpose :
1047//=============================================================================
1048void MAT2d_Tool2d::BisecFusion(const Standard_Integer I1,
1049 const Standard_Integer I2)
1050{
1051 Standard_Real DU,UL1,UF1;
1052 Handle(Geom2d_TrimmedCurve) Bisector1;
1053 Handle(Geom2d_TrimmedCurve) Bisector2;
1054
1055 Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I1).Value());
1056 Bisector2 = Handle(Geom2d_TrimmedCurve)::DownCast(GeomBis(I2).Value());
1057 UF1 = Bisector1->FirstParameter();
1058 UL1 = Bisector1->LastParameter();
1059
1060 Handle(Standard_Type) Type1 = Bisector1->BasisCurve()->DynamicType();
1061 if (Type1 == STANDARD_TYPE(Bisector_BisecCC)) {
1062 //------------------------------------------------------------------------------------
1063 // les bissectrice courbe/courbe sont construites avec un point de depart
1064 // elles ne peuvent pas etre trimes par un point se trouvant de l autre cote du
1065 // point de depart.
1066 // pour faire la fusion des deux bissectrices on reconstruit la bissectrice entre les
1067 // deux courbes avec comme point de depart le dernier point de la Bisector2.
1068 // on trime ensuite la courbe par le dernier point de Bisector1.
1069 //------------------------------------------------------------------------------------
1070 Standard_Real Tolerance = MAT2d_TOLCONF;
1071 Bisector_Bisec Bis;
1072 gp_Vec2d VBid(1,0);
1073 gp_Pnt2d P2 = Bisector2->Value(Bisector2->LastParameter());
1074 gp_Pnt2d P1 = Bisector1->Value(Bisector1->LastParameter());
1075 Handle(Bisector_BisecCC) BCC1 = Handle(Bisector_BisecCC)::DownCast(Bisector1->BasisCurve());
1076
1077 Bis.Perform(BCC1->Curve(2), BCC1->Curve(1), P2, VBid, VBid,
1078 theDirection, Tolerance, Standard_False);
1079
1080 Bisector1 = Handle(Geom2d_TrimmedCurve)::DownCast(Bis.Value());
1081 BCC1 = Handle(Bisector_BisecCC) ::DownCast(Bisector1->BasisCurve());
1082 UF1 = BCC1->FirstParameter();
1083 UL1 = BCC1->Parameter(P1);
1084 Bisector1->SetTrim(UF1,UL1);
1085 theGeomBisectors.Bind(I1,Bis);
1086 }
1087 else {
1088 DU = Bisector2->LastParameter() - Bisector2->FirstParameter();
1089 UF1 = UF1 - DU;
1090
1091 Handle(Bisector_BisecAna) BAna = Handle(Bisector_BisecAna)::DownCast(Bisector1->BasisCurve());
1092//---------------------------- uncomment if new method Bisector_BisecAna::SetTrim(f,l) is not used
1093// Handle(Geom2d_Curve) C2d = BAna->Geom2dCurve();
1094// Handle(Geom2d_TrimmedCurve) trimC2d = new Geom2d_TrimmedCurve(C2d, UF1, UL1);
1095// BAna->Init(trimC2d);
1096//--------------------------- end
1097 BAna->SetTrim(UF1,UL1); // put comment if SetTrim(f,l) is not used
1098
1099 Bisector1->SetTrim(UF1,UL1);
1100 }
1101}
1102
1103//=============================================================================
1104//function : Type
1105//purpose :
1106//=============================================================================
1107static Handle(Standard_Type) Type(const Handle(Geom2d_Geometry)& aGeom)
1108{
1109 Handle(Standard_Type) type = aGeom->DynamicType();
1110 Handle(Geom2d_Curve) curve;
1111
1112 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1113 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aGeom)->BasisCurve();
1114 type = curve->DynamicType();
1115 }
1116 return type;
1117}
1118
1119//==========================================================================
1120//function : AreNeighbours
1121//purpose : Return TRUE si IEdge1 et IEdge2 correspondent a des elements
1122// consecutifs sur un contour ferme de NbEdge elements.
1123//==========================================================================
1124Standard_Boolean AreNeighbours(const Standard_Integer IEdge1,
1125 const Standard_Integer IEdge2,
1126 const Standard_Integer NbEdge)
1127{
1128 if (Abs(IEdge1 - IEdge2) == 1) return Standard_True;
1129 else if (Abs(IEdge1 - IEdge2) == NbEdge -1) return Standard_True;
1130 else return Standard_False;
1131}
1132
1133//==========================================================================
1134//function : SetTrim
1135//purpose :
1136//==========================================================================
1137void SetTrim(Bisector_Bisec& Bis, Handle(Geom2d_Curve)& Line1)
1138{
1139 Geom2dInt_GInter Intersect;
1140 Standard_Real Distance;
1141 Standard_Real Tolerance = MAT2d_TOLCONF;
1142 Handle(Geom2d_TrimmedCurve) Bisector =
1143 Handle(Geom2d_TrimmedCurve)::DownCast(Bis.ChangeValue());
1144
1145 IntRes2d_Domain Domain1 = Domain(Bisector,Tolerance);
1146 Standard_Real UB1 = Bisector->FirstParameter();
1147 Standard_Real UB2 = Bisector->LastParameter();
1148
1149 gp_Pnt2d FirstPointBisector = Bisector->Value(UB1);
1150 Standard_Real UTrim = Precision::Infinite();
1151
1152 Geom2dAdaptor_Curve AdapBisector(Bisector);
1153 Geom2dAdaptor_Curve AdapLine1 (Line1);
1154 Intersect.Perform(AdapBisector, Domain1,
1155 AdapLine1, Tolerance, Tolerance);
1156
1157 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1158 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1159 gp_Pnt2d PInt = Intersect.Point(i).Value();
1160 Distance = FirstPointBisector.Distance(PInt);
1161 if (Distance > 10.*Tolerance &&
1162 Intersect.Point(i).ParamOnFirst() < UTrim ) {
1163 UTrim = Intersect.Point(i).ParamOnFirst();
1164 }
1165 }
1166 }
1167 // ------------------------------------------------------------------------
1168 // Restriction de la Bissectrice par le point d intersection de plus petit
1169 // parametre.
1170 // ------------------------------------------------------------------------
1171 if (UTrim < UB2 && UTrim > UB1) Bisector->SetTrim(UB1,UTrim);
1172}
1173
1174//==========================================================================
1175//function : Domain
1176//purpose :
1177//==========================================================================
1178IntRes2d_Domain Domain(const Handle(Geom2d_TrimmedCurve)& Bisector1,
1179 const Standard_Real Tolerance)
1180{
1181 Standard_Real Param1 = Bisector1->FirstParameter();
1182 Standard_Real Param2 = Bisector1->LastParameter();
1183 if(Param2 > 10000.) {
1184 Param2 = 10000.;
1185 Handle(Standard_Type) Type1 = Type(Bisector1->BasisCurve());
1186 Handle(Geom2d_Curve) BasisCurve;
1187 if (Type1 == STANDARD_TYPE(Bisector_BisecAna)) {
1188 BasisCurve = Handle(Bisector_BisecAna)
1189 ::DownCast(Bisector1->BasisCurve())->Geom2dCurve();
1190 Type1 = BasisCurve->DynamicType();
1191 }
1192 gp_Parab2d gpParabola;
1193 gp_Hypr2d gpHyperbola;
1194 Standard_Real Focus;
1195 Standard_Real Limit = 50000.;
1196 if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1197 gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1198 Focus = gpParabola.Focal();
1199 Standard_Real Val1 = Sqrt(Limit*Focus);
1200 Standard_Real Val2 = Sqrt(Limit*Limit);
1201 Param2 = (Val1 <= Val2 ? Val1:Val2);
1202 }
1203 else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1204 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1205 Standard_Real Majr = gpHyperbola.MajorRadius();
1206 Standard_Real Minr = gpHyperbola.MinorRadius();
1207 Standard_Real Valu1 = Limit/Majr;
1208 Standard_Real Valu2 = Limit/Minr;
1209 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
1210 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
1211 Param2 = (Val1 <= Val2 ? Val1:Val2);
1212 }
1213 }
1214
1215 IntRes2d_Domain Domain1(Bisector1->Value(Param1),Param1,Tolerance,
1216 Bisector1->Value(Param2),Param2,Tolerance);
1217 if(Bisector1->BasisCurve()->IsPeriodic()) {
c6541a0c 1218 Domain1.SetEquivalentParameters(0.,2.*M_PI);
7fd59977 1219 }
1220 return Domain1;
1221}
1222
1223#ifdef DEB
1224//==========================================================================
1225//function : MAT2d_DrawCurve
1226//purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
1227// definie par <Indice>.
1228// Indice = 1 jaune,
1229// Indice = 2 bleu,
1230// Indice = 3 rouge,
1231// Indice = 4 vert.
1232//==========================================================================
1233void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
35e08fe8 1234 const Standard_Integer /*Indice*/)
7fd59977 1235{
1236 Handle(Standard_Type) type = aCurve->DynamicType();
1237 Handle(Geom2d_Curve) curve,CurveDraw;
1238#ifdef DRAW
1239 Handle(DrawTrSurf_Curve2d) dr;
1240 Draw_Color Couleur;
1241#endif
1242
1243 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1244 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
1245 type = curve->DynamicType();
1246 // PB de representation des courbes semi_infinies.
1247 gp_Parab2d gpParabola;
1248 gp_Hypr2d gpHyperbola;
1249 Standard_Real Focus;
1250 Standard_Real Limit = 50000.;
1251 Standard_Real delta = 400;
1252
1253 // PB de representation des courbes semi_infinies.
1254 if (aCurve->LastParameter() == Precision::Infinite()) {
1255
1256 if (type == STANDARD_TYPE(Geom2d_Parabola)) {
1257 gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
1258 Focus = gpParabola.Focal();
1259 Standard_Real Val1 = Sqrt(Limit*Focus);
1260 Standard_Real Val2 = Sqrt(Limit*Limit);
1261 delta= (Val1 <= Val2 ? Val1:Val2);
1262 }
1263 else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1264 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
1265 Standard_Real Majr = gpHyperbola.MajorRadius();
1266 Standard_Real Minr = gpHyperbola.MinorRadius();
1267 Standard_Real Valu1 = Limit/Majr;
1268 Standard_Real Valu2 = Limit/Minr;
1269 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
1270 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
1271 delta = (Val1 <= Val2 ? Val1:Val2);
1272 }
1273 CurveDraw = new Geom2d_TrimmedCurve(aCurve,
1274 aCurve->FirstParameter(),
1275 aCurve->FirstParameter() + delta);
1276 }
1277 else {
1278 CurveDraw = aCurve;
1279 }
1280 // fin PB.
1281 }
1282 else {
1283 CurveDraw = aCurve;
1284 }
1285
1286#ifdef DRAW
1287 if (Indice == 1) Couleur = Draw_jaune;
1288 else if (Indice == 2) Couleur = Draw_bleu;
1289 else if (Indice == 3) Couleur = Draw_rouge;
1290 else if (Indice == 4) Couleur = Draw_vert;
1291
1292 if (type == STANDARD_TYPE(Geom2d_Circle))
1293 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
1294 else if (type == STANDARD_TYPE(Geom2d_Line))
1295 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
1296 else
1297 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
1298
1299 dout << dr;
1300 dout.Flush();
1301#endif
1302}
1303
1304#endif
1305