2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
4 * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
5 * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
6 * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7 * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
9 * This file must be used under the terms of the CeCILL.
10 * This source file is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at
13 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
17 /*------------------------------------------------------------------------
19 --------------------------------------------------------------------------*/
22 #include "math_graphics.h"
26 #define spINSIDE_SPARSE
27 #include "../../sparse/includes/spConfig.h"
29 #include "SetProperty.h"
30 #include "DrawObjects.h"
31 #include "BuildObjects.h"
33 #include "BasicAlgos.h"
37 #include "MALLOC.h" /* MALLOC */
38 #include "scitokenize.h"
39 #include "localization.h"
40 #include "get_ticks_utils.h"
41 #include "HandleManagement.h"
42 #include "freeArrayOfString.h"
44 #include "getGraphicObjectProperty.h"
45 #include "setGraphicObjectProperty.h"
46 #include "graphicObjectProperties.h"
47 #include "CurrentFigure.h"
48 #include "CurrentSubwin.h"
49 #include "CurrentObject.h"
51 /*--------------------------------------------------------------------
52 * plot2dn(ptype,Logflags,x,y,n1,n2,style,strflag,legend,brect,aaint,lstr1,lstr2)
54 * Draw *n1 curves of *n2 points each
56 * ptype is an int which gives the polyline drawind mode (0,1,2,3,4)
58 * Logflags is a two character string
60 * (x[i+(*n2)*j] ,y[i+(*n2)*j]) Double values giving the point
61 * position of point i of curve j (i=0,*n2-1 j=0,*n1-1)
63 * style[*n1]-> give the style to use for each curve
64 * if style is positive --> a mark is used (mark id = style[i])
65 * if style is strictly negative --> a dashed line is used
66 * (dash id = abs(style[i])
67 * if there's only one curve, style can be of type style[0]=style,
68 * style[1]=pos ( pos in [1,6])
69 * pos give the legend position (1 to 6) (this can be iteresting
70 * if you want to superpose curves with different legends by
71 * calling plot2d more than one time.
73 * strflag[3] is a string
75 * if strflag[0] == '1' then legends are added
76 * legend = "leg1@leg2@....@legn"; gives the legend for each curve
79 * if strflag[1] == '1' then the values of brect are used to fix
80 * the drawing boundaries : brect[]= <xmin,ymin,xmax,ymax>;
81 * if strflag[1] == '2' then the values are computed from data
82 * else if strflag[1]=='0' the previous values
83 * (previous call or defaut values) are used
85 * if strflag[2] == '1' ->then an axis is added
86 * the number of intervals
87 * is specified by the vector aaint[4] of integers
88 * <aaint[0],aaint[1]> specifies the x-axis number of points
89 * <aaint[2],aaint[3]> same for y-axis
90 * if strflag[2] == '2' -> no axis, only a box around the curves
91 * else no box and no axis
93 * lstr* : unused ( but used by Fortran )
94 *--------------------------------------------------------------------------*/
96 int plot2dn(int ptype, char *logflags, double *x, double *y, int *n1, int *n2, int *style, char *strflag, char *legend, double *brect, int *aaint,
97 BOOL flagNax, int lstr1, int lstr2)
99 char *psubwinUID = NULL;
100 char *curFigureUID = NULL;
103 long long *tabofhandles = NULL;
111 BOOL bounds_changed = FALSE;
112 BOOL axes_properties_changed = FALSE;
114 double rotationAngles[2];
120 char textLogFlags[3];
122 int newFirstPlot = 0;
123 int autoSubticks = 0;
125 psubwinUID = (char*)getOrCreateDefaultSubwin();
128 * Check if the auto_clear property is on and then erase everything
133 rotationAngles[0] = 0.0;
134 rotationAngles[1] = 270.0;
136 setGraphicObjectProperty(psubwinUID, __GO_ROTATION_ANGLES__, rotationAngles, jni_double_vector, 2);
138 /* Force logflags to those given by argument */
140 getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
143 /* Reset x and y logflags */
146 logFlags[0] = getBooleanLogFlag(logflags[1]);
147 logFlags[1] = getBooleanLogFlag(logflags[2]);
149 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, &logFlags[0], jni_bool, 1);
150 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, &logFlags[1], jni_bool, 1);
153 /* Forces "clipgrf" clipping (1) */
155 setGraphicObjectProperty(psubwinUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
157 getGraphicObjectProperty(psubwinUID, __GO_AUTO_SCALE__, jni_bool, (void **)&piTmp);
162 /* compute and merge new specified bounds with the data bounds */
166 /* do not change data bounds */
172 /* Force data bounds=brect */
173 re_index_brect(brect, drect);
180 /* Force data bounds to the x and y bounds */
181 if ((int)strlen(logflags) < 1)
184 dataflag = logflags[0];
186 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
188 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
190 getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
193 /* Conversion required by compute_data_bounds2 */
194 textLogFlags[0] = getTextLogFlag(logFlags[0]);
195 textLogFlags[1] = getTextLogFlag(logFlags[1]);
196 textLogFlags[2] = getTextLogFlag(logFlags[2]);
198 compute_data_bounds2(0, dataflag, textLogFlags, x, y, *n1, *n2, drect);
203 /* merge data bounds and drect */
204 if (!firstPlot && (strflag[1] == '5' || strflag[1] == '7' || strflag[1] == '8' || strflag[1] == '9'))
208 getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
210 drect[0] = Min(dataBounds[0], drect[0]); /*xmin */
211 drect[2] = Min(dataBounds[2], drect[2]); /*ymin */
212 drect[1] = Max(dataBounds[1], drect[1]); /*xmax */
213 drect[3] = Max(dataBounds[3], drect[3]); /*ymax */
216 if (strflag[1] != '0')
218 bounds_changed = update_specification_bounds(psubwinUID, drect, 2);
224 bounds_changed = TRUE;
227 /* Adapted to the MVC */
228 axes_properties_changed = strflag2axes_properties(psubwinUID, strflag);
230 /* just after strflag2axes_properties */
232 setGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, &newFirstPlot, jni_bool, 1);
234 with_leg = (strflag[0] == '1');
236 /* F.Leray 07.10.04 : trigger algo to init. manual graduation u_xgrads and
237 * u_ygrads if nax (in matdes.c which is == aaint HERE) was specified */
239 /* The MVC AUTO_SUBTICKS property corresponds to !flagNax */
240 autoSubticks = !flagNax;
241 setGraphicObjectProperty(psubwinUID, __GO_AUTO_SUBTICKS__, &autoSubticks, jni_bool, 1);
245 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
247 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
250 if (logFlags[0] == 0 && logFlags[1] == 0)
256 double* dXGrads = (double*) malloc(aaint[1] * sizeof(double));
257 double* dYGrads = (double*) malloc(aaint[3] * sizeof(double));
258 char** stringVector = NULL;
260 // set auto ticks to off
261 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
262 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
265 dXGrads[0] = drect[0];
268 double pas = (drect[1] - drect[0]) / (aaint[1] - 1);
269 for (i = 0; i < aaint[1]; i++)
271 dXGrads[i] = drect[0] + pas * i;
275 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LOCATIONS__, dXGrads, jni_double_vector, aaint[1]);
278 dYGrads[0] = drect[2];
281 double pas = (drect[3] - drect[2]) / (aaint[3] - 1);
282 for (i = 0; i < aaint[3]; i++)
284 dYGrads[i] = drect[2] + pas * i;
288 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LOCATIONS__, dYGrads, jni_double_vector, aaint[3]);
291 stringVector = (char **) malloc(aaint[1] * sizeof(char*));
292 for (i = 0; i < aaint[1]; i++)
299 dblFabs = fabs(dXGrads[i]);
302 iSize = iSize + (int)floor(log10(dblFabs));
305 stringVector[i] = (char*) malloc(iSize * sizeof(char));
306 sprintf(stringVector[i], "%.3f", dXGrads[i]);
307 stringVector[i][iSize - 1] = '\0';
310 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[1]);
312 for (i = 0; i < aaint[1]; i++)
314 free(stringVector[i]);
321 stringVector = (char**) malloc(aaint[3] * sizeof(char*));
322 for (i = 0; i < aaint[3]; i++)
329 dblFabs = fabs(dYGrads[i]);
332 iSize = iSize + (int)floor(log10(dblFabs));
334 stringVector[i] = (char*) malloc(iSize * sizeof(char));
335 sprintf(stringVector[i], "%.3f", dYGrads[i]);
336 stringVector[i][iSize - 1] = '\0';
339 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[3]);
341 for (i = 0; i < aaint[3]; i++)
343 free(stringVector[i]);
351 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_SUBTICKS__, aaint, jni_int, 1);
352 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_SUBTICKS__, &aaint[2], jni_int, 1);
357 sciprint(_("Warning: Nax does not work with logarithmic scaling.\n"));
362 /*---- Drawing the curves and the legends ----*/
365 if ((hdltab = MALLOC((*n1 + 1) * sizeof(long))) == NULL)
367 Scierror(999, _("%s: No more memory.\n"), "plot2d");
372 /* tabofhandles allocated for legends */
373 if ((tabofhandles = MALLOC((*n1) * sizeof(long long))) == NULL)
375 Scierror(999, _("%s: No more memory.\n"), "plot2d");
381 /*A.Djalel 3D axes */
382 for (jj = 0; jj < *n1; jj++)
384 char *pobjUID = NULL;
394 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
395 &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
396 &style[jj], NULL, NULL, NULL, NULL, isline, FALSE, FALSE, FALSE);
400 int minusstyle = -style[jj];
402 pobjUID = ConstructPolyline((char*)getCurrentSubWin(), &(x[jj * (*n2)]),
403 &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
404 NULL, NULL, &minusstyle, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
409 Scierror(999, _("%s: No more memory.\n"), "plot2d");
413 setCurrentObject(pobjUID);
415 hdl = getHandle(pobjUID);
416 releaseGraphicObjectProperty(__GO_PARENT__, pobjUID, jni_string, 1);
420 tabofhandles[cmpt] = hdl;
429 /*---- Drawing the Legends ----*/
436 if (scitokenize(legend, &Str, &nleg))
440 Scierror(999, _("%s: No more memory.\n"), "plot2d");
444 legUID = ConstructLegend((char*)getCurrentSubWin(), Str, tabofhandles, Min(nleg, cmpt));
451 /* 9: LOWER_CAPTION */
453 setGraphicObjectProperty(legUID, __GO_LEGEND_LOCATION__, &legendLocation, jni_int, 1);
457 setGraphicObjectProperty(legUID, __GO_FILL_MODE__, &contourMode, jni_bool, 1);
458 setGraphicObjectProperty(legUID, __GO_LINE_MODE__, &contourMode, jni_bool, 1);
461 freeArrayOfString(Str, nleg);
466 /*---- construct Compound ----*/
469 int parentVisible = 0;
470 int *piParentVisible = &parentVisible;
471 char* compoundUID = ConstructCompound (hdltab, cmpt);
472 setCurrentObject(compoundUID);
473 setGraphicObjectRelationship(psubwinUID, compoundUID);
474 getGraphicObjectProperty(psubwinUID, __GO_VISIBLE__, jni_bool, (void **)&piParentVisible);
475 setGraphicObjectProperty(compoundUID, __GO_VISIBLE__, &parentVisible, jni_bool, 1);
476 releaseGraphicObjectProperty(__GO_PARENT__, compoundUID, jni_string, 1);
481 /* End of the curves and legend block */
486 /* Given two set of coordinates x and y this routine computes the corresponding
487 * data bounds rectangle drect=[xmin,ymin,xmax,ymax] taking into account the logflag
488 * -> means we have to find among the data the min > 0.
490 void compute_data_bounds2(int cflag, char dataflag, char *logflags, double *x, double *y, int n1, int n2, double *drect)
492 int size_x = 0, size_y = 0;
502 size_x = (n2 != 0) ? 2 : 0;
511 size_x = (cflag == 1) ? n1 : (n1 * n2);
517 if (logflags[0] != 'l')
519 drect[0] = Mini(x1, size_x);
520 drect[1] = Maxi(x1, size_x);
525 drect[0] = sciFindStPosMin(x1, size_x);
526 drect[1] = Maxi(x1, size_x);
532 if (logflags[0] != 'l')
545 size_y = (cflag == 1) ? n2 : (n1 * n2);
548 if (logflags[1] != 'l')
550 drect[2] = Mini(y, size_y);
551 drect[3] = Maxi(y, size_y);
556 drect[2] = sciFindStPosMin(y, size_y);
557 drect[3] = Maxi(y, size_y);
563 if (logflags[1] != 'l')
575 /* back to default values for x=[] and y = [] */
576 if (drect[2] == LARGEST_REAL)
581 if (drect[0] == LARGEST_REAL)
589 BOOL update_specification_bounds(char *psubwinUID, double rect[6], int flag)
591 double *dataBounds = NULL;
594 * 2D: keep the existing zmin and zmax
595 * which is why they must be fetched
599 getGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
601 rect[4] = dataBounds[4];
602 rect[5] = dataBounds[5];
605 setGraphicObjectProperty(psubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
611 /* brect must have the same format as drect i.e.: [xmin,xmax,ymin,ymax] */
612 /* brect = INPUT ; drect = OUTPUT (warning drect is dim 6) */
613 int re_index_brect(double *brect, double *drect)
623 /* F.Leray 07.05.04 */
624 /* Dispatch info contained in strflag to all the flag available in
625 sciSubwin object (tight_limits, isoview, isaxes...) */
627 * This function has been adapted to the MVC framework
629 BOOL strflag2axes_properties(char *psubwinUID, char *strflag)
631 BOOL haschanged = FALSE;
632 BOOL tightLimitsPrev = FALSE;
633 BOOL isoviewPrev = FALSE;
639 int xLocationPrev = 0;
640 int yLocationPrev = 0;
644 int axesVisiblePrev[3];
650 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
651 axesVisiblePrev[0] = iTmp;
652 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
653 axesVisiblePrev[1] = iTmp;
654 getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
655 axesVisiblePrev[2] = iTmp;
657 getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
660 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
661 xLocationPrev = iTmp;
662 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
663 yLocationPrev = iTmp;
665 getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
666 tightLimitsPrev = iTmp;
667 getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
670 /* F.Leray 07.05.04 */
671 /* strflag[1] Isoview & tight_limits flags management */
683 setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
688 setGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, &isoview, jni_bool, 1);
694 setGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
698 /* F.Leray 07.05.04 */
704 getGraphicObjectProperty(psubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
713 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
714 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
715 /* also trigger z axis */
716 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
717 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
719 /*else no changes : the isaxes properties is driven by the previous plot */
728 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
729 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
730 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
731 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
732 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
739 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
740 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
741 /* also trigger z axis */
742 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
743 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
752 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
753 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
754 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
755 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
756 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
766 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
767 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
768 /* also trigger z axis */
769 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
770 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
771 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
772 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
781 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
782 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
783 /* also trigger z axis */
784 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
785 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
786 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
787 setGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
793 setGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
794 setGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
795 /* also trigger z axis */
796 setGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
799 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
800 axesVisible[0] = iTmp;
801 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
802 axesVisible[1] = iTmp;
803 getGraphicObjectProperty(psubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
804 axesVisible[2] = iTmp;
806 getGraphicObjectProperty(psubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
809 getGraphicObjectProperty(psubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
811 getGraphicObjectProperty(psubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
814 getGraphicObjectProperty(psubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
816 getGraphicObjectProperty(psubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
819 /* Find if something has changed */
820 if (axesVisible[0] != axesVisiblePrev[0]
821 || axesVisible[1] != axesVisiblePrev[1]
822 || axesVisible[2] != axesVisiblePrev[2]
823 || xLocation != xLocationPrev || yLocation != yLocationPrev || boxType != boxPrev || tightLimits != tightLimitsPrev || isoview != isoviewPrev)