Fix crash on Scicos exiting when simulation was stoped and some scope closed
[scilab.git] / scilab / modules / scicos_blocks / src / c / cmat3d.c
1 /*  Scicos
2 *
3 *  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * See the file ./license.txt
20 */
21 /**
22    \file cmat3d.c
23    \author Benoit Bayol
24    \version 1.0
25    \date September 2006 - January 2007
26    \brief CMAT3D is a scope which connect a matrix to a plot3d. Values of the matrix are the values at the nodes.
27    \see CMAT3D.sci in macros/scicos_blocks/Sinks/
28 */
29 #include "CurrentObjectsManagement.h"
30 #include "DrawingBridge.h"
31 #include "scoMemoryScope.h"
32 #include "scoWindowScope.h"
33 #include "scoMisc.h"
34 #include "scoGetProperty.h"
35 #include "scoSetProperty.h"
36 #include "scicos_block4.h"
37
38 /** \fn cmat3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
39     \brief Function to draw or redraw the window
40 */
41 void cmat3d_draw(scicos_block * block, ScopeMemory ** pScopeMemory, int firstdraw)
42 {
43   /*Declarations*/
44   int i; //As usual
45   int * ipar; //Integer Parameters
46   int win_pos[2]; //Position of the Window
47   int win_dim[2]; //Dimension of the Window
48   int dimension = 3;
49   double * rpar; //Reals parameters
50   double  ymin, ymax; //Ymin and Ymax are vectors here
51   double  xmin, xmax;
52   double zmin, zmax;
53   int number_of_curves_by_subwin;
54   int number_of_subwin;
55   double * mat;
56   int size_mat;
57   int size_in_x;
58   int size_in_y;
59   scoGraphicalObject pShortDraw;
60
61   /*Retrieve parameters from the scicos_model() which has been created thanks to the interfacing function*/
62   rpar = GetRparPtrs(block);
63   ipar = GetIparPtrs(block);
64
65   number_of_subwin = 1;
66
67   win_pos[0] = -1;
68   win_pos[1] = -1;
69   win_dim[0] = -1;
70   win_dim[1] = -1;
71
72   size_mat = ipar[2];
73   mat = (double*)scicos_malloc(size_mat*sizeof(double));
74   for(i = 0 ; i < size_mat ; i++)
75     {
76       mat[i] = rpar[i];
77     }
78   size_in_x = GetInPortSize(block,1,1);
79   size_in_y = GetInPortSize(block,1,2);
80   if(ipar[3] == 1)
81     {
82       xmax = size_in_x;
83       xmin = 0;
84       ymax = size_in_y;
85       ymin = 0;
86     }
87   else
88     {
89       xmin = rpar[size_mat];
90       xmax = rpar[size_mat+1];
91       ymin = rpar[size_mat+2];
92       ymax = rpar[size_mat+3];
93     }
94
95   zmin = ipar[0];
96   zmax = ipar[1];
97   number_of_curves_by_subwin = 1;
98
99   /*Allocating memory for scope only if the window has to be created and not redraw*/
100   if(firstdraw == 1)
101     {
102       scoInitScopeMemory(block->work,pScopeMemory, number_of_subwin, &number_of_curves_by_subwin);
103     }
104
105   /*Creating the Scope with axes*/
106   scoInitOfWindow(*pScopeMemory, dimension, -1, win_pos, win_dim, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax);
107   if(scoGetScopeActivation(*pScopeMemory) == 1)
108     {
109       /*Here we put the special window feature like pixmap or text title
110         Dont forget that the function scoAddTitleScope redraws the window at end so it would be a good idea to put it at the end*/
111       //sciSetPixmapMode(scoGetPointerScopeWindow(*pScopeMemory),TRUE);
112       //pFIGURE_FEATURE(scoGetPointerScopeWindow(*pScopeMemory))->pixmapMode = 1;
113
114       sciSetColormap(scoGetPointerScopeWindow(*pScopeMemory), mat , size_mat/3, 3);
115
116       pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->alpha = 50;
117       pSUBWIN_FEATURE(scoGetPointerAxes(*pScopeMemory,0))->theta = 280;
118   
119       /*Adding graphic elements like plot3d or polyline and so*/
120       if(ipar[3] == 1)
121         {
122           scoAddPlot3dForShortDraw(*pScopeMemory,0,0,GetInPortSize(block,1,1),GetInPortSize(block,1,2));
123         }
124       else
125         {
126           double h_x,h_y;
127           scoAddPlot3dForShortDraw(*pScopeMemory,0,0,GetInPortSize(block,1,1),GetInPortSize(block,1,2));
128           pShortDraw = scoGetPointerShortDraw(*pScopeMemory,0,0);
129           h_x = fabs((xmax-xmin)/(GetInPortSize(block,1,1)-1));
130           h_y = fabs((ymax-ymin)/(GetInPortSize(block,1,2)-1));
131       
132           for(i = 0 ; i < size_in_x ; i++)
133             {
134               pSURFACE_FEATURE(pShortDraw)->pvecx[i] = xmin + i*h_x;
135             } 
136           for(i = 0 ; i < size_in_y ; i++)
137             {
138               pSURFACE_FEATURE(pShortDraw)->pvecy[i] = ymin + i*h_y;
139             } 
140         }
141       scoAddTitlesScope(*pScopeMemory,"x","y","z");
142     }
143   /*Dont forget to free your scicos_malloc or MALLOC*/
144   scicos_free(mat);
145
146 }
147
148 /** \fn void cmat3d(scicos_block * block, int flag)
149     \brief the computational function
150     \param block A pointer to a scicos_block
151     \param flag An int which indicates the state of the block (init, update, ending)
152 */
153 void cmat3d(scicos_block * block, int flag)
154 {
155   /* Declarations */
156   ScopeMemory * pScopeMemory;
157   scoGraphicalObject pShortDraw;
158   double * u1;
159   int i,j;
160   int dim_i, dim_j;
161  
162   /* State Machine Control */
163   switch(flag)
164     {
165       /*Flag 4*/
166     case Initialization:
167       {
168         /*We create the window for the first time, so 1 is in parameters*/
169         cmat3d_draw(block,&pScopeMemory,1);
170         break; //dont forget the break
171       }
172       /*Flag 2*/
173     case StateUpdate:
174       {
175         /*Retreiving Scope in the block->work*/
176         scoRetrieveScopeMemory(block->work,&pScopeMemory);
177         if(scoGetScopeActivation(pScopeMemory) == 1)
178           {
179
180             /* If window has been destroyed we recreate it */
181             if(scoGetPointerScopeWindow(pScopeMemory) == NULL)
182               {
183                 //0 here because of the recreation
184                 cmat3d_draw(block,&pScopeMemory,0);
185               }
186             /*Here some allocations and calcul wich are necessary*/
187             pShortDraw = scoGetPointerShortDraw(pScopeMemory,0,0);
188
189             u1 = GetInPortPtrs(block,1);
190             dim_i = GetInPortRows(block,1);
191             dim_j = GetInPortCols(block,1);
192
193             for(i = 0 ; i < dim_i ; i++)
194               {
195             
196                 for(j = 0; j < dim_j ; j++)
197                   {
198                     pSURFACE_FEATURE(pShortDraw)->pvecz[j+i*dim_j] = u1[j+dim_j*i];
199                   }
200               }
201         
202             /*Here is the draw instructions*/
203             sciSetUsedWindow(scoGetWindowID(pScopeMemory));
204             if(sciGetPixmapMode(scoGetPointerScopeWindow(pScopeMemory)))
205               {
206                           /* TODO : not implemented */
207                           /*C2F(dr)("xset","wshow",PI0,PI0,PI0,PI0,PI0,PI0,PD0,PD0,PD0,PD0,0L,0L);*/
208               }
209             forceRedraw(pShortDraw);
210             sciDrawObj(scoGetPointerScopeWindow(pScopeMemory));
211           }
212         break; //dont forget the break
213       }
214       /*Flag 5*/
215     case Ending:
216       {
217         /*Retrieve Memory*/
218         scoRetrieveScopeMemory(block->work, &pScopeMemory);
219         /*Here we can add specific instructions to be sure that we have stick short and longdraw if we need it. Cscope for example stick the last short to the long to have one curve to move*/
220         /*Free Memory*/
221         if(scoGetScopeActivation(pScopeMemory) == 1)
222           {
223             /*sciSetUsedWindow(scoGetWindowID(pScopeMemory));
224             pShortDraw = sciGetCurrentFigure();
225             pFIGURE_FEATURE(pShortDraw)->user_data = NULL;
226             pFIGURE_FEATURE(pShortDraw)->size_of_user_data = 0;*/
227                         /* Check if figure is still opened, otherwise, don't try to destroy it again. */
228                         scoGraphicalObject figure = scoGetPointerScopeWindow(pScopeMemory);
229                         if (figure != NULL)
230                         {
231                                 /*pShortDraw = scoGetPointerScopeWindow(pScopeMemory);*/
232                                 clearUserData(figure);
233                         }
234           }
235         scoFreeScopeMemory(block->work, &pScopeMemory);
236         break;
237       }
238     }
239 }