0023317: Using the iteration variable in the inner and outer loop in GGraphic2d_SetOf...
[occt.git] / src / GGraphic2d / GGraphic2d_SetOfCurves.cxx
1 // Copyright (c) 1999-2012 OPEN CASCADE SAS
2 //
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
7 //
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10 //
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
17
18 #include <GGraphic2d_SetOfCurves.ixx>
19 #include <BndLib_Add2dCurve.hxx>
20 #include <Bnd_Box2d.hxx>
21 #include <Geom2dAdaptor_Curve.hxx>
22 #include <TColgp_Array1OfPnt2d.hxx>
23 #include <Geom2d_BezierCurve.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <Geom2d_Line.hxx>
26 #include <Geom2d_Circle.hxx>
27 #include <Geom2d_Ellipse.hxx>
28 #include <Geom2d_Parabola.hxx>
29 #include <Geom2d_Hyperbola.hxx>
30 #include <Geom2d_TrimmedCurve.hxx>
31 #include <Geom2d_OffsetCurve.hxx>
32 #include <GCPnts_UniformDeflection.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <gp_Dir2d.hxx>
35 #include <gp_Circ2d.hxx>
36 #include <gp_Elips2d.hxx>
37 #include <gp_Parab2d.hxx>
38 #include <gp_Hypr2d.hxx>
39
40 #include <gp_Pnt.hxx>
41 #include <TShort_Array1OfShortReal.hxx>
42 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
43 #include <Standard_ErrorHandler.hxx>
44
45 #define G002
46 #define VERTEXMARKER 2
47 #define DEFAULTMARKERSIZE 3.0
48
49 GGraphic2d_SetOfCurves::GGraphic2d_SetOfCurves (
50         const Handle(Graphic2d_GraphicObject)& aGraphicObject)
51
52   : Graphic2d_Line (aGraphicObject) {
53
54 }
55
56 void GGraphic2d_SetOfCurves::Add (const Handle(Geom2d_Curve) &aCurve)
57 {
58         Bnd_Box2d Box;
59         BndLib_Add2dCurve::Add(Geom2dAdaptor_Curve(aCurve),0.,Box);
60         Standard_Real Xmin, Ymin, Xmax, Ymax;
61         Box.Get( Xmin, Ymin, Xmax, Ymax);
62         Standard_ShortReal minX = Standard_ShortReal(Xmin);
63         Standard_ShortReal minY = Standard_ShortReal(Ymin);
64         Standard_ShortReal maxX = Standard_ShortReal(Xmax);
65         Standard_ShortReal maxY = Standard_ShortReal(Ymax);
66         myMinX  = Min(myMinX,minX);
67         myMinY  = Min(myMinY,minY);
68         myMaxX  = Max(myMaxX,maxX);
69         myMaxY  = Max(myMaxY,maxY);
70
71         myCurves.Append(aCurve);
72 }
73
74 Standard_Integer GGraphic2d_SetOfCurves::Length () const {
75    return myCurves.Length();
76 }
77
78 Handle(Geom2d_Curve) GGraphic2d_SetOfCurves::Values(const Standard_Integer aRank) const {
79
80         if( aRank < 1 || aRank > myCurves.Length() ) 
81                 Standard_OutOfRange::Raise
82                         ("the curve rank is out of bounds in the set");
83
84         return myCurves.Value(aRank);
85 }
86
87 void GGraphic2d_SetOfCurves::Draw (const Handle(Graphic2d_Drawer)& aDrawer) {
88 //Standard_Integer i,length = myCurves.Length(),bufferize = 1;
89  Standard_Integer length = myCurves.Length(), bufferize = 1;
90  Standard_Boolean IsIn = Standard_False;
91  Standard_ShortReal minX,minY,maxX,maxY;
92  Standard_Real Xmin,Ymin,Xmax,Ymax;
93
94  if( length <= 0 ) return ;
95
96  gp_GTrsf2d aTrsf = myGOPtr->Transform ();
97  
98   if (! myGOPtr->IsTransformed ())
99     IsIn = aDrawer->IsIn (myMinX,myMaxX,myMinY,myMaxY);
100   else {
101     MinMax(minX,maxX,minY,maxY);
102     IsIn = aDrawer->IsIn (minX,maxX,minY,maxY);
103   }
104
105   if ( IsIn ) {
106     Standard_ShortReal Def;
107     Standard_ShortReal Coeff;
108     Aspect_TypeOfDeflection Type;
109     Standard_Boolean Controll = Standard_True;
110     Handle(Geom2d_Curve) aCurve;
111     Standard_Integer i,typeindex = TypeIndex();
112
113     aDrawer->DrawPrecision(Def,Coeff,Type);
114     DrawLineAttrib(aDrawer);
115     for( i=1 ; i<=length ; i++ ) {
116       aCurve = myCurves.Value(i);
117
118       if (Type == Aspect_TOD_RELATIVE) {
119         Bnd_Box2d Box;
120         BndLib_Add2dCurve::Add(Geom2dAdaptor_Curve(aCurve),0.,Box);
121         Box.Get( Xmin,Ymin,Xmax,Ymax );
122         Def = Standard_ShortReal( (Abs(Xmax-Xmin) + Abs(Ymax-Ymin) ) * Coeff);
123       }
124
125       Geom2dAdaptor_Curve GAC(aCurve);
126       GCPnts_UniformDeflection UD(GAC,Def,Controll);
127       if(UD.IsDone()) {
128         Standard_Integer j,nbp = UD.NbPoints();
129         gp_Pnt p2;
130         Standard_Real x,y,z;
131         Standard_ShortReal x1=0,y1=0,x2,y2;
132         for (j=1; j<=nbp; j++) {
133           p2 = UD.Value(j);
134           p2.Coord(x,y,z);
135           if (myGOPtr->IsTransformed ()) {
136             aTrsf.Transforms(x, y);
137           }
138           if( typeindex > 0 ) {
139             if( j > 1 ) {
140               if( j < nbp ) bufferize = 0;
141               else          bufferize = -1;
142             } else {
143               bufferize = nbp;
144             }
145           aDrawer->MapPolylineFromTo( Standard_ShortReal(x), Standard_ShortReal(y), bufferize);
146           } else {
147             if( j > 1 ) {
148               if( (i == length) && (j == nbp) ) bufferize = -1;
149               x2 = Standard_ShortReal(x); y2 = Standard_ShortReal(y);
150           aDrawer->MapSegmentFromTo(x1,y1,x2,y2,bufferize);
151               x1 = x2; y1 = y2;
152               bufferize = 0; 
153             } else {
154               x1 = Standard_ShortReal(x); y1 = Standard_ShortReal(y);
155             }
156           }
157         }
158       }
159     }
160   }
161 }
162
163 #ifdef G002
164
165 void GGraphic2d_SetOfCurves::DrawElement( const Handle(Graphic2d_Drawer)& aDrawer,
166                                           const Standard_Integer anIndex ) {
167
168  Standard_Integer length = myCurves.Length(), bufferize = 1;
169  Standard_Boolean IsIn = Standard_False;
170  Standard_ShortReal minX,minY,maxX,maxY;
171  Standard_Real Xmin,Ymin,Xmax,Ymax;
172
173  if ( length <= 0 ) return ;
174
175  gp_GTrsf2d aTrsf = myGOPtr->Transform ();
176  
177  if ( ! myGOPtr->IsTransformed() )
178     IsIn = aDrawer->IsIn( myMinX,myMaxX,myMinY,myMaxY );
179  else {
180     MinMax(minX,maxX,minY,maxY);
181     IsIn = aDrawer->IsIn (minX,maxX,minY,maxY);
182   }
183
184   if ( IsIn ) {
185
186    if ( anIndex > 0 && anIndex <= length ) { 
187
188     Standard_ShortReal Def, Coeff;
189     Aspect_TypeOfDeflection Type;
190     Standard_Boolean Controll = Standard_True;
191     Handle(Geom2d_Curve) aCurve;
192     Standard_Integer typeindex = TypeIndex();
193
194     aDrawer->DrawPrecision( Def, Coeff, Type );
195     DrawLineAttrib( aDrawer );
196     aCurve = myCurves.Value( anIndex );
197
198     if ( Type == Aspect_TOD_RELATIVE ) {
199       Bnd_Box2d Box;
200       BndLib_Add2dCurve::Add(Geom2dAdaptor_Curve(aCurve),0.,Box);
201       Box.Get( Xmin,Ymin,Xmax,Ymax  );
202       Def = Standard_ShortReal( (Abs(Xmax-Xmin) + Abs(Ymax-Ymin) ) * Coeff);
203     }
204
205     Geom2dAdaptor_Curve GAC(aCurve);
206     GCPnts_UniformDeflection UD(GAC,Def,Controll);
207     if ( UD.IsDone() ) {
208       Standard_Integer j,nbp = UD.NbPoints();
209       gp_Pnt p2;
210       Standard_Real x,y,z;
211       Standard_ShortReal x1=0,y1=0,x2,y2;
212       for ( j = 1; j <= nbp; j++ ) {
213           p2 = UD.Value( j );
214           p2.Coord( x, y, z );
215           if ( myGOPtr->IsTransformed() ) {
216             aTrsf.Transforms (x, y);
217           }
218               if ( typeindex > 0 ) {
219                 if ( j > 1 ) {
220               bufferize = ( j < nbp ) ? 0 : -1;
221             } else {
222                    bufferize = nbp;
223             }
224             aDrawer->MapPolylineFromTo( Standard_ShortReal(x), Standard_ShortReal(y), bufferize );
225           } else {
226                 if ( j > 1 ) {
227                  if ( ( anIndex == length ) && (j == nbp) ) 
228                  bufferize = -1;
229                  x2 = Standard_ShortReal(x); y2 = Standard_ShortReal(y);
230              aDrawer->MapSegmentFromTo( x1, y1, x2, y2, bufferize );
231                  x1 = x2; y1 = y2;
232                  bufferize = 0; 
233             } else {
234                  x1 = Standard_ShortReal(x); y1 = Standard_ShortReal(y);
235             }
236           }
237       } // end for
238     }
239   }
240  
241  } // end if IsIn
242 }
243
244 void GGraphic2d_SetOfCurves::DrawVertex( const Handle(Graphic2d_Drawer)& aDrawer,
245                                          const Standard_Integer anIndex ) {
246
247  Standard_Integer length = myCurves.Length();
248  Standard_Boolean IsIn = Standard_False;
249  Standard_ShortReal minX,minY,maxX,maxY;
250
251  if ( length <= 0 ) return ;
252
253  if ( ! myGOPtr->IsTransformed() )
254     IsIn = aDrawer->IsIn( myMinX,myMaxX,myMinY,myMaxY );
255  else {
256     MinMax(minX,maxX,minY,maxY);
257     IsIn = aDrawer->IsIn (minX,maxX,minY,maxY);
258   }
259
260   if ( IsIn ) {
261
262    if ( anIndex > 0 && anIndex <= 2*length ) { 
263       
264       DrawMarkerAttrib (aDrawer);
265       Handle(Geom2d_Curve) aCurve; 
266       Standard_Real theParam; 
267       if ( anIndex <= length ) { 
268        aCurve = myCurves.Value( anIndex );
269        theParam = aCurve->FirstParameter();
270       } else {
271        aCurve = myCurves.Value( anIndex - length);
272        theParam = aCurve->LastParameter();
273       }
274       gp_Pnt2d thePnt = aCurve->Value(theParam);
275       Standard_ShortReal a = Standard_ShortReal(thePnt.X()),
276                          b = Standard_ShortReal(thePnt.Y());
277       if ( myGOPtr->IsTransformed() ) {
278         gp_GTrsf2d aTrsf = myGOPtr->Transform ();
279         Standard_Real a1, b1;
280         a1 = Standard_Real(a);
281         b1 = Standard_Real(b);
282         aTrsf.Transforms( a1, b1 );
283         a = Standard_ShortReal( a1 );
284         b = Standard_ShortReal( b1 );
285       } 
286       aDrawer->MapMarkerFromTo( VERTEXMARKER, a, b,
287                         DEFAULTMARKERSIZE,DEFAULTMARKERSIZE,0.0);
288    } 
289   } // end if IsIn
290 }
291
292 #endif
293
294 Standard_Boolean GGraphic2d_SetOfCurves::Pick( 
295                       const Standard_ShortReal X,
296                       const Standard_ShortReal Y,
297                       const Standard_ShortReal aPrecision,
298                       const Handle(Graphic2d_Drawer)& /*aDrawer*/) {
299
300  Standard_Integer i,length = myCurves.Length();
301  //Standard_ShortReal SRX = X, SRY = Y;
302  static Standard_ShortReal SRX , SRY ;
303  SRX = X;
304  SRY = Y;
305  //Standard_Boolean isPicked = Standard_False;
306   
307  if ( (length > 0) && IsInMinMax (X, Y, aPrecision)) {
308   if (myGOPtr->IsTransformed ()) {
309     gp_GTrsf2d aTrsf = (myGOPtr->Transform()).Inverted();
310     Standard_Real RX = Standard_Real( SRX ), RY = Standard_Real( SRY );
311     aTrsf.Transforms( RX, RY );
312     SRX = Standard_ShortReal( RX ); SRY = Standard_ShortReal( RY );
313    }
314    try {
315      OCC_CATCH_SIGNALS
316       Handle(Geom2d_Curve) aCurve;
317       for ( i = 1 ; i <= length; i++ ) {
318         aCurve = myCurves.Value(i);
319         Standard_Real FParam = aCurve->FirstParameter(), 
320                       LParam = aCurve->LastParameter();
321         gp_Pnt2d FP = aCurve->Value(FParam), 
322                  LP = aCurve->Value(LParam);
323         Geom2dAPI_ProjectPointOnCurve PC(gp_Pnt2d(SRX, SRY),
324                                      aCurve,
325                                      FParam,
326                                      LParam );
327         if ( PC.NbPoints() > 0 ) {
328           gp_Pnt2d P = PC.NearestPoint();
329
330 #ifdef G002
331
332           if ( ( Abs( SRX - P.X() ) +  Abs( SRY - P.Y() ) ) < aPrecision ) {
333             SetPickedIndex( i );
334             return Standard_True;
335           } else if ( Graphic2d_Primitive::IsOn( SRX, SRY, 
336               Standard_ShortReal(FP.X()), Standard_ShortReal(FP.Y()), aPrecision) ) {
337             SetPickedIndex( -i );
338             return Standard_True;
339           } else if ( Graphic2d_Primitive::IsOn( SRX, SRY, 
340               Standard_ShortReal(LP.X()), Standard_ShortReal(LP.Y()), aPrecision) ) {
341             SetPickedIndex( -i - length );
342             return Standard_True;
343           }
344 #else
345           if ( ( Abs( SRX - P.X() ) +  Abs( SRY - P.Y() ) ) < aPrecision ) {
346                 myPickedIndex = i;
347             return Standard_True;
348           }
349 #endif
350         } // end if NbPoints() > 0
351       } // end for
352     } catch( Standard_Failure )  {
353       return Standard_False;
354     }
355   }
356
357   return Standard_False;
358  
359 }
360
361 void GGraphic2d_SetOfCurves::Save(Aspect_FStream& aFStream) const
362 {
363         int i,lngth = Length();
364         if ( ! lngth ) return;
365
366         *aFStream << "GGraphic2d_SetOfCurves" << endl;
367         *aFStream << lngth << endl;     
368
369
370         Handle(Geom2d_Curve) myCurve;
371
372         for ( i = 1; i <= lngth; i++ ) {
373
374         myCurve = myCurves.Value( i );
375
376         if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_Line)) ) {
377
378         Handle(Geom2d_Line) theLine = Handle(Geom2d_Line)::DownCast( myCurve );
379         gp_Dir2d tDir = theLine->Direction();
380         gp_Pnt2d tPnt = theLine->Location();
381
382         *aFStream << "Geom2d_Line" << endl;
383         *aFStream << tDir.X() << ' ' << tDir.Y() << endl;
384         *aFStream << tPnt.X() << ' ' << tPnt.Y() << endl;
385
386         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_Circle)) ) {
387
388         Handle(Geom2d_Circle) theCirc = Handle(Geom2d_Circle)::DownCast( myCurve );
389         gp_Circ2d tCirc  = theCirc->Circ2d();
390         gp_Ax22d tAx22d = tCirc.Axis();
391         gp_Pnt2d tLoc  = tAx22d.Location();
392         gp_Dir2d tDirX = tAx22d.XDirection(),
393                tDirY = tAx22d.YDirection();
394
395         Standard_Real tRad = tCirc.Radius();
396
397         *aFStream << "Geom2d_Circle" << endl;
398         *aFStream << tLoc.X() << ' ' << tLoc.Y() << endl;
399         *aFStream << tDirX.X() << ' ' << tDirX.Y() << endl;
400         *aFStream << tDirY.X() << ' ' << tDirY.Y() << endl;
401         *aFStream << tRad << endl;
402
403         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_Parabola)) ) {
404
405         Handle(Geom2d_Parabola) theParab = Handle(Geom2d_Parabola)::DownCast( myCurve );
406         gp_Parab2d tParab = theParab->Parab2d();
407         gp_Ax22d tAx22d = tParab.Axis();
408         gp_Pnt2d tLoc  = tAx22d.Location();
409         gp_Dir2d tDirX = tAx22d.XDirection(),
410                 tDirY = tAx22d.YDirection();
411
412         Standard_Real tFocal = theParab->Focal();
413
414         *aFStream << "Geom2d_Parabola" << endl;
415         *aFStream << tLoc.X() << ' ' << tLoc.Y() << endl;
416         *aFStream << tDirX.X() << ' ' << tDirX.Y() << endl;
417         *aFStream << tDirY.X() << ' ' << tDirY.Y() << endl;
418         *aFStream << tFocal << endl;
419
420         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_Ellipse)) ) {
421         Handle(Geom2d_Ellipse) theEllipse = Handle(Geom2d_Ellipse)::DownCast(myCurve);
422         gp_Elips2d tElips = theEllipse->Elips2d();
423         Standard_Real tMin = tElips.MinorRadius(),
424                      tMaj = tElips.MajorRadius();
425         gp_Ax22d tAx22d = tElips.Axis();
426         gp_Pnt2d tLoc  = tAx22d.Location();
427         gp_Dir2d tDirX = tAx22d.XDirection(),
428                 tDirY = tAx22d.YDirection();
429
430         *aFStream << "Geom2d_Ellipse" << endl;
431
432         *aFStream << tMin << ' ' << tMaj << endl;
433         *aFStream << tLoc.X() << ' ' << tLoc.Y() << endl;
434         *aFStream << tDirX.X() << ' ' << tDirX.Y() << endl;
435         *aFStream << tDirY.X() << ' ' << tDirY.Y() << endl;
436
437         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_Hyperbola)) ) {
438
439         Handle(Geom2d_Hyperbola) theHypr = Handle(Geom2d_Hyperbola)::DownCast(myCurve);
440         gp_Hypr2d tHypr = theHypr->Hypr2d();
441         Standard_Real tMin = tHypr.MinorRadius(),
442                       tMaj = tHypr.MajorRadius();
443         gp_Ax22d tAx22d = tHypr.Axis();
444         gp_Pnt2d tLoc  = tAx22d.Location();
445         gp_Dir2d tDirX = tAx22d.XDirection(),
446                  tDirY = tAx22d.YDirection();
447
448         *aFStream << "Geom2d_Hyperbola" << endl;
449
450         *aFStream << tMin << ' ' << tMaj << endl;
451         *aFStream << tLoc.X() << ' ' << tLoc.Y() << endl;
452         *aFStream << tDirX.X() << ' ' << tDirX.Y() << endl;
453         *aFStream << tDirY.X() << ' ' << tDirY.Y() << endl;
454
455         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) ) {
456
457         Handle(Geom2d_BezierCurve) theBC = Handle(Geom2d_BezierCurve)::DownCast(myCurve);
458         Standard_Integer nbPoles = theBC->NbPoles();
459         TColgp_Array1OfPnt2d tpoles( 1, nbPoles );
460         theBC->Poles( tpoles );
461         *aFStream << "Geom2d_BezierCurve" << endl;
462
463         for ( Standard_Integer k = 1; k <= nbPoles; k++ ) 
464           *aFStream << tpoles(k).X() << ' ' << tpoles(k).Y() << endl;
465
466         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) ) {
467         Handle(Geom2d_BSplineCurve) theBSC = Handle(Geom2d_BSplineCurve)::DownCast(myCurve);
468
469         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve)) ) {
470         Handle(Geom2d_OffsetCurve) theOC = Handle(Geom2d_OffsetCurve)::DownCast(myCurve);
471
472         } else if ( myCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)) ) {    
473         Handle(Geom2d_TrimmedCurve) theTC = Handle(Geom2d_TrimmedCurve)::DownCast(myCurve);
474         }
475
476         } // end for 
477         Graphic2d_Line::Save(aFStream);
478 }