Salome HOME
fcfbd0fec0aa840fee288e616cb2ee9a472489fe
[modules/gui.git] / src / Plot2d / Plot2d_AnalyticalCurve.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : Plot2d_AnalyticalCurve.cxx
23 //  Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
24
25 #include "Plot2d_AnalyticalParser.h"
26 #include "Plot2d_AnalyticalCurve.h"
27 #include "Plot2d_PlotItems.h"
28 #include "Plot2d_Object.h"
29
30 #include <qwt_scale_div.h>
31
32
33 //Init static data;
34
35 int Plot2d_AnalyticalCurve::myNbCurves = 0;
36
37 /*!
38   Constructor
39 */
40 Plot2d_AnalyticalCurve::Plot2d_AnalyticalCurve() : 
41   myAutoAssign(true),
42   myColor( 0, 0, 0 ), 
43   myMarker( Plot2d::Circle ), 
44   myMarkerSize( 0 ), 
45   myLine( Plot2d::Solid ), 
46   myLineWidth( 0 ),
47   myNbIntervals(100),
48   myRangeBegin(0.0),
49   myRangeEnd(100.0),
50   myExpression(""),
51   myAction(Plot2d_AnalyticalCurve::ActAddInView),
52   myState(Plot2d_AnalyticalCurve::StateNeedUpdate),
53   myCurve(0),
54   myActive(true),
55   myIsSelected(false)
56 {
57   myName = QString("Analytical Curve %1").arg(++myNbCurves);
58 }
59
60
61 /*!
62   Destructor
63 */
64 Plot2d_AnalyticalCurve::~Plot2d_AnalyticalCurve()
65 {
66 }
67
68 /*!
69   Copy constructor. Makes deep copy of data
70 */
71 Plot2d_AnalyticalCurve::Plot2d_AnalyticalCurve( const Plot2d_AnalyticalCurve& curve )
72 {
73   myAutoAssign = curve.isAutoAssign();
74   myColor      = curve.getColor();
75   myMarker     = curve.getMarker();
76   myMarkerSize = curve.getMarkerSize();
77   myLine       = curve.getLine();
78   myLineWidth  = curve.getLineWidth();
79   myRangeBegin = curve.getRangeBegin();
80   myRangeEnd   = curve.getRangeEnd();
81   myNbIntervals= curve.getNbIntervals();
82   myPoints     = curve.myPoints;
83   myAction     = curve.getAction();
84   myName       = curve.getName();
85   myExpression = curve.getExpression();
86   myState      = curve.state();
87   myCurve      = curve.myCurve;
88   myActive     = curve.isActive();
89 }
90
91 /*!
92   operator=. Makes deep copy of data
93 */
94 Plot2d_AnalyticalCurve& Plot2d_AnalyticalCurve::operator=( const Plot2d_AnalyticalCurve& curve )
95 {
96   myAutoAssign = curve.isAutoAssign();
97   myColor      = curve.getColor();
98   myMarker     = curve.getMarker();
99   myMarkerSize = curve.getMarkerSize();
100   myLine       = curve.getLine();
101   myLineWidth  = curve.getLineWidth();
102   myRangeBegin = curve.getRangeBegin();
103   myRangeEnd   = curve.getRangeEnd();
104   myNbIntervals= curve.getNbIntervals();
105   myPoints     = curve.myPoints;
106   myAction     = curve.getAction();
107   myName       = curve.getName();
108   myExpression = curve.getExpression();
109   myState      = curve.state();
110   myCurve      = curve.myCurve;
111   myActive     = curve.isActive();
112   return *this;
113 }
114
115 /*!
116   Create plot object for the curve
117 */
118 QwtPlotItem* Plot2d_AnalyticalCurve::plotItem()
119 {
120   if(!myCurve) {
121     myCurve = new Plot2d_QwtPlotCurve(QString(""));
122     updatePlotItem();
123   }
124   return myCurve;
125 }
126
127 /*!
128   Auto fill parameters of object by plot view
129 */
130 void Plot2d_AnalyticalCurve::autoFill( const QwtPlot* thePlot )
131 {
132   QwtSymbol::Style typeMarker;
133   QColor           color;
134   Qt::PenStyle     typeLine;
135   Plot2d::getNextMarker( QwtPlotItem::Rtti_PlotCurve, thePlot, typeMarker, color, typeLine );
136   
137   setColor( color );
138   setLine( Plot2d::qwt2plotLine( typeLine ));
139   setLineWidth(1);
140   setMarker( Plot2d::qwt2plotMarker( typeMarker ) );
141 }
142
143 /*!
144   Updates curve fields
145 */
146 void Plot2d_AnalyticalCurve::updatePlotItem()
147 {
148   if ( !myCurve )
149     return;
150
151   Plot2d_QwtPlotCurve* aCurve = dynamic_cast<Plot2d_QwtPlotCurve*>(myCurve);
152
153   if(!aCurve)
154     return;
155   
156   Qt::PenStyle     ps = Plot2d::plot2qwtLine( getLine() );
157   QwtSymbol::Style ms = Plot2d::plot2qwtMarker( getMarker() );
158
159   QColor aColor = isSelected() ?  Plot2d_Object::selectionColor() : getColor();
160   int lineW = getLineWidth(); 
161   if ( isSelected() ) lineW += (lineW == 0 ? 3 : 2);
162
163   int markerS = isSelected() ? getMarkerSize() + 2 : getMarkerSize();
164
165   aCurve->setSelected(isSelected());
166
167   aCurve->setPen( QPen(aColor , lineW, ps ) );
168   aCurve->setSymbol( new QwtSymbol( ms, QBrush( aColor ),
169                                     QPen( aColor ),
170                                     QSize( markerS , markerS ) ) );
171
172   aCurve->setLegendPen(QPen(getColor(), getLineWidth(), ps ));
173   aCurve->setLegendSymbol( new QwtSymbol( ms, QBrush( getColor() ),
174                                           QPen( getColor() ),
175                                           QSize( getMarkerSize() , getMarkerSize() )));
176
177   double *x, *y;
178   long nb = getData( &x, &y );
179   aCurve->setSamples( x, y, nb );
180   aCurve->setTitle(getName());
181 }
182
183
184 /*!
185   Calculate the curve points.
186 */
187 void Plot2d_AnalyticalCurve::calculate() {
188   if( state() == Plot2d_AnalyticalCurve::StateOk )
189     return;
190
191   if(myRangeBegin > myRangeEnd)
192     return;
193
194   Plot2d_AnalyticalParser* parser = Plot2d_AnalyticalParser::parser();
195   double* x = 0;
196   double* y = 0;
197   int nb = parser->calculate(getExpression(), getRangeBegin(), getRangeEnd(),
198                              getNbIntervals(),&x,&y);
199   if( nb > 0 ) {
200     myPoints.clear();
201     for( int i = 0; i < nb; i++ ) {
202       Plot2d_Point pnt(x[i], y[i]);
203       myPoints.append(pnt);
204     }
205     delete x;
206     delete y;
207     myState = Plot2d_AnalyticalCurve::StateOk;
208     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
209   }
210 }
211 /*!
212   Checks that this curve can be computed for the input QwtPlot
213 */
214 bool Plot2d_AnalyticalCurve::checkCurve( const QwtPlot* thePlot) {
215   if( !myExpression.isEmpty() && thePlot ) {
216     const QwtScaleDiv div = thePlot->axisScaleDiv(QwtPlot::xBottom);
217     setRangeBegin(div.lowerBound());
218     setRangeEnd(div.upperBound());
219     calculate();
220   }
221   return myState == Plot2d_AnalyticalCurve::StateOk;
222 }
223
224
225 /*!
226   Gets object's data
227 */
228 long Plot2d_AnalyticalCurve::getData( double** theX, double** theY ) const
229 {
230   int aNPoints = myPoints.size();
231   *theX = new double[aNPoints];
232   *theY = new double[aNPoints];
233   for (int i = 0; i < aNPoints; i++) {
234     (*theX)[i] = myPoints[i].x;
235     (*theY)[i] = myPoints[i].y;
236   }
237   return aNPoints;
238 }
239
240 /*!
241   Sets curves's AutoAssign flag - in this case attributes will be set automatically
242 */
243 void Plot2d_AnalyticalCurve::setAutoAssign( bool on )
244 {
245   if( myAutoAssign != on ) {
246     myAutoAssign = on;
247     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
248   }
249 }
250
251 /*!
252   Gets curve's AutoAssign flag state
253 */
254 bool Plot2d_AnalyticalCurve::isAutoAssign() const
255 {
256   return myAutoAssign;
257 }
258
259 /*!
260   Sets curve's color.
261 */
262 void Plot2d_AnalyticalCurve::setColor( const QColor& color )
263 {
264   if(myColor != color) {
265     myColor = color;
266     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
267   }
268 }
269
270 /*!
271   Gets curve's color
272 */
273 QColor Plot2d_AnalyticalCurve::getColor() const
274 {
275   return myColor;
276 }
277
278
279 /*!
280   Sets marker type ( and resets AutoAssign flag )
281 */
282 void Plot2d_AnalyticalCurve::setMarker( Plot2d::MarkerType marker )
283 {
284   if(myMarker != marker) {
285     myMarker = marker;
286     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
287   }
288 }
289
290 /*!
291   Gets marker type
292 */
293 Plot2d::MarkerType Plot2d_AnalyticalCurve::getMarker() const
294 {
295   return myMarker;
296 }
297
298 /*!
299   Sets new marker size
300 */
301 void Plot2d_AnalyticalCurve::setMarkerSize( const int theSize )
302 {
303   if( myMarkerSize != theSize ) {
304     myMarkerSize = theSize < 0 ? 0 : theSize;
305     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
306   }
307 }
308
309 /*!
310   Gets marker size
311 */
312 int Plot2d_AnalyticalCurve::getMarkerSize() const
313 {
314   return myMarkerSize;
315 }
316
317 /*!
318   Sets line type
319 */
320 void Plot2d_AnalyticalCurve::setLine( Plot2d::LineType line )
321 {
322   if(myLine != line) {
323     myLine = line;
324     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
325   }
326 }
327
328 /*!
329   Gets line type
330 */
331 Plot2d::LineType Plot2d_AnalyticalCurve::getLine() const
332 {
333   return myLine;
334 }
335
336
337 /*!
338   Sets line width
339 */
340 void Plot2d_AnalyticalCurve::setLineWidth( const int lineWidth )
341 {
342   if( myLineWidth != lineWidth ) {
343     myLineWidth = lineWidth < 0 ? 0 : lineWidth;
344     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
345   }
346 }
347
348 /*!
349   Gets line width
350 */
351 int Plot2d_AnalyticalCurve::getLineWidth() const
352 {
353   return myLineWidth;
354 }
355
356 /*!
357   Sets number of points
358 */
359 void Plot2d_AnalyticalCurve::setNbIntervals( const long nb )
360 {
361   if( myNbIntervals != nb ) {
362     myNbIntervals = nb < 1 ? 1 : nb;
363     myState = Plot2d_AnalyticalCurve::StateNeedUpdate;
364   }
365 }
366
367 /*!
368   Gets number of points
369 */
370 long Plot2d_AnalyticalCurve::getNbIntervals() const
371 {
372   return myNbIntervals;
373 }
374
375 /*!
376   Sets X coordinate of the first curve points
377 */
378 void Plot2d_AnalyticalCurve::setRangeBegin( const double coord) {
379   if( myRangeBegin != coord ) {
380     myRangeBegin = coord;
381     myState = Plot2d_AnalyticalCurve::StateNeedUpdate;
382   }
383 }
384
385 /*!
386   Gets X coordinate of the first curve points
387 */
388 double Plot2d_AnalyticalCurve::getRangeBegin() const {
389   return myRangeBegin;
390 }
391
392 /*!
393   Sets X coordinate of the last curve points
394 */
395 void Plot2d_AnalyticalCurve::setRangeEnd( const double coord) {
396   if( myRangeEnd != coord ) {
397     myRangeEnd = coord;
398     myState = Plot2d_AnalyticalCurve::StateNeedUpdate;
399   }
400 }
401
402 /*!
403   Gets X coordinate of the last curve points
404 */
405 double Plot2d_AnalyticalCurve::getRangeEnd() const {
406   return myRangeEnd;
407 }
408
409 /*!
410   Sets the curve expression.
411 */
412 void Plot2d_AnalyticalCurve::setExpression( const QString& expr ) {
413   if( myExpression != expr ) {
414     myExpression = expr;
415     myState = Plot2d_AnalyticalCurve::StateNeedUpdate;
416   }
417 }
418
419 /*!
420   Gets the curve expression.
421 */
422 QString Plot2d_AnalyticalCurve::getExpression() const {
423   return  myExpression;
424 }
425
426 /*!
427   Sets the curve name.
428 */
429 void Plot2d_AnalyticalCurve::setName( const QString& name ) {
430   if( myName != name ) {    
431     myName = name;
432     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
433   }
434 }
435
436 /*!
437   Gets the curve name.
438 */
439 QString Plot2d_AnalyticalCurve::getName() const {
440   return myName;
441 }
442
443
444 /*!
445   Sets the curve action.
446 */
447 void Plot2d_AnalyticalCurve::setAction(const int act) {
448   if( act == Plot2d_AnalyticalCurve::ActNothing ) {
449     myAction = act;
450     return;
451   }
452   
453   if(myAction != Plot2d_AnalyticalCurve::ActAddInView && 
454      myAction != Plot2d_AnalyticalCurve::ActRemoveFromView) {
455     myAction = act;  
456   }
457 }
458
459 /*!
460   Gets the curve action.
461 */
462 int Plot2d_AnalyticalCurve::getAction() const {
463   return myAction;
464 }
465
466 /*!
467   Gets the curve state.
468 */
469 int Plot2d_AnalyticalCurve::state() const {
470   return myState;
471 }
472
473 /*!
474   Sets the curve active status.
475 */
476 void Plot2d_AnalyticalCurve::setActive(const bool on) {
477   if( myActive != on ) {    
478     if(myActive && !on)
479       setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
480     else if(!myActive && on) {
481       setAction(Plot2d_AnalyticalCurve::ActAddInView);
482       myState = Plot2d_AnalyticalCurve::StateNeedUpdate;
483     }
484     myActive = on;
485   }  
486 }
487
488 /*!
489   Gets the curve active status.
490 */
491 bool Plot2d_AnalyticalCurve::isActive() const {
492   return myActive;
493 }
494
495
496 /*!
497   Sets curve's selected property.
498 */
499 void Plot2d_AnalyticalCurve::setSelected(const bool on) {
500   if(myIsSelected != on) {
501         myIsSelected  = on;
502     setAction(Plot2d_AnalyticalCurve::ActUpdateInView);
503   }
504
505 }
506
507 /*!
508   Gets curve's selected property.
509 */
510 bool Plot2d_AnalyticalCurve::isSelected() const {
511   return myIsSelected;
512 }