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