ViSP
vpCoreDisplay.cpp
1 /****************************************************************************
2  *
3  * $Id: vpCoreDisplay.cpp 5294 2015-02-10 09:41:38Z fspindle $
4  *
5 * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  * Description:
34  * Le module "display.c" contient les procedures de d'affichage
35  * des scenes de modele geometrique surfacique.
36  *
37  * Authors:
38  * Jean-Luc CORRE
39  *
40  *****************************************************************************/
41 
42 
43 
44 
45 #include <visp/vpConfig.h>
46 
47 #ifndef DOXYGEN_SHOULD_SKIP_THIS
48 #include <stdio.h>
49 #include <stdlib.h>
50 /*
51 #include <suntool/sunview.h>
52 */
53 #ifdef suncgi
54 #include "cgidefs.h"
55 #endif /* suncgi */
56 
57 #include <visp/vpMy.h>
58 #include <visp/vpArit.h>
59 //#include "graph.h"
60 
61 #include <visp/vpBound.h>
62 #include <visp/vpView.h>
63 #include <visp/vpImstack.h>
64 #include <visp/vpRfstack.h>
65 #include <visp/vpVwstack.h>
66 
67 
68 /*
69  * POINT2I :
70  * Tableau de points 2D dans l'espace ecran servant a l'affichage fil-de-fer.
71  *
72  * RENAME :
73  * Tableau de renommage des sommets ou tableau de compteurs associes aux points.
74  */
75 Point2i *point2i = (Point2i *) NULL;
76 Point2i *listpoint2i = (Point2i *) NULL;
77 static int *rename_jlc = (int *) NULL;
78 
79 
80 /*
81  * La procedure "open_display" alloue et initialise les variables utilisees
82  * par le mode "display".
83  */
84 void open_display (void)
85 {
86  static char proc_name[] = "open_display";
87 
88  if ((point2i = (Point2i *) malloc (POINT_NBR*sizeof (Point2i))) == NULL
89  || (listpoint2i = (Point2i *) malloc (50*sizeof (Point2i))) == NULL
90  || (rename_jlc = (int *) malloc (POINT_NBR * sizeof (int))) == NULL)
91  {
92  perror (proc_name);
93  exit (1);
94  }
95 }
96 
97 /*
98  * La procedure "close_display" libere les variables utilisees par le mode
99  * "display".
100  */
101 void close_display (void)
102 {
103  free ((char *) point2i);
104  free ((char *) listpoint2i);
105  free ((char *) rename_jlc);
106  point2i = (Point2i *) NULL;
107  listpoint2i = (Point2i *) NULL;
108  rename_jlc = (int *) NULL;
109 }
110 
111 /*
112  * La procedure "point_3D_2D" projette les points 3D du volume canonique
113  * dans l'espace image 2D.
114  *
115  * Volume canonique Espace image
116  * ________________ ____________
117  *
118  * - 1 < X < 1 0 < X < xsize
119  * - 1 < Y < 1 0 < Y < ysize
120  * 0 < Z < 1
121  *
122  * Z < 0 X = 0, Y = -1 non significatifs.
123  *
124  * Entree :
125  * p3 Tableau de points 3D a projeter.
126  * size Taille du tableau de points "p3".
127  * xsize, ysize Tailles de l'espace image.
128  * p2 Tableau de points 2D en sortie.
129  */
130 // static
131 void point_3D_2D (Point3f *p3, Index size, int xsize, int ysize, Point2i *p2)
132 {
133  Point3f *pend = p3 + size; /* borne de p3 */
134  float xdiv2 = ((float) xsize) / (float)2.0;
135  float ydiv2 = ((float) ysize) / (float)2.0;
136 
137  for (; p3 < pend; p3++, p2++) {
138  p2->x = (int) ((1.0 + p3->x) * xdiv2);
139  p2->y = (int) ((1.0 - p3->y) * ydiv2);
140  }
141 }
142 
143 /*
144  * La procedure "set_Bound_face_display" marque les faces affichables
145  * de la surface "bp".
146  * Soit la face comportant le contour oriente suivant : (...,P2,P0,P1...).
147  * La normale a la face au point P0 est obtenue par le produit vectoriel :
148  *
149  * | x1 - x0 x2 - x0 | | Nx |
150  * N = (P1 - P0) ^ (P2 - P0) = | y1 - y0 y2 - y0 | = | Ny |
151  * | z1 - z0 z2 - z0 | | Nz |
152  *
153  * La face est dans le volume canonique de vision et dans un repere gauche.
154  * L'observateur est situe a l'infini dans la direction [0, 0, -1].
155  * IS_ABOVE <=> Ny < 0, IS_BELOW <=> Ny > 0.
156  * IS_RIGHT <=> Nx < 0, IS_LEFT <=> Nx > 0.
157  * IS_BACK <=> Nz < 0, IS_FRONT <=> Nz > 0.
158  * Entree :
159  * bp Surface a initialiser.
160  * b Drapeaux indiquant les faces non affichables.
161  */
162 void set_Bound_face_display (Bound *bp, Byte b)
163 {
164  Face *fp = bp->face.ptr;
165  Face *fend = fp + bp->face.nbr;
166  Point3f *pp = bp->point.ptr;
167 
168  for (; fp < fend; fp++) {
169  Index *vp;
170  Point3f *p0; /* premier sommet */
171  Point3f *p1; /* second sommet */
172  Point3f *p2; /* dernier sommet */
173 
174  fp->is_visible = TRUE;
175  if (b == IS_INSIDE) continue;
176  vp = fp->vertex.ptr;
177  p0 = pp + *vp;
178  p1 = pp + *(vp + 1);
179  p2 = pp + *(vp + fp->vertex.nbr - 1);
180  if (b & IS_ABOVE) {
181  fp->is_visible = ((p1->z - p0->z) * (p2->x - p0->x)
182  >= (p1->x - p0->x) * (p2->z - p0->z));
183  }
184  if (! fp->is_visible) continue;
185  if (b & IS_BELOW) {
186  fp->is_visible = ((p1->z - p0->z) * (p2->x - p0->x)
187  <= (p1->x - p0->x) * (p2->z - p0->z));
188  }
189  if (! fp->is_visible) continue;
190  if (b & IS_RIGHT) {
191  fp->is_visible = ((p1->y - p0->y) * (p2->z - p0->z)
192  >= (p1->z - p0->z) * (p2->y - p0->y));
193  }
194  if (! fp->is_visible) continue;
195  if (b & IS_LEFT) {
196  fp->is_visible = ((p1->y - p0->y) * (p2->z - p0->z)
197  <= (p1->z - p0->z) * (p2->y - p0->y));
198  }
199  if (! fp->is_visible) continue;
200  if (b & IS_BACK) {
201  fp->is_visible = ((p1->x - p0->x) * (p2->y - p0->y)
202  >= (p1->y - p0->y) * (p2->x - p0->x));
203  }
204  if (! fp->is_visible) continue;
205  if (b & IS_FRONT) {
206  fp->is_visible = ((p1->x - p0->x) * (p2->y - p0->y)
207  <= (p1->y - p0->y) * (p2->x - p0->x));
208  }
209  }
210 }
211 
212 
213 /*
214  * La procedure "wireframe_Face" affiche une face "fp" en "fil de fer".
215  * sur la fenetre graphique de "suncgi" sur "SUN".
216  * Les points des sommets de la face sont contenu dans les points "pp"
217  * de la surface contenant la face.
218  * Entree :
219  * fp face a afficher.
220  * pp Points de la surface contenant la face.
221  */
222 void wireframe_Face (Face *fp, Point2i *pp)
223 {
224 // extern Window id_window;
225 
226  Index *vp = fp->vertex.ptr;
227  Index *vend = vp + fp->vertex.nbr;
228  Point2i *cp = listpoint2i;
229 
230  if (fp->vertex.nbr < 2) return;
231  if (fp->vertex.nbr > 50)
232  {
233  printf("pb malloc listpoint2i (display.c)\n"); return;
234  }
235  for (; vp < vend; vp++, cp++) {
236  SET_COORD2(*cp, pp[*vp].x, pp[*vp].y);
237  }
238 }
239 
240 #endif