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