2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Clement DAVID
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
15 #define M_PI 3.14159265358979323846
19 #include "dynlib_scicos_blocks.h"
23 #include "elementary_functions.h"
25 #include "setGraphicObjectProperty.h"
26 #include "getGraphicObjectProperty.h"
27 #include "graphicObjectProperties.h"
28 #include "createGraphicObject.h"
30 #include "CurrentFigure.h"
32 #include "scicos_block4.h"
35 #include "localization.h"
37 #include "strdup_windows.h"
40 #include "FigureList.h"
41 #include "BuildObjects.h"
42 #include "AxesModel.h"
44 /*****************************************************************************
45 * Internal container structure
46 ****************************************************************************/
68 * Get (and allocate on demand) the internal data used on this scope
69 * \param block the block
70 * \return the scope data
72 static sco_data *getScoData(scicos_block * block);
75 * Release any internal data
77 * \param block the block
79 static void freeScoData(scicos_block * block);
82 * Append the data to the current data
84 * \param block the block
88 static void appendData(scicos_block * block, double *x, double *y);
91 * Push the block data to the polyline
93 * \param block the block
94 * \param row the selected row
97 static BOOL pushData(scicos_block * block, int row);
99 /*****************************************************************************
101 ****************************************************************************/
104 * Get (and allocate on demand) the figure associated with the block
105 * \param block the block
106 * \return a valid figure UID or NULL on error
108 static int getFigure(scicos_block * block);
111 * Get (and allocate on demand) the axe associated with the input
113 * \param iFigureUID the parent figure UID
114 * \param block the block
115 * \param input the current input index (0-indexed)
116 * \return a valid axe UID or NULL on error
118 static int getAxe(int iFigureUID, scicos_block * block);
121 * Get (and allocate on demand) the arc associated with the row
123 * \param iAxeUID the parent axe UID
124 * \param block the block
125 * \param row the current row index (0-indexed)
126 * \return a valid polyline UID or NULL on error
128 static int getArc(int iAxeUID, scicos_block * block, int row);
133 * \param block the block
135 static BOOL setBounds(scicos_block * block);
137 /*****************************************************************************
138 * Simulation function
139 ****************************************************************************/
141 /** \fn void bouncexy(scicos_block * block,int flag)
142 \brief the computational function
143 \param block A pointer to a scicos_block
144 \param flag An int which indicates the state of the block (init, update, ending)
146 SCICOS_BLOCKS_IMPEXP void bouncexy(scicos_block * block, scicos_flag flag)
159 sco = getScoData(block);
164 iFigureUID = getFigure(block);
173 iFigureUID = getFigure(block);
181 appendData(block, (double *)block->inptr[0], (double *)block->inptr[1]);
182 for (j = 0; j < block->insz[0]; j++)
184 result = pushData(block, j);
187 Coserror("%s: unable to push some data.", "bouncexy");
202 /*-------------------------------------------------------------------------*/
204 /*****************************************************************************
206 * Container management
208 ****************************************************************************/
210 static sco_data *getScoData(scicos_block * block)
212 sco_data *sco = (sco_data *) * (block->work);
221 sco = (sco_data *) MALLOC(sizeof(sco_data));
224 goto error_handler_sco;
227 sco->internal.ballsSize = (double *)CALLOC(block->insz[0], sizeof(double));
228 if (sco->internal.ballsSize == NULL)
230 goto error_handler_ballsSize;
232 for (i = 0; i < block->insz[0]; i++)
234 sco->internal.ballsSize[i] = block->z[6 * i + 2];
237 sco->internal.data = (double **)CALLOC(block->insz[0], sizeof(double *));
238 if (sco->internal.data == NULL)
240 goto error_handler_data;
243 for (i = 0; i < block->insz[0]; i++)
245 sco->internal.data[i] = (double *)CALLOC(3, sizeof(double));
246 if (sco->internal.data[i] == NULL)
248 goto error_handler_data_i;
252 sco->scope.cachedFigureUID = 0;
253 sco->scope.cachedAxeUID = 0;
255 sco->scope.cachedArcsUIDs = (int*)CALLOC(block->insz[0], sizeof(int));
257 *(block->work) = sco;
263 * Error management (out of normal flow)
266 error_handler_data_i:
267 for (j = 0; j < i; j++)
269 FREE(sco->internal.data[i]);
271 FREE(sco->internal.data);
273 FREE(sco->internal.ballsSize);
274 error_handler_ballsSize:
282 static void freeScoData(scicos_block * block)
284 sco_data *sco = (sco_data *) * (block->work);
289 for (i = 0; i < block->insz[0]; i++)
291 FREE(sco->internal.data[i]);
294 FREE(sco->internal.data);
295 FREE(sco->internal.ballsSize);
296 FREE(sco->scope.cachedArcsUIDs);
299 *(block->work) = NULL;
303 static void appendData(scicos_block * block, double *x, double *y)
306 double *upperLeftPoint;
308 sco_data *sco = (sco_data *) * (block->work);
315 for (i = 0; i < block->insz[0]; i++)
317 upperLeftPoint = sco->internal.data[i];
318 ballSize = sco->internal.ballsSize[i];
320 upperLeftPoint[0] = x[i] - (ballSize / 2); // x
321 upperLeftPoint[1] = y[i] + (ballSize / 2); // y
322 upperLeftPoint[2] = 0; // z
327 static BOOL pushData(scicos_block * block, int row)
333 double *upperLeftPoint;
336 iFigureUID = getFigure(block);
337 iAxeUID = getAxe(iFigureUID, block);
338 iArcUID = getArc(iAxeUID, block, row);
340 sco = getScoData(block);
346 upperLeftPoint = sco->internal.data[row];
347 return setGraphicObjectProperty(iArcUID, __GO_UPPER_LEFT_POINT__, upperLeftPoint, jni_double_vector, 3);
350 /*****************************************************************************
354 ****************************************************************************/
356 /*****************************************************************************
360 ****************************************************************************/
362 static int getFigure(scicos_block * block)
370 sco_data *sco = (sco_data *) * (block->work);
372 // assert the sco is not NULL
378 // fast path for an existing object
379 if (sco->scope.cachedFigureUID)
381 return sco->scope.cachedFigureUID;
384 figNum = block->ipar[0];
386 // with a negative id, use the block number indexed from a constant.
389 figNum = 20000 + get_block_number();
392 iFigureUID = getFigureFromIndex(figNum);
396 iFigureUID = createNewFigureWithAxes();
397 setGraphicObjectProperty(iFigureUID, __GO_ID__, &figNum, jni_int, 1);
399 // the stored uid is a reference to the figure map, not to the current figure
400 iFigureUID = getFigureFromIndex(figNum);
401 sco->scope.cachedFigureUID = iFigureUID;
403 // allocate the axes through the getter
404 iAxe = getAxe(iFigureUID, block);
407 * Setup according to block settings
409 setGraphicObjectProperty(iAxe, __GO_BOX_TYPE__, &i__1, jni_int, 1);
410 setGraphicObjectProperty(iAxe, __GO_ISOVIEW__, &b_true, jni_bool, 1);
415 if (sco->scope.cachedFigureUID == 0)
417 sco->scope.cachedFigureUID = iFigureUID;
422 static int getAxe(int iFigureUID, scicos_block * block)
427 sco_data *sco = (sco_data *) * (block->work);
429 // assert the sco is not NULL
435 // fast path for an existing object
436 if (sco->scope.cachedAxeUID)
438 return sco->scope.cachedAxeUID;
441 iAxe = findChildWithKindAt(iFigureUID, __GO_AXES__, 0);
444 * Allocate if necessary
448 cloneAxesModel(iFigureUID);
449 iAxe = findChildWithKindAt(iFigureUID, __GO_AXES__, 0);
453 * Setup on first access
457 // allocate the polylines through the getter
458 for (i = 0; i < block->insz[0]; i++)
460 getArc(iAxe, block, i);
469 * then cache with local storage
471 sco->scope.cachedAxeUID = iAxe;
472 return sco->scope.cachedAxeUID;
475 static int getArc(int iAxeUID, scicos_block * block, int row)
477 static double d__0 = 0.0;
478 static double d__2PI = 2 * M_PI;
479 static BOOL b__true = TRUE;
484 sco_data *sco = (sco_data *) * (block->work);
486 // assert the sco is not NULL
487 if (sco == NULL || sco->scope.cachedArcsUIDs == NULL)
492 // fast path for an existing object
493 if (sco->scope.cachedArcsUIDs[row])
495 return sco->scope.cachedArcsUIDs[row];
498 iArc = findChildWithKindAt(iAxeUID, __GO_ARC__, row);
501 * Allocate if necessary
505 iArc = createGraphicObject(__GO_ARC__);
509 createDataObject(iArc, __GO_ARC__);
510 setGraphicObjectRelationship(iAxeUID, iArc);
519 * Setup on first access
521 setGraphicObjectProperty(iArc, __GO_START_ANGLE__, &d__0, jni_double, 1);
522 setGraphicObjectProperty(iArc, __GO_END_ANGLE__, &d__2PI, jni_double, 1);
524 color = block->ipar[2 + row];
525 setGraphicObjectProperty(iArc, __GO_BACKGROUND__, &color, jni_int, 1);
527 setGraphicObjectProperty(iArc, __GO_WIDTH__, &sco->internal.ballsSize[row], jni_double, 1);
528 setGraphicObjectProperty(iArc, __GO_HEIGHT__, &sco->internal.ballsSize[row], jni_double, 1);
530 setGraphicObjectProperty(iArc, __GO_FILL_MODE__, &b__true, jni_bool, 1);
533 int iClipState = 1; //on
534 setGraphicObjectProperty(iArc, __GO_CLIP_STATE__, &iClipState, jni_int, 1);
538 * then cache with local storage
540 sco->scope.cachedArcsUIDs[row] = iArc;
541 return sco->scope.cachedArcsUIDs[row];
544 static BOOL setBounds(scicos_block * block)
549 double dataBounds[6];
551 dataBounds[0] = block->rpar[0]; // xMin
552 dataBounds[1] = block->rpar[1]; // xMax
553 dataBounds[2] = block->rpar[2]; // yMin
554 dataBounds[3] = block->rpar[3]; // yMax
555 dataBounds[4] = -1.0; // zMin
556 dataBounds[5] = 1.0; // zMax
558 iFigureUID = getFigure(block);
559 iAxeUID = getAxe(iFigureUID, block);
561 return setGraphicObjectProperty(iAxeUID, __GO_DATA_BOUNDS__, dataBounds, jni_double_vector, 6);