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