1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 http://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 "vwstack.c" contient les procedures de gestion
33  * de la pile des points de vue (VieW STACK).
34  *
35  * Authors:
36  * Jean-Luc CORRE
37  *
38  *****************************************************************************/
39 
40 #include <visp3/core/vpConfig.h>
41 
42 #ifndef DOXYGEN_SHOULD_SKIP_THIS
43 
44 #include <cmath> // std::fabs()
45 #include <limits>
46 #include <stdarg.h>
47 #include <stdio.h>
48 #include <string.h>
49 
50 #include "vpArit.h"
51 #include "vpMy.h"
52 #include "vpView.h"
53 #include "vpVwstack.h"
54 
55 #define STACKSIZE 4
56 
57 static View_parameters stack[STACKSIZE] = {vpDEFAULT_VIEW};
58 static View_parameters *sp = stack;
59 
60 /*
61  * La procedure "fprintf_vwstack" affiche un parametre du sommet
62  * de la pile des prises de vue.
63  * Entree :
64  * fp		Fichier de sortie.
65  * argv		Argument a afficher.
66  *		Si argv est nul, tous les parametres sont affiches.
67  */
fprintf_vwstack(FILE * fp,char * argv)68 void fprintf_vwstack(FILE *fp, char *argv)
69 {
70   if (argv == NULL || strcmp(argv, "type") == 0) {
71     const char *typetoa;
72 
73     switch (sp->type) {
74     case PARALLEL:
75       typetoa = "parallel";
76       break;
77     case PERSPECTIVE:
78       typetoa = "perspective";
79       break;
80     default:
81       typetoa = "unknown";
82       break;
83     }
84     fprintf(fp, "(type\t%s)\n", typetoa);
85     if (argv != NULL)
86       return;
87   }
88   if (argv == NULL || strcmp(argv, "cop") == 0) {
89     fprintf(fp, "(cop\t%.3f\t%.3f\t%.3f)\n", sp->cop.x, sp->cop.y, sp->cop.z);
90     if (argv != NULL)
91       return;
92   }
93   if (argv == NULL || strcmp(argv, "vrp") == 0) {
94     fprintf(fp, "(vrp\t%.3f\t%.3f\t%.3f)\n", sp->vrp.x, sp->vrp.y, sp->vrp.z);
95     if (argv != NULL)
96       return;
97   }
98   if (argv == NULL || strcmp(argv, "vpn") == 0) {
99     fprintf(fp, "(vpn\t%.3f\t%.3f\t%.3f)\n", sp->vpn.x, sp->vpn.y, sp->vpn.z);
100     if (argv != NULL)
101       return;
102   }
103   if (argv == NULL || strcmp(argv, "vup") == 0) {
104     fprintf(fp, "(vup\t%.3f\t%.3f\t%.3f)\n", sp->vup.x, sp->vup.y, sp->vup.z);
105     if (argv != NULL)
106       return;
107   }
108   if (argv == NULL || strcmp(argv, "window") == 0) {
109     fprintf(fp, "(window\t%.3f\t%.3f\t%.3f\t%.3f)\n", sp->vwd.umin, sp->vwd.umax, sp->vwd.vmin, sp->vwd.vmax);
110     if (argv != NULL)
111       return;
112   }
113   if (argv == NULL || strcmp(argv, "depth") == 0) {
114     fprintf(fp, "(depth\t%.3f\t%.3f)\n", sp->depth.front, sp->depth.back);
115     if (argv != NULL)
116       return;
117   }
118   if (argv != NULL) {
119     static char proc_name[] = "fprintf_vwstack";
120     fprintf(stderr, "%s: argument unknown\n", proc_name);
121   }
122 }
123 
124 /*
125  * La procedure "get_vwstack" retourne le point de vue au sommet
126  * de la pile des points de vue.
127  * Sortie :
128  * 		Pointeur sur le point de vue du sommet de la pile.
129  */
get_vwstack(void)130 View_parameters *get_vwstack(void) { return (sp); }
131 
132 /*
133  * La procedure "load_vwstack" charge un point de vue au sommet
134  * de la pile des points de vue.
135  * Entree :
136  * vp		Point de vue a charger.
137  */
load_vwstack(View_parameters * vp)138 void load_vwstack(View_parameters *vp) { *sp = *vp; }
139 
140 /*
141  * La procedure "pop_vwstack" depile le point de vue au sommet
142  * de la pile des points de vue.
143  */
pop_vwstack(void)144 void pop_vwstack(void)
145 {
146   if (sp == stack) {
147     static char proc_name[] = "pop_vwstack";
148     fprintf(stderr, "%s: stack underflow\n", proc_name);
149     return;
150   } else
151     sp--;
152 }
153 
154 /*
155  * La procedure "push_vwstack" empile et duplique le point de vue au sommet
156  * de la pile des points de vue.
157  */
push_vwstack(void)158 void push_vwstack(void)
159 {
160   if (sp == stack + STACKSIZE - 1) {
161     static char proc_name[] = "push_vwstack";
162     fprintf(stderr, "%s: stack overflow\n", proc_name);
163     return;
164   }
165   sp++;
166   *sp = *(sp - 1);
167 }
168 
169 /*
170  * La procedure "swap_vwstack" echange les deux premiers elements
171  * de la pile des points de vue.
172  */
swap_vwstack(void)173 void swap_vwstack(void)
174 {
175   View_parameters *vp, tmp;
176 
177   vp = (sp == stack) ? sp + 1 : sp - 1;
178   SWAP(*sp, *vp, tmp);
179 }
180 
181 /*
182  * La procedure "add_vwstack" modifie un agrument du point de vue au sommet
183  * de la pile des points de vue.
184  * Entree :
185  * va_alist	Nom de l'argument a modifier suivi de ses parametres.
186  */
187 
add_vwstack(const char * path,...)188 void add_vwstack(const char *path, ...)
189 // add_vwstack (va_alist)
190 // va_dcl
191 {
192   va_list ap;
193   char *argv;
194 
195   va_start(ap, path);
196   argv = va_arg(ap, char *);
197   if (strcmp(argv, "cop") == 0) {
198     /* initialise le centre de projection	*/
199     SET_COORD3(sp->cop, (float)va_arg(ap, double), (float)va_arg(ap, double), (float)va_arg(ap, double));
200   } else if (strcmp(argv, "depth") == 0) {
201     /* initialise les distances des plans de decoupage	*/
202     sp->depth.front = (float)va_arg(ap, double);
203     sp->depth.back = (float)va_arg(ap, double);
204   } else if (strcmp(argv, "type") == 0) {
205     /* initialise le type de projection	*/
206     sp->type = (Type)va_arg(ap, int);
207   } else if (strcmp(argv, "vpn") == 0) {
208     /* initialise le vecteur normal au plan	*/
209     float x = (float)va_arg(ap, double);
210     float y = (float)va_arg(ap, double);
211     float z = (float)va_arg(ap, double);
212 
213     // if (x == 0 && y == 0 && z == 0)
214     if (std::fabs(x) <= std::numeric_limits<double>::epsilon() &&
215         std::fabs(y) <= std::numeric_limits<double>::epsilon() &&
216         std::fabs(z) <= std::numeric_limits<double>::epsilon()) {
217       static char proc_name[] = "add_vwstack";
218       fprintf(stderr, "%s: bad vpn\n", proc_name);
219     } else {
220       SET_COORD3(sp->vpn, x, y, z);
221     }
222   } else if (strcmp(argv, "vrp") == 0) {
223     /* initialise le vecteur de reference	*/
224     SET_COORD3(sp->vrp, (float)va_arg(ap, double), (float)va_arg(ap, double), (float)va_arg(ap, double));
225   } else if (strcmp(argv, "vup") == 0) {
226     /* initialise le vecteur haut du plan	*/
227     float x = (float)va_arg(ap, double);
228     float y = (float)va_arg(ap, double);
229     float z = (float)va_arg(ap, double);
230 
231     // if (x == 0 && y == 0 && z == 0)
232     if (std::fabs(x) <= std::numeric_limits<double>::epsilon() &&
233         std::fabs(y) <= std::numeric_limits<double>::epsilon() &&
234         std::fabs(z) <= std::numeric_limits<double>::epsilon()) {
235       static char proc_name[] = "add_vwstack";
236       fprintf(stderr, "%s: bad vup\n", proc_name);
237     } else {
238       SET_COORD3(sp->vup, x, y, z);
239     }
240   } else if (strcmp(argv, "window") == 0) {
241     /* initialise la fenetre de projection	*/
242     sp->vwd.umin = (float)va_arg(ap, double);
243     sp->vwd.umax = (float)va_arg(ap, double);
244     sp->vwd.vmin = (float)va_arg(ap, double);
245     sp->vwd.vmax = (float)va_arg(ap, double);
246   } else {
247     static char proc_name[] = "add_vwstack";
248     fprintf(stderr, "%s: bad argument\n", proc_name);
249   }
250   va_end(ap);
251 }
252 
253 #endif
254