Update ChangeLog
[gss-tcad.git] / src / graphic / plot3d.cc
blob5b3ecfeaaaf3e032c515202fe69c47cc5e735013
1 /*****************************************************************************/
2 /* 8888888 88888888 88888888 */
3 /* 8 8 8 */
4 /* 8 8 8 */
5 /* 8 88888888 88888888 */
6 /* 8 8888 8 8 */
7 /* 8 8 8 8 */
8 /* 888888 888888888 888888888 */
9 /* */
10 /* A Two-Dimensional General Purpose Semiconductor Simulator. */
11 /* */
12 /* GSS 0.4x */
13 /* Last update: Dec 31, 2007 */
14 /* */
15 /* Gong Ding */
16 /* gdiso@ustc.edu */
17 /* NINT, No.69 P.O.Box, Xi'an City, China */
18 /* */
19 /*****************************************************************************/
21 #include "config.h"
22 #if (defined(HAVE_WIN32) || defined(HAVE_X11))
24 #include "bsolver.h"
25 #include "xgraph.h"
26 #include "wgraph.h"
27 #include "grafix3d.h"
28 #include "log.h"
30 static PlotDefine *plotdef;
31 static TriPlot3D* triplot;
32 static BSolver * bsolver;
34 inline double FunLinear(PetscScalar value)
36 return value;
39 inline double FunSignedLog10(PetscScalar value)
41 return dsign(value)*log10(1.0+fabs(value));
44 void TitleEtc ( PlotDefine &plot, int x1, int y1, int ResFactor )
46 char txt[64];
47 int ix;
48 int iy = int(CHARPIXELHIGH * ResFactor * 1.2);
50 if (plot.Resolution == RES_640x480) ix = 56;
51 else if (plot.Resolution == RES_1024x768) ix = 64;
52 else if (plot.Resolution == RES_800x600) ix = 96;
53 //set the unit for each variable
54 string unit;
55 switch(plot.Variable)
57 case DopingNd:
58 case DopingNa:
59 case Doping:
60 case ElecDensity:
61 case HoleDensity:
62 unit = "(cm^-3)"; break;
63 case ElecTemp:
64 case HoleTemp:
65 case Temperature:
66 unit = "(K)"; break;
67 case Potential:
68 case Phi_Intrinsic:
69 case PhiP:
70 case PhiN:
71 unit = "(V)"; break;
72 case EFieldX:
73 case EFieldY:
74 case OpticalEx:
75 case OpticalEy:
76 case OpticalEz:
77 unit = "(V/cm)"; break;
78 case QuantumEc:
79 case QuantumEv:
80 unit = "(eV)"; break;
81 case OpticalG:
82 unit = "(cm^-3 s^-1)"; break;
83 case OpticalHx:
84 case OpticalHy:
85 case OpticalHz:
86 unit = "(A/cm)"; break;
89 x1 += 4 * ResFactor * CHARPIXELWIDE;
90 y1 *= ResFactor;
91 sprintf(txt, "GSS 3D graphic output");
92 GRText(ix + x1, y1 += iy, txt);
93 sprintf(txt, "Variable : %s %s",plot.VariableName.c_str(),unit.c_str());
94 GRText(ix + x1, y1 += iy, txt);
95 sprintf(txt, "AZ = %e, EL = %e",plot.az, plot.el);
96 GRText(ix + x1, y1 += iy, txt);
98 #ifdef HAVE_X11
99 sprintf(txt, "Press ESC to exit");
100 GRText(ix + x1, y1 += iy, txt);
101 #endif
104 void Redraw3D()
106 triplot->PlotGrid();
107 triplot->PlotMesh();
108 triplot->PlotData(TRUE, TRUE);
109 TitleEtc(*plotdef,0, 5, 1);
113 /*-----------------------------------------------------------------------
114 * Function: BSolver::plot_data
115 * Scope: Public
116 * Description: This function draws 3D data and mesh on the screen
118 void BSolver::plot_data(PlotDefine &plot)
120 int MAXx,MAXy;
121 int x,y; //location of pointer
122 int x_old,y_old; //last location of pointer
123 AINODE *aainode=0,*painode=0;
124 PNT3D *apnt3dInput=0;
125 int nodes=0,triangles=0;
126 int daz=10,del=5;
127 double (*Measure) (PetscScalar);
128 plotdef = &plot;
130 if(plot.Measure==Linear)
131 Measure = FunLinear;
132 if(plot.Measure==SignedLog)
133 Measure = FunSignedLog10;
135 //data for semiconductor zone only
136 if(plot.Variable==Doping||plot.Variable==DopingNd||plot.Variable==DopingNa||
137 plot.Variable==ElecDensity||plot.Variable==HoleDensity||
138 plot.Variable==ElecTemp||plot.Variable==HoleTemp||
139 plot.Variable==PhiP||plot.Variable==PhiN||plot.Variable==Phi_Intrinsic||
140 plot.Variable==QuantumEc||plot.Variable==QuantumEv||
141 plot.Variable==OpticalG)
143 for(int z=0;z<zone_num;z++)
144 if(zonedata[z]->material_type == Semiconductor)
146 nodes += zone[z].danode.size();
147 triangles += zone[z].datri.size();
149 aainode = new AINODE[triangles];
150 apnt3dInput = new PNT3D[nodes];
151 painode=aainode;
152 int offset = 0;
153 for(int z=0;z<zone_num;z++)
155 if(zonedata[z]->material_type == Semiconductor)
157 SMCZone *pzonedata = dynamic_cast<SMCZone *>(zonedata[z]);
158 for(int i=0;i<zone[z].datri.size();i++)
160 (*painode)[0] = zone[z].datri[i].node[0] + offset;
161 (*painode)[1] = zone[z].datri[i].node[1] + offset;
162 (*painode)[2] = zone[z].datri[i].node[2] + offset;
163 (*painode)[3] = -1u;
165 painode++;
168 for(int j=0;j<zone[z].danode.size();j++)
170 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
171 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
172 switch(plot.Variable)
174 case DopingNd:
175 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Nd*pow(scale_unit.s_centimeter,3));break;
176 case DopingNa:
177 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Na*pow(scale_unit.s_centimeter,3));break;
178 case Doping:
179 apnt3dInput[j+offset].z = Measure((pzonedata->aux[j].Nd-pzonedata->aux[j].Na)*pow(scale_unit.s_centimeter,3));break;
180 case ElecDensity:
181 apnt3dInput[j+offset].z = Measure(fabs(pzonedata->fs[j].n)*pow(scale_unit.s_centimeter,3));break;
182 case HoleDensity:
183 apnt3dInput[j+offset].z = Measure(fabs(pzonedata->fs[j].p)*pow(scale_unit.s_centimeter,3));break;
184 case ElecTemp:
185 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].Tn/scale_unit.s_kelvin);break;
186 case HoleTemp:
187 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].Tp/scale_unit.s_kelvin);break;
188 case Phi_Intrinsic:
189 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].phi_intrinsic/scale_unit.s_volt);break;
190 case PhiP:
191 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].phip/scale_unit.s_volt);break;
192 case PhiN:
193 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].phin/scale_unit.s_volt);break;
194 case QuantumEc:
195 apnt3dInput[j+offset].z = Measure((pzonedata->fs[j].Eqc+pzonedata->fs[j].P+pzonedata->aux[j].affinity)/scale_unit.s_volt);break;
196 case QuantumEv:
197 apnt3dInput[j+offset].z = Measure((pzonedata->fs[j].Eqv+pzonedata->fs[j].P+pzonedata->aux[j].affinity+pzonedata->aux[j].Eg)/scale_unit.s_volt); break;
198 case OpticalG:
199 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OptG*pow(scale_unit.s_centimeter,3)*scale_unit.s_second); break;
202 offset+=zone[z].danode.size();
207 // data for semiconductor zone, insulator zone and electrode zone
208 if(plot.Variable==Potential||plot.Variable==EFieldX||plot.Variable==EFieldY||plot.Variable==Temperature)
210 for(int z=0;z<zone_num;z++)
212 if(zonedata[z]->material_type == Semiconductor ||
213 zonedata[z]->material_type == Insulator ||
214 zonedata[z]->material_type == Conductor)
216 nodes += zone[z].danode.size();
217 triangles += zone[z].datri.size();
220 aainode = new AINODE[triangles];
221 apnt3dInput = new PNT3D[nodes];
222 painode=aainode;
223 int offset = 0;
224 for(int z=0;z<zone_num;z++)
226 if(zonedata[z]->material_type == Semiconductor ||
227 zonedata[z]->material_type == Insulator ||
228 zonedata[z]->material_type == Conductor)
230 for(int i=0;i<zone[z].datri.size();i++)
232 (*painode)[0] = zone[z].datri[i].node[0] + offset;
233 (*painode)[1] = zone[z].datri[i].node[1] + offset;
234 (*painode)[2] = zone[z].datri[i].node[2] + offset;
235 (*painode)[3] = -1u;
236 painode++;
239 if(zonedata[z]->material_type == Semiconductor)
241 SMCZone *pzonedata = dynamic_cast<SMCZone *> (zonedata[z]);
242 for(int j=0;j<zone[z].danode.size();j++)
244 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
245 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
246 switch(plot.Variable)
248 case Potential:
249 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].P/scale_unit.s_volt);break;
250 case EFieldX:
251 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ex/scale_unit.s_volt*scale_unit.s_centimeter);break;
252 case EFieldY:
253 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ey/scale_unit.s_volt*scale_unit.s_centimeter);break;
254 case Temperature:
255 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].T/scale_unit.s_kelvin);break;
260 if(zonedata[z]->material_type == Insulator)
262 ISZone *pzonedata = dynamic_cast<ISZone *> (zonedata[z]);
263 for(int j=0;j<zone[z].danode.size();j++)
265 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
266 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
267 switch(plot.Variable)
269 case Potential:
270 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].P/scale_unit.s_volt);break;
271 case EFieldX:
272 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ex/scale_unit.s_volt*scale_unit.s_centimeter);break;
273 case EFieldY:
274 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ey/scale_unit.s_volt*scale_unit.s_centimeter);break;
275 case Temperature:
276 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].T/scale_unit.s_kelvin);break;
281 if(zonedata[z]->material_type == Conductor)
283 ElZone *pzonedata = dynamic_cast<ElZone *> (zonedata[z]);
284 for(int j=0;j<zone[z].danode.size();j++)
286 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
287 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
288 switch(plot.Variable)
290 case Potential:
291 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].P/scale_unit.s_volt);break;
292 case EFieldX:
293 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ex/scale_unit.s_volt*scale_unit.s_centimeter);break;
294 case EFieldY:
295 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].Ey/scale_unit.s_volt*scale_unit.s_centimeter);break;
296 case Temperature:
297 apnt3dInput[j+offset].z = Measure(pzonedata->fs[j].T/scale_unit.s_kelvin);break;
301 offset += zone[z].danode.size();
306 // data for all zones
307 if(plot.Variable==OpticalEx||plot.Variable==OpticalEy||plot.Variable==OpticalEz||plot.Variable==OpticalHx||
308 plot.Variable==OpticalHy||plot.Variable==OpticalHz)
310 for(int z=0;z<zone_num;z++)
312 if(zonedata[z]->material_type == Semiconductor ||
313 zonedata[z]->material_type == Insulator||
314 zonedata[z]->material_type == Conductor||
315 zonedata[z]->material_type == Vacuum||
316 zonedata[z]->material_type == PML)
318 nodes += zone[z].danode.size();
319 triangles += zone[z].datri.size();
322 aainode = new AINODE[triangles];
323 apnt3dInput = new PNT3D[nodes];
324 painode=aainode;
325 int offset = 0;
326 for(int z=0;z<zone_num;z++)
328 if(zonedata[z]->material_type == Semiconductor || zonedata[z]->material_type == Insulator||
329 zonedata[z]->material_type==Conductor||zonedata[z]->material_type==Vacuum||zonedata[z]->material_type==PML)
331 for(int i=0;i<zone[z].datri.size();i++)
333 (*painode)[0] = zone[z].datri[i].node[0] + offset;
334 (*painode)[1] = zone[z].datri[i].node[1] + offset;
335 (*painode)[2] = zone[z].datri[i].node[2] + offset;
336 (*painode)[3] = -1u;
337 painode++;
340 if(zonedata[z]->material_type == Semiconductor)
342 SMCZone *pzonedata = dynamic_cast<SMCZone *> (zonedata[z]);
343 for(int j=0;j<zone[z].danode.size();j++)
345 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
346 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
347 switch(plot.Variable)
349 case OpticalEx://The scale parameter can be found in phy_scale.cc```
350 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEx/scale_unit.s_volt*scale_unit.s_centimeter);break;
351 case OpticalEy:
352 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEy/scale_unit.s_volt*scale_unit.s_centimeter);break;
353 case OpticalEz:
354 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEz/scale_unit.s_volt*scale_unit.s_centimeter);break;
355 case OpticalHx:
356 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHx/scale_unit.s_A*scale_unit.s_centimeter);break;
357 case OpticalHy:
358 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHy/scale_unit.s_A*scale_unit.s_centimeter);break;
359 case OpticalHz:
360 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHz/scale_unit.s_A*scale_unit.s_centimeter);break;
365 if(zonedata[z]->material_type == Insulator)
367 ISZone *pzonedata = dynamic_cast<ISZone *> (zonedata[z]);
368 for(int j=0;j<zone[z].danode.size();j++)
370 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
371 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
372 switch(plot.Variable)
374 case OpticalEx://The scale parameter can be found in phy_scale.cc```
375 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEx/scale_unit.s_volt*scale_unit.s_centimeter);break;
376 case OpticalEy:
377 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEy/scale_unit.s_volt*scale_unit.s_centimeter);break;
378 case OpticalEz:
379 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEz/scale_unit.s_volt*scale_unit.s_centimeter);break;
380 case OpticalHx:
381 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHx/scale_unit.s_A*scale_unit.s_centimeter);break;
382 case OpticalHy:
383 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHy/scale_unit.s_A*scale_unit.s_centimeter);break;
384 case OpticalHz:
385 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHz/scale_unit.s_A*scale_unit.s_centimeter);break;
389 if(zonedata[z]->material_type==Conductor)
391 ElZone *pzonedata = dynamic_cast<ElZone *> (zonedata[z]);
392 for(int j=0;j<zone[z].danode.size();j++)
394 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
395 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
396 switch(plot.Variable)
398 case OpticalEx://The scale parameter can be found in phy_scale.cc```
399 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEx/scale_unit.s_volt*scale_unit.s_centimeter);break;
400 case OpticalEy:
401 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEy/scale_unit.s_volt*scale_unit.s_centimeter);break;
402 case OpticalEz:
403 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEz/scale_unit.s_volt*scale_unit.s_centimeter);break;
404 case OpticalHx:
405 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHx/scale_unit.s_A*scale_unit.s_centimeter);break;
406 case OpticalHy:
407 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHy/scale_unit.s_A*scale_unit.s_centimeter);break;
408 case OpticalHz:
409 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHz/scale_unit.s_A*scale_unit.s_centimeter);break;
413 if(zonedata[z]->material_type==Vacuum)
415 VacuumZone *pzonedata = dynamic_cast<VacuumZone *> (zonedata[z]);
416 for(int j=0;j<zone[z].danode.size();j++)
418 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
419 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
420 switch(plot.Variable)
422 case OpticalEx://The scale parameter can be found in phy_scale.cc```
423 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEx/scale_unit.s_volt*scale_unit.s_centimeter);break;
424 case OpticalEy:
425 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEy/scale_unit.s_volt*scale_unit.s_centimeter);break;
426 case OpticalEz:
427 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEz/scale_unit.s_volt*scale_unit.s_centimeter);break;
428 case OpticalHx:
429 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHx/scale_unit.s_A*scale_unit.s_centimeter);break;
430 case OpticalHy:
431 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHy/scale_unit.s_A*scale_unit.s_centimeter);break;
432 case OpticalHz:
433 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHz/scale_unit.s_A*scale_unit.s_centimeter);break;
437 if(zonedata[z]->material_type==PML)
439 PMLZone *pzonedata = dynamic_cast<PMLZone *> (zonedata[z]);
440 for(int j=0;j<zone[z].danode.size();j++)
442 apnt3dInput[j+offset].x = zone[z].danode[j].x*1e4/scale_unit.s_centimeter;
443 apnt3dInput[j+offset].y = zone[z].danode[j].y*1e4/scale_unit.s_centimeter;
444 switch(plot.Variable)
446 case OpticalEx://The scale parameter can be found in phy_scale.cc```
447 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEx/scale_unit.s_volt*scale_unit.s_centimeter);break;
448 case OpticalEy:
449 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEy/scale_unit.s_volt*scale_unit.s_centimeter);break;
450 case OpticalEz:
451 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpEz/scale_unit.s_volt*scale_unit.s_centimeter);break;
452 case OpticalHx:
453 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHx/scale_unit.s_A*scale_unit.s_centimeter);break;
454 case OpticalHy:
455 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHy/scale_unit.s_A*scale_unit.s_centimeter);break;
456 case OpticalHz:
457 apnt3dInput[j+offset].z = Measure(pzonedata->aux[j].OpHz/scale_unit.s_A*scale_unit.s_centimeter);break;
461 offset += zone[z].danode.size();
466 if(plot.Resolution == RES_640x480)
467 {MAXx = 640; MAXy = 480;}
468 else if(plot.Resolution == RES_1024x768)
469 {MAXx = 1024; MAXy = 768;}
470 else if(plot.Resolution == RES_800x600)
471 {MAXx = 800; MAXy = 600;}
473 triplot = new TriPlot3D(triangles, nodes,
474 aainode, apnt3dInput,
475 plot.az, plot.el,
476 plot.Resolution, plot.Style,
477 50, -1, 0,
478 plot.Measure==SignedLog);
480 #ifdef HAVE_X11
481 GROpenGraphWin("3D Surface Plot", "Plot", 0, 0, MAXx, MAXy, NULL);
482 int fDone = FALSE;
483 short int keycode;
484 int arg1, arg2;
485 while (!fDone)
487 switch(getevent(&keycode, &arg1, &arg2,&x,&y))
489 case EXPOSE:
490 triplot->PlotGrid();
491 triplot->PlotMesh();
492 triplot->PlotData(TRUE, TRUE);
493 TitleEtc(plot,0, 5, 1);
494 flushdisplay();
495 break;
497 case CONFIGURENOTIFY:
498 break;
499 case BUTTONPRESS:
500 x_old=x;
501 y_old=y;
502 case BUTTONRELEASE:
503 break;
504 case BUTTONMOTION:
505 daz = isign(x_old-x)*int(sqrt(fabs((x_old-x)/1.0)));
506 del = isign(y_old-y)*int(sqrt(fabs((y_old-y)/1.0)));
507 GRClearGraphWin();
508 triplot->GetViewAspect(plot.az+=daz, plot.el+=del);
509 triplot->Xform3DData(); // Transform the data 3D->3D
510 triplot->Xform2DData(); // Transform the data 3D->2D
511 triplot->DeterminePlotOrder(); // Sort the order of appearance
512 triplot->PlotGrid();
513 triplot->PlotMesh();
514 triplot->PlotData(TRUE, TRUE);
515 TitleEtc(plot,0, 5, 1);
516 flushdisplay();
517 break;
518 case KEYPRESS:
519 if(keycode == ESCAPE) fDone = 1;
520 break;
523 if(plot.GenerateTIFF)
525 gss_log.string_buf()<<"Saving Screen to TIFF File "<<plot.TIFFFileName<<"...";
526 gss_log.record();
527 if(GRSaveScreen (plot.TIFFFileName.c_str(), MAXx, MAXy))
529 gss_log.string_buf()<<"Open TIFF File failed."<<endl;
530 gss_log.record();
532 else
534 gss_log.string_buf()<<"ok"<<endl;
535 gss_log.record();
538 GRFreeGraphics();
539 #endif
541 #ifdef HAVE_WIN32
542 GROpenGraphWin("3D Surface Plot", "Plot", 0, 0, MAXx, MAXy, Redraw3D);
543 #endif
546 if (plot.GeneratePS)
548 gss_log.string_buf()<<"Saving Screen to PS File "<<plot.PSFileName<<"...";
549 gss_log.record();
550 triplot->nResFactor = 20;
551 triplot->cx = 468 * triplot->nResFactor;
552 triplot->cy = 468 * triplot->nResFactor;
553 triplot->cxLBorder = 72 * triplot->nResFactor;
554 triplot->cyLBorder = 162 * triplot->nResFactor;
555 triplot->Xform2DData();
556 if(GRPrintOpen(plot.PSFileName.c_str(), triplot->nResFactor))
558 gss_log.string_buf()<<"Open PS File failed."<<endl;
559 gss_log.record();
561 else
563 triplot->PlotGrid();
564 triplot->PlotMesh();
565 triplot->PlotData(TRUE, TRUE);
566 TitleEtc(plot, 0, 15, triplot->nResFactor);
567 GRPrintClose();
568 gss_log.string_buf()<<"ok"<<endl;
569 gss_log.record();
573 delete triplot;
574 delete [] apnt3dInput;
575 delete [] aainode;
579 #endif