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