1 /*****************************************************************************
2 FILE : $Source: /projects/higgs1/SNNS/CVS/SNNS/xgui/sources/d3_main.c,v $
3 SHORTNAME : main.c
4 SNNS VERSION : 4.2
5
6 PURPOSE : contains the main routine to draw the net
7 NOTES :
8
9 AUTHOR : Ralf Huebner
10 DATE : 1.12.1991
11
12 CHANGED BY : Niels Mache
13 RCS VERSION : $Revision: 2.13 $
14 LAST CHANGE : $Date: 1998/03/13 16:31:48 $
15
16 Copyright (c) 1990-1995 SNNS Group, IPVR, Univ. Stuttgart, FRG
17 Copyright (c) 1996-1998 SNNS Group, WSI, Univ. Tuebingen, FRG
18
19 ******************************************************************************/
20 #include <config.h>
21
22
23 #include <math.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <ctype.h>
28
29 #include <X11/Xlib.h>
30
31 #include "ui.h"
32
33 #include "glob_typ.h" /* Kernel constant and type definitions */
34 #include "d3_global.h"
35 #include "d3_draw.h"
36 #include "d3_anageo.h"
37 #include "d3_graph.h"
38 #include "d3_fonts.h"
39 #include "d3_point.h"
40
41 #include "kr_ui.h" /* Kernel interface functions */
42
43 #include "d3_zgraph.h"
44 #include "ui_setup.h"
45 #include "ui_color.h"
46
47 #include "d3_main.ph"
48
49
50 /*****************************************************************************
51 FUNCTION : d3_getColorValue
52
53 PURPOSE : get the value of an unit for a selected mode
54 RETURNS : -1.0 <= value <= 1.0
55 NOTES :
56
57 UPDATE :
58 ******************************************************************************/
d3_getColorValue(int mode,int unitNo,float * value)59 void d3_getColorValue (int mode, int unitNo, float *value)
60
61 {
62 switch (mode) {
63 case activation_on : *value = krui_getUnitActivation (unitNo);
64 break;
65 case init_act_on : *value = krui_getUnitInitialActivation (unitNo);
66 break;
67 case output_on : *value = krui_getUnitOutput (unitNo);
68 break;
69 case bias_on : *value = krui_getUnitBias (unitNo);
70 break;
71 default : *value = krui_getUnitActivation (unitNo);
72 break;
73 }
74 if (*value > 1.0)
75 *value = 1.0;
76 if (*value < -1.0)
77 *value = -1.0;
78 }
79
80
81 /*****************************************************************************
82 FUNCTION : get_unit_pos_vector
83
84 PURPOSE : calculates the 3d vector form the 2d representation
85 RETURNS : the vector
86 NOTES : this is the only interface to get a 3d vector
87
88 UPDATE :
89 ******************************************************************************/
get_unit_pos_vector(int unit,vector v)90 static void get_unit_pos_vector (int unit, vector v)
91
92 {
93 struct PosType unit_pos;
94 int x, y;
95
96 krui_getUnitPosition (unit, &unit_pos);
97 krui_xyTransTable( OP_TRANSTABLE_GET, &x, &y, unit_pos.z );
98
99 v[0]= (unit_pos.x - x) * grid_size;
100 v[1] = (unit_pos.y - y) * grid_size;
101
102 v[2] = unit_pos.z * grid_size;
103 v[3] = 1.0;
104 }
105
106
107 /*****************************************************************************
108 FUNCTION : unit_transformation
109
110 PURPOSE : multipies a matrix with an unit cube
111 RETURNS : the transformed cube
112 NOTES :
113
114 UPDATE :
115 ******************************************************************************/
unit_transformation(cube c,matrix m)116 static void unit_transformation (cube c, matrix m)
117
118 {
119 int i;
120
121 for (i=0; i<ANZ_VECS; i++)
122 d3_multMatrixVector (c[i], m, d3_e_cube[i]);
123 }
124
125
126 /*****************************************************************************
127 FUNCTION : get_net_extrema
128
129 PURPOSE : calculates the dimensions of a net
130 RETURNS : two vectors containing the minimum and the maximum of the net
131 NOTES :
132
133 UPDATE :
134 ******************************************************************************/
get_net_extrema(vector min,vector max)135 static void get_net_extrema (vector min, vector max)
136
137 {
138 vector p;
139 int act_unit, i;
140
141 act_unit = krui_getFirstUnit ();
142 if (act_unit != 0)
143 {
144 get_unit_pos_vector (act_unit, min);
145 get_unit_pos_vector (act_unit, max);
146 act_unit = krui_getNextUnit ();
147 while (act_unit != 0)
148 {
149 get_unit_pos_vector (act_unit, p);
150 for (i=0; i<3; i++)
151 {
152 if (p[i] < min[i])
153 min[i] = p[i];
154 if (p[i] > max[i])
155 max[i] = p[i];
156 }
157 act_unit = krui_getNextUnit ();
158 }
159 }
160 }
161
162
163 /*****************************************************************************
164 FUNCTION : insert_center_vector
165
166 PURPOSE : stores the center of a cube
167 RETURNS : void
168 NOTES :
169
170 UPDATE :
171 ******************************************************************************/
insert_center_vector(cube c,int unit)172 static void insert_center_vector (cube c, int unit)
173
174 {
175 struct PositionVector pv;
176
177 pv.x = c[CENTER_VECTOR][0];
178 pv.y = c[CENTER_VECTOR][1];
179 pv.z = c[CENTER_VECTOR][2];
180 krui_setUnitCenters (unit, d3_currentDisplay, &pv);
181 }
182
183
184 /*****************************************************************************
185 FUNCTION : get_size_vector
186
187 PURPOSE : get the value of an unit to calculate the size
188 RETURNS : a vector containing the size
189 NOTES : only positive values are returned
190
191 UPDATE :
192 ******************************************************************************/
get_size_vector(vector v,int unitNo)193 static bool get_size_vector (vector v, int unitNo)
194
195 {
196 float value;
197
198 switch (d3_state.unit_mode.size)
199 {
200 case activation_on : value = krui_getUnitActivation (unitNo);
201 break;
202 case init_act_on : value = krui_getUnitInitialActivation(unitNo);
203 break;
204 case output_on : value = krui_getUnitOutput(unitNo);
205 break;
206 case bias_on : value = krui_getUnitBias(unitNo);
207 break;
208 case nothing_on : value = 1.0;
209 break;
210 default : value = 1.0;
211 }
212 if (value > 1.0)
213 value = 1.0;
214 v[0] = v[1] = v[2] = value;
215 return (value >= 0.1);
216 }
217
218
219 /*****************************************************************************
220 FUNCTION : get_label_string
221
222 PURPOSE : gets the label for an unit
223 RETURNS : the string
224 NOTES :
225
226 UPDATE :
227 ******************************************************************************/
get_label_string(int label,int unitNo)228 static char *get_label_string (int label, int unitNo)
229
230 {
231 char *fmt_string = "%.3f", *str;
232 struct PosType pos;
233
234 str = malloc (255);
235 switch (label) {
236 case activation_on : sprintf (str, fmt_string,
237 krui_getUnitActivation (unitNo));
238 break;
239 case init_act_on : sprintf (str, fmt_string,
240 krui_getUnitInitialActivation (unitNo));
241 break;
242 case output_on : sprintf (str, fmt_string,
243 krui_getUnitOutput (unitNo));
244 break;
245 case bias_on : sprintf (str, fmt_string,
246 krui_getUnitBias (unitNo));
247 break;
248 case number_on : sprintf (str, "%d", unitNo);
249 break;
250 case zvalue_on : krui_getUnitPosition (unitNo, &pos);
251 sprintf (str, "%d", pos.z);
252 break;
253 case name_on : sprintf (str, "%s", krui_getUnitName(unitNo));
254 if (str == NULL)
255 sprintf (str, " ");
256 break;
257 default : sprintf (str, "%s", "nothing");
258 break;
259 }
260 return (str);
261
262 }
263
264
265 /*****************************************************************************
266 FUNCTION : d3_labelUnit
267
268 PURPOSE : draws a string at the specified vertex of a cube
269 RETURNS : void
270 NOTES :
271
272 UPDATE :
273 ******************************************************************************/
d3_labelUnit(cube c,int unitNo,int vert,int label,bool toplabel_flag)274 static void d3_labelUnit (cube c, int unitNo, int vert, int label,
275 bool toplabel_flag)
276
277 {
278 int x, y;
279 float z;
280 char *label_string;
281
282 x = c[vert][0];
283 y = c[vert][1];
284 z = c[vert][2];
285 if (toplabel_flag)
286 y = y - d3_fontYsize;
287 label_string = get_label_string (label, unitNo);
288 d3_draw_string (x, y, z, label_string);
289 }
290
291
292 /*****************************************************************************
293 FUNCTION : get_vert_index
294
295 PURPOSE : calculates the neatest vertex for a given vector
296 RETURNS : the index in the vertex structure
297 NOTES :
298
299 UPDATE :
300 ******************************************************************************/
get_vert_index(cube c,vector corner)301 static int get_vert_index (cube c, vector corner)
302
303 {
304 cube vert_diff;
305 float length, vert_len;
306 int index, i, j;
307
308 for (i=0; i<8; i++) {
309 for (j=0; j<3; j++) {
310 vert_diff[i][j] = corner[j] - c[i][j];
311 }
312 }
313 length = vert_diff[0][0]*vert_diff[0][0] + vert_diff[0][1]*vert_diff[0][1] +
314 vert_diff[0][2]*vert_diff[0][2];
315 index = 0;
316 for (i=1; i<8; i++) {
317 vert_len = vert_diff[i][0]*vert_diff[i][0] +
318 vert_diff[i][1]*vert_diff[i][1] +
319 vert_diff[i][2]*vert_diff[i][2];
320 if (vert_len < length) {
321 length = vert_len;
322 index = i;
323 }
324 }
325 return (index);
326 }
327
328
329 /*****************************************************************************
330 FUNCTION : get_label_vert_indices
331
332 PURPOSE : gets the vertex indices of the upper right and the lower right
333 vertex for a given rotation
334 RETURNS : the two indices
335 NOTES :
336
337 UPDATE :
338 ******************************************************************************/
get_label_vert_indices(vector rot_vec,int * top_index,int * bott_index)339 static void get_label_vert_indices (vector rot_vec, int *top_index,
340 int *bott_index)
341
342 {
343 static vector upper_corner = {0.0, -0.5, -0.5, 1.0};
344 static vector lower_corner = {0.0, 0.5, -0.5, 1.0};
345 cube c;
346
347 d3_rotateCube (c, rot_vec, d3_e_cube);
348 *top_index = get_vert_index (c, upper_corner);
349 *bott_index = get_vert_index (c, lower_corner);
350 }
351
352
353 /*****************************************************************************
354 FUNCTION : calc_transformed_cube
355
356 PURPOSE : multplies all matices for the viewing pipeline
357 RETURNS : the transformed cube
358 NOTES :
359
360 UPDATE :
361 ******************************************************************************/
calc_transformed_cube(matrix unit_trans_mat,matrix world_center_mat,matrix unit_scale_mat,matrix unit_activ_mat,matrix world_scale_mat,matrix world_trans_mat,vector viewpoint,cube transformed_cube)362 static void calc_transformed_cube (matrix unit_trans_mat,
363 matrix world_center_mat,
364 matrix unit_scale_mat,
365 matrix unit_activ_mat,
366 matrix world_scale_mat,
367 matrix world_trans_mat,
368 vector viewpoint, cube transformed_cube)
369
370 {
371 matrix trans_mat, scale_mat, unit_mat, world_mat, global_mat;
372 cube c1, c2;
373 int i,j;
374
375 for(i=0;i<4;i++)
376 for(j=0;j<ANZ_VECS;j++)
377 c1[j][i] = c2[j][i] = transformed_cube[j][i] = 0.0;
378
379
380 d3_multMatrix (trans_mat, world_center_mat, unit_trans_mat);
381 d3_multMatrix (scale_mat, unit_activ_mat, unit_scale_mat);
382 d3_multMatrix (unit_mat, trans_mat, scale_mat);
383 d3_multMatrix (world_mat, world_trans_mat, world_scale_mat);
384 d3_multMatrix (global_mat, world_mat, unit_mat);
385
386 unit_transformation (c1, global_mat);
387
388 d3_rotateCube (c2, d3_state.rot_vec, c1);
389
390 d3_shiftCube (transformed_cube, c2, trans_x, trans_y);
391 if (d3_state.projection_mode == central)
392 d3_projection (transformed_cube, viewpoint, transformed_cube);
393 }
394
395
396 /*****************************************************************************
397 FUNCTION : draw_units
398
399 PURPOSE : draw all units of the net
400 RETURNS : void
401 NOTES : the centers of the the units are stored
402
403 UPDATE :
404 ******************************************************************************/
draw_units(void)405 static void draw_units (void)
406
407 {
408 cube transformed_cube;
409 vector min, max, center, p, unit_scale, activ_vec, vp, lp;
410 matrix world_center_mat, world_scale_mat, world_trans_mat;
411 matrix unit_scale_mat, unit_trans_mat, unit_activ_mat;
412 int act_unit, i, top_vert_index, bott_vert_index, do_draw;
413
414 d3_shiftVector (vp, d3_state.viewpoint, trans_x, trans_y);
415 d3_shiftVector (lp, d3_state.light.position, trans_x, trans_y);
416
417 get_net_extrema (min, max);
418 for (i=0; i<3; i++)
419 center[i] = -(max[i] - min[i]) / 2.0 - min[i];
420 center[3] = 1.0;
421 d3_transMatrix (world_center_mat, center);
422 unit_scale[0] = unit_scale[1] = unit_scale[2] = grid_size *
423 d3_state.unit_aspect;
424 d3_scaleMatrix (unit_scale_mat, unit_scale);
425 d3_scaleMatrix (world_scale_mat, d3_state.scale_vec);
426 d3_transMatrix (world_trans_mat, d3_state.trans_vec);
427
428 get_label_vert_indices(d3_state.rot_vec, &top_vert_index, &bott_vert_index);
429
430 act_unit = krui_getFirstUnit ();
431 while (act_unit != 0) {
432 get_unit_pos_vector (act_unit, p);
433 d3_transMatrix (unit_trans_mat, p);
434 do_draw = get_size_vector (activ_vec, act_unit);
435 d3_scaleMatrix (unit_activ_mat, activ_vec);
436 calc_transformed_cube (unit_trans_mat, world_center_mat,
437 unit_scale_mat,
438 unit_activ_mat, world_scale_mat,
439 world_trans_mat, vp, transformed_cube);
440 insert_center_vector (transformed_cube, act_unit);
441 if (do_draw) {
442 if (d3_state.model_mode == wire_frame)
443 d3_draw_wireframeCube (transformed_cube);
444 else {
445
446 d3_draw_solidCube (transformed_cube, vp, lp, act_unit);
447 }
448 if (d3_state.unit_mode.top_label != nothing_on)
449 d3_labelUnit (transformed_cube, act_unit, top_vert_index,
450 d3_state.unit_mode.top_label, TRUE);
451 if (d3_state.unit_mode.bottom_label != nothing_on)
452 d3_labelUnit (transformed_cube, act_unit, bott_vert_index,
453 d3_state.unit_mode.bottom_label, FALSE);
454 }
455 act_unit = krui_getNextUnit ();
456 }
457 }
458
459
460 /*****************************************************************************
461 FUNCTION : d3_labelLink
462
463 PURPOSE : draws the weight of a link
464 RETURNS : void
465 NOTES :
466
467 UPDATE :
468 ******************************************************************************/
d3_labelLink(vector v1,vector v2,float * weight)469 static void d3_labelLink (vector v1, vector v2, float *weight)
470
471 {
472 char string[40];
473 int dx, dy;
474 float dz;
475
476 dx = floor (v1[0] + (v2[0] - v1[0]) / 2);
477 dy = floor (v1[1] + (v2[1] - v1[1]) / 2);
478 dz = v1[2] + (v2[2] - v1[2]) / 2;
479 sprintf (string, "%.3f", *weight);
480 d3_setBlackColor ();
481 d3_draw_string (dx, dy, dz, string);
482 d3_setColor (linkColor);
483 }
484
485
486 /*****************************************************************************
487 FUNCTION : draw_links
488
489 PURPOSE : draws all links of the net
490 RETURNS : void
491 NOTES :
492
493 UPDATE : 8.3.93 Link Trigger
494 ******************************************************************************/
draw_links(void)495 static void draw_links (void)
496
497 {
498 int act_unit, pred_unit;
499 FlintType str; /* old style: FlintType *str */
500 struct PositionVector *start_vec, *end_vec;
501 vector v1, v2;
502
503 if (d3_state.model_mode == solid) {
504 d3_setColor (linkColor);
505 if (d3_state.color_mode == mono_mode) {
506 d3_setBlackColor ();
507 d3_intens = 0.0;
508 }
509 } else {
510 d3_setBlackColor ();
511 d3_intens = 0.0;
512 }
513
514 act_unit = krui_getFirstUnit ();
515 while (act_unit != 0) {
516 pred_unit = krui_getFirstPredUnit (&str);
517 while (pred_unit != 0) {
518 krui_getUnitCenters (act_unit, d3_currentDisplay, &start_vec);
519 krui_getUnitCenters (pred_unit, d3_currentDisplay, &end_vec);
520 v1[0] = start_vec->x;
521 v1[1] = start_vec->y;
522 v1[2] = start_vec->z;
523 v1[3] = 0.0;
524 v2[0] = end_vec->x;
525 v2[1] = end_vec->y;
526 v2[2] = end_vec->z;
527 v2[3] = 0.0;
528
529 if ((str >= d3_state.pos_link_trigger)
530 OR (str <= -d3_state.neg_link_trigger)) {
531 if (d3_state.model_mode == wire_frame)
532 d3_draw_wireframeLine (v1, v2);
533 else {
534 if ((d3_state.link_mode == links_color) &&
535 (d3_state.color_mode == rgb_mode))
536 d3_setLinkColor (&str);
537 if (d3_state.color_mode == mono_mode)
538 d3_setBlackColor ();
539 d3_draw_solidLine (v1, v2);
540 }
541 if (d3_state.link_mode == links_label)
542 d3_labelLink (v1, v2, &str);
543 }
544 pred_unit = krui_getNextPredUnit (&str);
545 }
546 act_unit = krui_getNextUnit ();
547 }
548 if (d3_state.model_mode == solid)
549 d3_flushPixels ();
550 }
551
552
553 /*****************************************************************************
554 FUNCTION : d3_drawNet
555
556 PURPOSE : draws the whole net
557 RETURNS : void
558 NOTES : this routine is called by every redraw request
559
560 UPDATE :
561 ******************************************************************************/
d3_drawNet(void)562 void d3_drawNet (void)
563
564 {
565 if (d3_freeze)
566 return;
567 if (d3_displayIsReady) {
568 if (d3_state.model_mode == solid)
569 d3_clearZbuffer ();
570 else
571 d3_setBlackColor ();
572 d3_clearDisplay (); /* old style: d3_clearDispaly */
573 draw_units ();
574 if (d3_state.link_mode != links_off)
575 draw_links ();
576 }
577
578 }
579
580
581 /*****************************************************************************
582 FUNCTION : d3_recenter_window
583
584 PURPOSE : calculate the new dimensions if the window is resized by the user
585 RETURNS : new dimension values
586 NOTES : called by the X-Event Handler
587
588 UPDATE :
589 ******************************************************************************/
d3_recenter_window(int width,int height)590 void d3_recenter_window (int width, int height)
591
592 {
593 if ((width != d3_displayXsize) || (height != d3_displayYsize)) {
594 d3_displayXsize = width;
595 d3_displayYsize = height;
596 trans_x = width / 2;
597 trans_y = height / 2;
598 d3_setClipWindow (0, 0, d3_displayXsize, d3_displayYsize);
599 }
600 }
601
602
603 /*****************************************************************************
604 FUNCTION : d3_resetDisplay
605
606 PURPOSE : set all translations, scalings and rotations to zero
607 RETURNS : void
608 NOTES :
609
610 UPDATE :
611 ******************************************************************************/
d3_resetDisplay(void)612 void d3_resetDisplay (void)
613
614 {
615 int i;
616
617 if (d3_freeze)
618 return;
619 for (i=0; i<3; i++)
620 {
621 d3_state.scale_vec [i] = 1.0;
622 d3_state.trans_vec [i] = 0.0;
623 d3_state.rot_vec [i] = 0.0;
624 }
625 d3_drawNet ();
626 }
627
628
629 /*****************************************************************************
630 FUNCTION : d3_clear_xyTranslationTable
631
632 PURPOSE : clears the Translation Table for the 2d -> 3d mapping
633 RETURNS : the cleared Table
634 NOTES :
635
636 UPDATE :
637 ******************************************************************************/
d3_clear_xyTranslationTable(void)638 void d3_clear_xyTranslationTable (void)
639
640 {
641 krui_xyTransTable( OP_TRANSTABLE_CLEAR, NULL, NULL, 0 );
642 }
643
644
645 /*****************************************************************************
646 FUNCTION : d3_init_main
647
648 PURPOSE : this is the initialization for the Translation Table, the Fonts,
649 the color, and the dimensions
650 RETURNS : void
651 NOTES : only called one time by ui_init
652
653 UPDATE :
654 ******************************************************************************/
d3_init_main(void)655 void d3_init_main (void)
656 {
657 trans_x = d3_displayXsize / 2.0;
658 trans_y = d3_displayYsize / 2.0;
659
660 d3_setClipWindow (0, 0, d3_displayXsize, d3_displayYsize);
661
662 if (ui_col_monochromeMode)
663 d3_state.color_mode = mono_mode;
664 else
665 d3_state.color_mode = rgb_mode;
666
667 d3_select_font (fnt8x14);
668 d3_get_font_size (&d3_fontXsize, &d3_fontYsize);
669 }
670 /* end of file */
671
672