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