0025298: New option of BRepOffsetAPI_MakeOffset algorithm: processing of sharp corner...
[occt.git] / src / MAT2d / MAT2d_Circuit.cxx
CommitLineData
b311480e 1// Created on: 1993-11-19
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#ifdef DRAW
18#include <Draw_Appli.hxx>
19#include <DrawTrSurf_Curve2d.hxx>
20#include <Draw_Marker2D.hxx>
21#endif
22#ifdef DEB
23#include <GCE2d_MakeSegment.hxx>
24#include <Geom2d_Curve.hxx>
25#include <Geom2d_Parabola.hxx>
26#include <Geom2d_Hyperbola.hxx>
27#include <Geom2d_TrimmedCurve.hxx>
28#include <Geom2d_CartesianPoint.hxx>
29#include <Geom2d_Line.hxx>
30#include <Geom2d_Circle.hxx>
31#endif
32
33#include <MAT2d_Circuit.ixx>
34#include <Geom2d_TrimmedCurve.hxx>
35#include <Geom2d_CartesianPoint.hxx>
36#include <Geom2d_Geometry.hxx>
37#include <TColStd_SequenceOfInteger.hxx>
38#include <TColStd_Array1OfBoolean.hxx>
39#include <TColStd_Array1OfInteger.hxx>
40#include <MAT2d_BiInt.hxx>
41#include <MAT2d_MiniPath.hxx>
42#include <MAT2d_Connexion.hxx>
43#include <MAT2d_SequenceOfConnexion.hxx>
44#include <MAT2d_DataMapOfIntegerConnexion.hxx>
45#include <MAT2d_SequenceOfSequenceOfGeometry.hxx>
46#include <MAT2d_DataMapOfBiIntSequenceOfInteger.hxx>
47#include <MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger.hxx>
48#include <Precision.hxx>
49#include <Adaptor3d_OffsetCurve.hxx>
50#include <Geom2dInt_GInter.hxx>
51#include <Geom2dAdaptor_HCurve.hxx>
52#include <IntRes2d_IntersectionPoint.hxx>
53
54#ifdef DRAW
55 static Handle(DrawTrSurf_Curve2d) draw;
56 Standard_EXPORT Draw_Viewer dout;
57#endif
58#ifdef DEB
59 static void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
60 const Standard_Integer Indice);
61 static Standard_Boolean AffichCircuit = 0;
62#endif
63
64// static functions:
65
66static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
67 const Handle(Geom2d_Geometry)& Geom2,
68 Standard_Real& DotProd);
69
7fd59977 70
71//=============================================================================
72//function : Constructor
73//purpose :
74//=============================================================================
c19dd45e 75MAT2d_Circuit::MAT2d_Circuit(const GeomAbs_JoinType aJoinType,
76 const Standard_Boolean IsOpenResult)
7fd59977 77{
c19dd45e 78 myJoinType = aJoinType;
6a442250 79 myIsOpenResult = IsOpenResult;
7fd59977 80}
81
82//=============================================================================
83//function : Perform
84//purpose :
85//=============================================================================
86void MAT2d_Circuit::Perform
87 ( MAT2d_SequenceOfSequenceOfGeometry& FigItem,
88 const TColStd_SequenceOfBoolean & IsClosed,
89 const Standard_Integer IndRefLine,
90 const Standard_Boolean Trigo)
91{
92 Standard_Integer NbLines = FigItem.Length();
93 Standard_Integer i;
94 TColStd_Array1OfBoolean Open(1,NbLines);
95 MAT2d_SequenceOfConnexion SVide;
96 Handle(MAT2d_Connexion) ConnexionNul;
97
98 if (Trigo) direction = 1.; else direction = -1.;
99
100 //---------------------
101 // Reinitialisation SD.
102 //---------------------
103 geomElements.Clear();
104 connexionMap.Clear();
105 linkRefEqui.Clear();
106 linesLength.Clear();
107
108 //----------------------------
109 // Detection Lignes ouvertes.
110 //----------------------------
111 for ( i = 1; i <= NbLines; i++) {
857ffd5e 112 Handle(Geom2d_TrimmedCurve) Curve;
7fd59977 113 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).First());
114 gp_Pnt2d P1 = Curve->StartPoint();
115 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(FigItem.Value(i).Last());
116 gp_Pnt2d P2 = Curve->EndPoint();
117// Modified by Sergey KHROMOV - Wed Mar 6 16:59:01 2002 Begin
118// if ( P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
119// else Open(i) = Standard_True;
120 if (IsClosed(i)) Open(i) = Standard_False;
121 else if (P1.IsEqual(P2,Precision::Confusion())) Open(i) = Standard_False;
122 else Open(i) = Standard_True;
123// Modified by Sergey KHROMOV - Wed Mar 6 16:59:04 2002 End
124 }
125
126 //---------------------------------------------------------------
127 // Insertion des cassures saillantes ou
128 // ajout des extremites de chaque courbe si la ligne est ouverte.
129 //---------------------------------------------------------------
130 for ( i = 1; i <= NbLines; i++) {
131 if (Open(i)) {
132 InitOpen(FigItem.ChangeValue(i));
133 linesLength.Append(FigItem.Value(i).Length());
134 }
135 else {
136 InsertCorner(FigItem.ChangeValue(i));
137 linesLength.Append(FigItem.Value(i).Length());
138 }
139 }
140
141 //---------------------------------
142 // Une seule ligne => Rien a faire.
143 //---------------------------------
144 if (NbLines == 1) {
145 if (Open(1)) {
146 DoubleLine(FigItem.ChangeValue(1),SVide,ConnexionNul,direction);
147 linesLength.SetValue(1,FigItem.Value(1).Length());
148 }
149 geomElements = FigItem.Value(1);
150 UpDateLink(1,1,1,geomElements.Length());
151 linesLength.Append(FigItem.Value(1).Length());
152 return;
153 }
154
155 //------------------
156 // Plusieurs lignes.
157 //------------------
158
159 //---------------------------------------------------------
160 // Calcul de l ensemble des connexions realisant le chemin.
161 //---------------------------------------------------------
162 MAT2d_MiniPath Road;
163 Road.Perform(FigItem,IndRefLine,Trigo);
164
165 //------------------------
166 // Fermeture ligne ouverte.
167 //-------------------------
168 for ( i = 1; i <= NbLines; i++) {
169 if (Open(i)) {
170 Handle(MAT2d_Connexion) CF;
171 if (Road.IsRoot(i)) CF = ConnexionNul; else CF = Road.Father(i);
172 if (Road.IsConnexionsFrom(i)) {
173 DoubleLine(FigItem.ChangeValue(i),Road.ConnexionsFrom(i),
174 CF,direction);
175 }
176 else {
177 DoubleLine(FigItem.ChangeValue(i),SVide,CF,direction);
178 }
179 linesLength.SetValue(i,FigItem.Value(i).Length());
180 }
181 }
182
183 //------------------------
184 // Construction du chemin.
185 //------------------------
186 Road.RunOnConnexions();
187
188#ifdef DEB
189 if (AffichCircuit) {
190 Standard_Integer NbConnexions = Road.Path().Length();
191 for (i = 1; i <= NbConnexions; i++) {
192 Handle(Geom2d_TrimmedCurve) edge;
193 edge = GCE2d_MakeSegment(Road.Path().Value(i)->PointOnFirst(),
194 Road.Path().Value(i)->PointOnSecond());
195 MAT2d_DrawCurve(edge,2);
196 }
197 }
198#endif
199
200 //-------------------------
201 // Construction du Circuit.
202 //-------------------------
203 ConstructCircuit(FigItem,IndRefLine,Road);
204}
205
c19dd45e 206//=======================================================================
207//function : IsSharpCorner
208//purpose : Return True Si le point commun entre <Geom1> et <Geom2> est
209// une cassure saillante par rapport <Direction>
210//=======================================================================
211
212Standard_Boolean MAT2d_Circuit::IsSharpCorner(const Handle(Geom2d_Geometry)& Geom1,
213 const Handle(Geom2d_Geometry)& Geom2,
214 const Standard_Real Direction) const
215{
216 Standard_Real DotProd;
217 Standard_Real ProVec = CrossProd (Geom1,Geom2,DotProd);
218 Standard_Integer NbTest = 1;
219 Standard_Real DU = Precision::Confusion();
220 Handle(Geom2d_TrimmedCurve) C1,C2;
221
222 C1= Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
223 C2= Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
224// Modified by Sergey KHROMOV - Thu Oct 24 19:02:46 2002 Begin
225// Add the same criterion as it is in MAT2d_Circuit::InitOpen(..)
226// Standard_Real TolAng = 1.E-5;
227 Standard_Real TolAng = 1.E-8;
228// Modified by Sergey KHROMOV - Thu Oct 24 19:02:47 2002 End
229
230 if (myJoinType == GeomAbs_Arc)
231 {
232 while (NbTest <= 10) {
233 if ((ProVec)*Direction < -TolAng)
234 return Standard_True; // Saillant.
235 if ((ProVec)*Direction > TolAng)
236 return Standard_False; // Rentrant.
237 else {
238 if (DotProd > 0) {
239 return Standard_False; // Plat.
240 }
241 TolAng = 1.E-8;
242 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
243 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
244 gp_Dir2d Dir1(C1->DN(U1,1));
245 gp_Dir2d Dir2(C2->DN(U2,1));
246 DotProd = Dir1.Dot(Dir2);
247 ProVec = Dir1^Dir2;
248 NbTest++;
249 }
250 }
251
252
253
254 // Rebroussement.
255 // on calculde des paralleles aux deux courbes du cote du domaine
256 // de calcul
257 // Si pas dintersection => saillant.
258 // Sinon => rentrant.
259 Standard_Real D ;
260 Standard_Real Tol = Precision::Confusion();
261 Standard_Real MilC1 = (C1->LastParameter() + C1->FirstParameter())*0.5;
262 Standard_Real MilC2 = (C2->LastParameter() + C2->FirstParameter())*0.5;
263 gp_Pnt2d P = C1->Value(C1->LastParameter());
264 gp_Pnt2d P1 = C1->Value(MilC1);
265 gp_Pnt2d P2 = C2->Value(MilC2);
266
267 D = Min(P1.Distance(P),P2.Distance(P));
268 D /= 10;
269
270 if (Direction > 0.) D = -D;
271
272 Handle(Geom2dAdaptor_HCurve) HC1 = new Geom2dAdaptor_HCurve(C1);
273 Handle(Geom2dAdaptor_HCurve) HC2 = new Geom2dAdaptor_HCurve(C2);
274 Adaptor3d_OffsetCurve OC1(HC1,D,MilC1,C1->LastParameter());
275 Adaptor3d_OffsetCurve OC2(HC2,D,C2->FirstParameter(),MilC2);
276 Geom2dInt_GInter Intersect;
277 Intersect.Perform(OC1,OC2,Tol,Tol);
278
279#ifdef DEB
280 static Standard_Boolean Affich = 0;
281 if (Affich) {
282#ifdef DRAW
283 Standard_Real DU1 = (OC1.LastParameter() - OC1.FirstParameter())/9.;
284 Standard_Real DU2 = (OC2.LastParameter() - OC2.FirstParameter())/9.;
285 for (Standard_Integer ki = 0; ki <= 9; ki++) {
286 gp_Pnt2d P1 = OC1.Value(OC1.FirstParameter()+ki*DU1);
287 gp_Pnt2d P2 = OC2.Value(OC2.FirstParameter()+ki*DU2);
288 Handle(Draw_Marker2D) dr1 = new Draw_Marker2D(P1,Draw_Plus,Draw_vert);
289 Handle(Draw_Marker2D) dr2 = new Draw_Marker2D(P2,Draw_Plus,Draw_rouge);
290 dout << dr1;
291 dout << dr2;
292 }
293 dout.Flush();
294#endif
295 }
296#endif
297
298 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
299 return Standard_False;
300 }
301 else {
302 return Standard_True;
303 }
304 } //end of if (myJoinType == GeomAbs_Arc)
305 else if (myJoinType == GeomAbs_Intersection)
306 {
307 if (Abs(ProVec) <= TolAng &&
308 DotProd < 0)
309 {
310 while (NbTest <= 10)
311 {
312 Standard_Real U1 = C1->LastParameter() - NbTest*DU;
313 Standard_Real U2 = C2->FirstParameter() + NbTest*DU;
314 gp_Dir2d Dir1(C1->DN(U1,1));
315 gp_Dir2d Dir2(C2->DN(U2,1));
316 DotProd = Dir1.Dot(Dir2);
317 ProVec = Dir1^Dir2;
318 if ((ProVec)*Direction < -TolAng)
319 return Standard_True; // Saillant.
320 if ((ProVec)*Direction > TolAng)
321 return Standard_False; // Rentrant.
322
323 NbTest++;
324 }
325 return Standard_False;
326 }
327 else
328 return Standard_False;
329 }
330 return Standard_False;
331}
332
7fd59977 333//=======================================================================
334//function : SubSequence
335//purpose :
336//=======================================================================
337static void SubSequence(const TColGeom2d_SequenceOfGeometry& S1,
338 Standard_Integer IF,
339 Standard_Integer IL,
340 TColGeom2d_SequenceOfGeometry& S2)
341{
342 S2.Clear();
343 for (Standard_Integer i = IF; i<= IL; i++){
344 S2.Append(S1.Value(i));
345 }
346}
347
348
349//=============================================================================
350//function : ConstructCircuit
351//purpose :
352//=============================================================================
353void MAT2d_Circuit::ConstructCircuit
354 (const MAT2d_SequenceOfSequenceOfGeometry& FigItem,
355 const Standard_Integer IndRefLine,
356 const MAT2d_MiniPath& Road)
357{
358 Handle(MAT2d_Connexion) PrevC,CurC;
359 TColGeom2d_SequenceOfGeometry SetOfItem;
360 Standard_Integer NbConnexions;
361 Standard_Integer ILastItem;
362 Standard_Integer IndLast;
363 Standard_Integer i;
364
365 NbConnexions = Road.Path().Length();
366 //-----------------------------------------------------
367 // Depart du premier element de la ligne de reference.
368 //-----------------------------------------------------
369 PrevC = Road.Path().Value(1);
370 SubSequence(FigItem.Value(IndRefLine),
371 1,
372 PrevC->IndexItemOnFirst(),
373 geomElements);
374 UpDateLink(1,IndRefLine,1,PrevC->IndexItemOnFirst());
375 connexionMap.Bind(geomElements.Length()+1,PrevC);
376 ILastItem = geomElements.Length();
377
378 //-----------------------------------------------------------------------
379 // Ajout des portion de lignes delimites par deux connexions successives.
380 //-----------------------------------------------------------------------
381 for ( i = 2; i <= NbConnexions; i++) {
382 CurC = Road.Path().Value(i);
383 if (PassByLast(PrevC,CurC)) {
384 //------------------------------------------------------
385 // La portion passe par le dernier element de la ligne.
386 // - ajout de la portion de PrevC au dernier element
387 // de la ligne.
388 // - Si la ligne contient plus d'un element ajout de la
389 // portion du premier element de la ligne a CurC.
390 //------------------------------------------------------
391 IndLast = FigItem.Value(CurC->IndexFirstLine()).Length();
392 SubSequence (FigItem.Value(CurC->IndexFirstLine()),
393 PrevC->IndexItemOnSecond(),
394 IndLast,
395 SetOfItem);
396 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
397 PrevC->IndexItemOnSecond(),IndLast);
398 geomElements.Append(SetOfItem);
399 ILastItem = geomElements.Length();
400
401 if (FigItem.Value(CurC->IndexFirstLine()).Length() > 1) {
402 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
403 1,
404 CurC->IndexItemOnFirst(),
405 SetOfItem);
406 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
407 1,CurC->IndexItemOnFirst());
408 geomElements.Append(SetOfItem);
409 ILastItem = geomElements.Length();
410 }
411 connexionMap.Bind(ILastItem+1,CurC);
412 }
413 else{
414
415 //------------------------------------------------------
416 // La portion ne passe par le dernier element de la ligne.
417 //------------------------------------------------------
418 SubSequence(FigItem.Value(CurC->IndexFirstLine()),
419 PrevC->IndexItemOnSecond(),
420 CurC ->IndexItemOnFirst(),
421 SetOfItem);
422 UpDateLink(ILastItem+1,CurC->IndexFirstLine(),
423 PrevC->IndexItemOnSecond(),CurC->IndexItemOnFirst());
424 geomElements.Append(SetOfItem);
425 ILastItem = geomElements.Length();
426 connexionMap.Bind(ILastItem+1,CurC);
427 }
428 PrevC = CurC;
429 }
430
431 //-------------------------------------------------------------
432 // Fermeture : de la derniere connexion au dernier element de la
433 // ligne de reference.
434 //-------------------------------------------------------------
435 IndLast = FigItem.Value(IndRefLine).Length();
436 if (IndLast == 1) {
437 connexionMap.Bind(1,CurC);
438 connexionMap.UnBind(ILastItem+1);
439 }
440 else {
441 SubSequence(FigItem.Value(IndRefLine),
442 PrevC->IndexItemOnSecond(),
443 IndLast,
444 SetOfItem);
445 UpDateLink(ILastItem+1,IndRefLine,PrevC->IndexItemOnSecond(),IndLast);
446 geomElements.Append(SetOfItem);
447 ILastItem = geomElements.Length();
448 }
449
450 //--------------------------------------
451 // Tri des RefToEqui pour chaque element.
452 //--------------------------------------
453 MAT2d_DataMapIteratorOfDataMapOfBiIntSequenceOfInteger Ite;
454
455 for ( Ite.Initialize(linkRefEqui); Ite.More(); Ite.Next()) {
456 if (Ite.Value().Length() > 1) {
457 SortRefToEqui(Ite.Key());
458 }
459 }
460
461#ifdef DEB
462 if (AffichCircuit) {
463 ILastItem = geomElements.Length();
464 for (i = 1; i <= ILastItem; i++) {
465 if (geomElements.Value(i)->DynamicType() != STANDARD_TYPE(Geom2d_CartesianPoint) ){
466 MAT2d_DrawCurve
467 (Handle(Geom2d_Curve)::DownCast(geomElements.Value(i)),2);
468 }
469 }
470 }
471#endif
472}
473
474//=============================================================================
475//function : InitOpen
476//purpose :
477//=============================================================================
478void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
479{
480 Handle(Geom2d_TrimmedCurve) Curve;
481 Standard_Real DotProd;
7fd59977 482
6a442250 483 if (!myIsOpenResult)
484 {
485 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
486 Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
487 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
488 Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
489 }
490
491 Standard_Integer addition = (myIsOpenResult)? 1 : 2;
492 for ( Standard_Integer i = addition; i <= Line.Length() - addition; i++) {
7fd59977 493 if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
494 DotProd < 0. ) {
495 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
496 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->EndPoint()));
497 i++;
498 }
499 }
500}
501
502//=============================================================================
503//function : DoubleLine
504//purpose :
505//=============================================================================
506void MAT2d_Circuit::DoubleLine
507 ( TColGeom2d_SequenceOfGeometry& Line,
508 MAT2d_SequenceOfConnexion& ConnexionFrom,
509 const Handle(MAT2d_Connexion)& ConnexionFather,
510 const Standard_Real SideRef)
511const
512{
513 Handle(Standard_Type) Type;
514 Handle(Geom2d_TrimmedCurve) Curve;
515 Standard_Integer NbItems = Line.Length();
516 Standard_Integer i;
517 Standard_Real ProVec,DotProd;
518 Handle(MAT2d_Connexion) CC;
519
520 //--------------------------
521 // Completion de la ligne.
522 //--------------------------
6a442250 523 if (!myIsOpenResult)
524 {
525 for ( i = NbItems - 1; i > 1; i--){
526 Type = Line.Value(i)->DynamicType();
527 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
528 Line.Append(Line.Value(i));
529 }
530 else {
531 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i)->Copy());
532 Curve->Reverse();
533 Line.Append(Curve);
534 }
7fd59977 535 }
536 }
537
538 //------------------------------------------
539 // Repartition des connexions sur la ligne
540 //------------------------------------------
541 Standard_Integer IAfter = ConnexionFrom.Length();
542 Standard_Integer NbConnexions = IAfter;
543 Standard_Integer IndCOF;
544
545 for (i = 1; i <= IAfter; i++) {
546 CC = ConnexionFrom.Value(i);
547 IndCOF = CC->IndexItemOnFirst();
548 Type = Line.Value(IndCOF)->DynamicType();
549
550 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
551 if (IndCOF!= NbItems && IndCOF!= 1) {
552 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
553 if ((ProVec)*SideRef > 0){
554 CC->IndexItemOnFirst(2*NbItems - IndCOF);
555 ConnexionFrom.InsertAfter(IAfter,CC);
556 ConnexionFrom.Remove(i);
557 IAfter--;
558 i--;
559 }
560 }
561 }
562 else if (Side(CC,Line) != SideRef){
563 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
564 CC->IndexItemOnFirst(2*NbItems - IndCOF);
565 CC->ParameterOnFirst(Curve->ReversedParameter(CC->ParameterOnFirst()));
566 ConnexionFrom.InsertAfter(IAfter,CC);
567 ConnexionFrom.Remove(i);
568 IAfter--;
569 i--;
570 }
571 }
572
573 //---------------------------
574 // Mise a jour connexion pere.
575 //---------------------------
576 if (!ConnexionFather.IsNull()) {
577 CC = ConnexionFather->Reverse();
578 IndCOF = CC->IndexItemOnFirst();
579 Type = Line.Value(IndCOF)->DynamicType();
580
581 if ( Type == STANDARD_TYPE(Geom2d_CartesianPoint) ){
582 if (IndCOF != NbItems && IndCOF != 1) {
583 ProVec = CrossProd(Line.Value(IndCOF - 1),Line.Value(IndCOF + 1),DotProd);
584 if ((ProVec)*SideRef > 0){
585 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
586 }
587 }
588 }
589 else if (Side(CC,Line) != SideRef){
590 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(IndCOF));
591 ConnexionFather->IndexItemOnSecond(2*NbItems - IndCOF);
592 ConnexionFather->ParameterOnSecond
593 (Curve->ReversedParameter(ConnexionFather->ParameterOnSecond()));
594 }
595 }
596
597 //-------------------------------------
598 // Suppression des cassures rentrantes.
599 //-------------------------------------
600 Standard_Integer IndLine = 1;
601 Standard_Integer ICorres = 1;
602 TColStd_Array1OfInteger Corres(1,Line.Length());
603
604 while (Line.Value(IndLine) != Line.Last()){
605 Corres(ICorres) = IndLine;
606 Type = Line.Value(IndLine)->DynamicType();
607
608 if (Type == STANDARD_TYPE(Geom2d_CartesianPoint) &&
609 ICorres != 1 && ICorres != NbItems) {
610
611 if (!IsSharpCorner(Line.Value(IndLine - 1),
612 Line.Value(IndLine + 1),SideRef)){
613 Line.Remove(IndLine);
614 IndLine--;
615 Corres(ICorres) =0;
616 }
617 }
618 IndLine++;
619 ICorres++;
620 }
621 Corres(ICorres) = IndLine;
7fd59977 622
6a442250 623 if (!myIsOpenResult)
624 {
625 for (i = 1; i < 2*NbItems - 2; i++) {
626 if (Corres(i) == 0)
627 Corres(i) = Corres(2*NbItems - i);
628 }
629
7fd59977 630#ifdef DEB
6a442250 631 if (AffichCircuit) {
632 for (i = 1; i <= 2*NbItems - 2; i++) {
633 cout<< "Correspondance "<< i<<" -> "<<Corres(i)<<endl;
634 }
7fd59977 635 }
7fd59977 636#endif
6a442250 637
638 //----------------------------
639 // Mise a jour des Connexions.
640 //----------------------------
641 for ( i = 1; i <= NbConnexions; i++){
642 CC = ConnexionFrom.ChangeValue(i);
643 CC->IndexItemOnFirst(Corres(CC->IndexItemOnFirst()));
644 }
645
646 if (!ConnexionFather.IsNull()) {
647 ConnexionFather
648 ->IndexItemOnSecond(Corres(ConnexionFather->IndexItemOnSecond()));
649 }
7fd59977 650 }
651}
652
653
654//=============================================================================
655//function : InsertCorner
656//purpose :
657//=============================================================================
658void MAT2d_Circuit::InsertCorner (TColGeom2d_SequenceOfGeometry& Line) const
659{
660 Standard_Integer i,isuiv;
661 Handle(Geom2d_TrimmedCurve) Curve;
662 Standard_Boolean Insert;
663
664 for ( i = 1; i <= Line.Length(); i++) {
665 isuiv = (i == Line.Length()) ? 1 : i + 1;
666 Insert = IsSharpCorner(Line.Value(i),Line.Value(isuiv),direction);
667
668#ifdef DEB
669 if (AffichCircuit) {
670 if (Insert) {
671 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
7fd59977 672#ifdef DRAW
96a95605 673 gp_Pnt2d P = Curve->StartPoint();
7fd59977 674 Handle(Draw_Marker2D) dr = new Draw_Marker2D(P,Draw_Plus,Draw_vert);
675 dout << dr;
676 dout.Flush();
677#endif
678 }
679 }
680#endif
681
682 if (Insert) {
683 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(isuiv));
684 Line.InsertAfter(i,new Geom2d_CartesianPoint(Curve->StartPoint()));
685 i++;
686 }
687 }
688}
689
690//=============================================================================
691//function : NumberOfItem
692//purpose :
693//=============================================================================
694Standard_Integer MAT2d_Circuit::NumberOfItems()const
695{
696 return geomElements.Length();
697}
698
699//=============================================================================
700//function : LineLength
701//purpose :
702//=============================================================================
703Standard_Integer MAT2d_Circuit::LineLength(const Standard_Integer I) const
704{
705 return linesLength(I);
706}
707
708//=============================================================================
709//function : Value
710//purpose :
711//=============================================================================
712Handle(Geom2d_Geometry) MAT2d_Circuit::Value
713 (const Standard_Integer Index)const
714{
715 return geomElements.Value(Index);
716}
717
718//=============================================================================
719//function : RefToEqui
720//purpose :
721//=============================================================================
722const TColStd_SequenceOfInteger& MAT2d_Circuit::RefToEqui
723 (const Standard_Integer IndLine,
724 const Standard_Integer IndCurve) const
725{
726 MAT2d_BiInt Key(IndLine,IndCurve);
727 return linkRefEqui(Key);
728}
729
730//=============================================================================
731//function : SortRefToEqui
732//purpose :
733//=============================================================================
734void MAT2d_Circuit::SortRefToEqui (const MAT2d_BiInt& BiRef)
735{
736 Standard_Integer i;
737 TColStd_SequenceOfInteger& S = linkRefEqui.ChangeFind(BiRef);
738 TColStd_SequenceOfInteger SFin;
739
740 for( i = 1; i <= S.Length(); i++){
741 if (!ConnexionOn(S.Value(i))) break;
742 }
743 if ( i > 1 && i <= S.Length()) {
744 SFin = S;
745 SFin.Split(i,S);
746 S.Append(SFin);
747 }
748}
749
750//=============================================================================
751//function : Connexion
752//purpose :
753//=============================================================================
754Handle(MAT2d_Connexion) MAT2d_Circuit::Connexion(const Standard_Integer I)const
755{
756 return connexionMap(I);
757}
758
759//=============================================================================
760//function : ConnexionOn
761//purpose :
762//=============================================================================
763Standard_Boolean MAT2d_Circuit::ConnexionOn(const Standard_Integer I)const
764{
765 return connexionMap.IsBound(I);
766}
767
768//=============================================================================
769//function : Side
770//purpose :
771//=============================================================================
772Standard_Real MAT2d_Circuit::Side
773 (const Handle(MAT2d_Connexion)& C1,
774 const TColGeom2d_SequenceOfGeometry& Line)
775const
776{
777 Handle(Geom2d_TrimmedCurve) Curve;
778
779 gp_Vec2d Vect1(C1->PointOnSecond().X() - C1->PointOnFirst().X(),
780 C1->PointOnSecond().Y() - C1->PointOnFirst().Y());
781 Curve = Handle(Geom2d_TrimmedCurve)::DownCast
782 (Line.Value(C1->IndexItemOnFirst()));
783 gp_Vec2d Vect2 = Curve->DN(C1->ParameterOnFirst(),1);
784 if ( (Vect1^Vect2) > 0.) return - 1.; else return 1.;
785}
786
787//=============================================================================
788//function : PassByLast
789//purpose :
790//=============================================================================
791Standard_Boolean MAT2d_Circuit::PassByLast
792 (const Handle(MAT2d_Connexion)& C1,
793 const Handle(MAT2d_Connexion)& C2) const
794{
795 if (C2->IndexFirstLine() == C1->IndexSecondLine()){
796 if (C2->IndexItemOnFirst() < C1->IndexItemOnSecond()) {
797 return Standard_True;
798 }
799 else if (C2->IndexItemOnFirst() == C1->IndexItemOnSecond()) {
800 if (C1->IndexFirstLine() == C2->IndexSecondLine()) {
801 return Standard_True;
802 }
803 if (C2->ParameterOnFirst() == C1->ParameterOnSecond()) {
804 gp_Vec2d Vect1(C1->PointOnSecond(),C1->PointOnFirst());
805 gp_Vec2d Vect2(C2->PointOnFirst(),C2->PointOnSecond());
806 if ((Vect1^Vect2)*direction > 0) {
807 return Standard_True;
808 }
809 }
810 else if (C2->ParameterOnFirst() < C1->ParameterOnSecond()) {
811 return Standard_True;
812 }
813 }
814 }
815 return Standard_False;
816}
817
818//=============================================================================
819//function : UpDateLink
820//purpose :
821//=============================================================================
822void MAT2d_Circuit::UpDateLink(const Standard_Integer IFirst,
823 const Standard_Integer ILine,
824 const Standard_Integer ICurveFirst,
825 const Standard_Integer ICurveLast)
826{
827 Standard_Integer IEqui = IFirst;
828 Standard_Integer i;
829
830 for (i = ICurveFirst; i <= ICurveLast; i++) {
831 MAT2d_BiInt Key(ILine,i);
832 if (linkRefEqui.IsBound(Key)) {
833 linkRefEqui(Key).Append(IEqui);
834 }
835 else {
836 TColStd_SequenceOfInteger L;
837 linkRefEqui.Bind(Key,L);
838 linkRefEqui(Key).Append(IEqui);
839 }
840 IEqui++;
841 }
842}
843
844//==========================================================================
845//function : CrossProd
846//purpose : Calcul le produit vectoriel et scalaire entre les directions des
847// tangentes a la fin de Geom1 et au debut de Geom2.
848// Geom1 et Geom2 doivent etre des courbes.
849//==========================================================================
850static Standard_Real CrossProd(const Handle(Geom2d_Geometry)& Geom1,
851 const Handle(Geom2d_Geometry)& Geom2,
852 Standard_Real& DotProd)
853{
854 Handle(Geom2d_TrimmedCurve) Curve;
855
856 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom1);
857 gp_Dir2d Dir1(Curve->DN(Curve->LastParameter(),1));
858 Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Geom2);
859 gp_Dir2d Dir2(Curve->DN(Curve->FirstParameter(),1));
860 DotProd = Dir1.Dot(Dir2);
861 return Dir1^Dir2;
862}
863
864
7fd59977 865
866
867
868#ifdef DEB
869//==========================================================================
870//function : MAT2d_DrawCurve
871//purpose : Affichage d une courbe <aCurve> de Geom2d. dans une couleur
872// definie par <Indice>.
873// Indice = 1 jaune,
874// Indice = 2 bleu,
875// Indice = 3 rouge,
876// Indice = 4 vert.
877//==========================================================================
878void MAT2d_DrawCurve(const Handle(Geom2d_Curve)& aCurve,
35e08fe8 879 const Standard_Integer /*Indice*/)
7fd59977 880{
881 Handle(Standard_Type) type = aCurve->DynamicType();
882 Handle(Geom2d_Curve) curve,CurveDraw;
883#ifdef DRAW
884 Handle(DrawTrSurf_Curve2d) dr;
885 Draw_Color Couleur;
886#endif
887
888 if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
889 curve = Handle(Geom2d_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
890 type = curve->DynamicType();
891 // PB de representation des courbes semi_infinies.
892 gp_Parab2d gpParabola;
893 gp_Hypr2d gpHyperbola;
894 Standard_Real Focus;
895 Standard_Real Limit = 50000.;
896 Standard_Real delta = 400;
897
898 // PB de representation des courbes semi_infinies.
899 if (aCurve->LastParameter() == Precision::Infinite()) {
900
901 if (type == STANDARD_TYPE(Geom2d_Parabola)) {
902 gpParabola = Handle(Geom2d_Parabola)::DownCast(curve)->Parab2d();
903 Focus = gpParabola.Focal();
904 Standard_Real Val1 = Sqrt(Limit*Focus);
905 Standard_Real Val2 = Sqrt(Limit*Limit);
906 delta= (Val1 <= Val2 ? Val1:Val2);
907 }
908 else if (type == STANDARD_TYPE(Geom2d_Hyperbola)) {
909 gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(curve)->Hypr2d();
910 Standard_Real Majr = gpHyperbola.MajorRadius();
911 Standard_Real Minr = gpHyperbola.MinorRadius();
912 Standard_Real Valu1 = Limit/Majr;
913 Standard_Real Valu2 = Limit/Minr;
914 Standard_Real Val1 = Log(Valu1+Sqrt(Valu1*Valu1-1));
915 Standard_Real Val2 = Log(Valu2+Sqrt(Valu2*Valu2+1));
916 delta = (Val1 <= Val2 ? Val1:Val2);
917 }
918 CurveDraw = new Geom2d_TrimmedCurve(aCurve,
919 aCurve->FirstParameter(),
920 aCurve->FirstParameter() + delta);
921 }
922 else {
923 CurveDraw = aCurve;
924 }
925 // fin PB.
926 }
927 else {
928 CurveDraw = aCurve;
929 }
930
931#ifdef DRAW
932 if (Indice == 1) Couleur = Draw_jaune;
933 else if (Indice == 2) Couleur = Draw_bleu;
934 else if (Indice == 3) Couleur = Draw_rouge;
935 else if (Indice == 4) Couleur = Draw_vert;
936
937 if (type == STANDARD_TYPE(Geom2d_Circle))
938 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,30);
939 else if (type == STANDARD_TYPE(Geom2d_Line))
940 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,2);
941 else
942 dr = new DrawTrSurf_Curve2d(CurveDraw,Couleur,500);
943
944 dout << dr;
945 dout.Flush();
946#endif
947}
948
949#endif
950