Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
vpScene.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  *
33  * Authors:
34  * Jean-Luc CORRE
35  *
36 *****************************************************************************/
37 
38 #include <visp3/core/vpConfig.h>
39 
40 #ifndef DOXYGEN_SHOULD_SKIP_THIS
41 
42 #include <cmath>
43 #include <limits>
44 
45 #include "vpKeyword.h"
46 #include "vpLex.h"
47 #include "vpParser.h"
48 #include "vpScene.h"
49 
50 #include <visp3/core/vpException.h>
51 #include <visp3/core/vpPoint.h>
52 
53 BEGIN_VISP_NAMESPACE
54 /*
55  Get the extension of the file and return it
56 */
57 Model_3D getExtension(const char *file)
58 {
59  std::string sfilename(file);
60 
61  size_t bnd = sfilename.find("bnd");
62  size_t BND = sfilename.find("BND");
63  size_t wrl = sfilename.find("wrl");
64  size_t WRL = sfilename.find("WRL");
65 
66  size_t size = sfilename.size();
67 
68  if ((bnd > 0 && bnd < size) || (BND > 0 && BND < size))
69  return BND_MODEL;
70  else if ((wrl > 0 && wrl < size) || (WRL > 0 && WRL < size)) {
71 #if defined(VISP_HAVE_COIN3D)
72  return WRL_MODEL;
73 #else
74  std::cout << "Coin not installed, cannot read VRML files" << std::endl;
75  throw std::string("Coin not installed, cannot read VRML files");
76 #endif
77  }
78  return UNKNOWN_MODEL;
79 }
80 
81 /*
82  Enable to initialize the scene
83 */
84 void set_scene(const char *str, Bound_scene *sc, float factor)
85 {
86  FILE *fd;
87 
88  // if ((fd = fopen (str, 0)) == -1)
89  if ((fd = fopen(str, "r")) == NULL) {
90  std::string error = "The file " + std::string(str) + " can not be opened";
91 
92  throw(vpException(vpException::ioError, error.c_str()));
93  }
94  open_keyword(keyword_tbl);
95  open_lex();
96  open_source(fd, str);
97  malloc_Bound_scene(sc, str, (Index)BOUND_NBR);
98  parser(sc);
99 
100  // if (factor != 1)
101  if (std::fabs(factor) > std::numeric_limits<double>::epsilon()) {
102  for (int i = 0; i < sc->bound.nbr; i++) {
103  for (int j = 0; j < sc->bound.ptr[i].point.nbr; j++) {
104  sc->bound.ptr[i].point.ptr[j].x = sc->bound.ptr[i].point.ptr[j].x * factor;
105  sc->bound.ptr[i].point.ptr[j].y = sc->bound.ptr[i].point.ptr[j].y * factor;
106  sc->bound.ptr[i].point.ptr[j].z = sc->bound.ptr[i].point.ptr[j].z * factor;
107  }
108  }
109  }
110 
111  close_source();
112  close_lex();
113  close_keyword();
114  fclose(fd);
115 }
116 
117 #if defined(VISP_HAVE_COIN3D)
118 
119 void set_scene_wrl(const char *str, Bound_scene *sc, float factor)
120 {
121  // Load the sceneGraph
122  SoDB::init();
123  SoInput in;
124  SbBool ok = in.openFile(str);
125  SoVRMLGroup *sceneGraphVRML2;
126 
127  if (!ok) {
128  throw(vpException(vpException::fatalError, "Can't open file \"%s\". Please check the Marker_Less.ini file", str));
129  }
130 
131  if (!in.isFileVRML2()) {
132  SoSeparator *sceneGraph = SoDB::readAll(&in);
133  if (sceneGraph == NULL) { /*return -1;*/
134  }
135  sceneGraph->ref();
136 
137  SoToVRML2Action tovrml2;
138  tovrml2.apply(sceneGraph);
139  sceneGraphVRML2 = tovrml2.getVRML2SceneGraph();
140  sceneGraphVRML2->ref();
141  sceneGraph->unref();
142  }
143  else {
144  sceneGraphVRML2 = SoDB::readAllVRML(&in);
145  if (sceneGraphVRML2 == NULL) {
146  /*return -1;*/
147  throw(vpException(vpException::notInitialized, "Cannot read VRML file"));
148  }
149  sceneGraphVRML2->ref();
150  }
151 
152  in.closeFile();
153 
154  int nbShapes = sceneGraphVRML2->getNumChildren();
155 
156  SoNode *child;
157 
158  malloc_Bound_scene(sc, str, (Index)BOUND_NBR);
159 
160  int iterShapes = 0;
161  for (int i = 0; i < nbShapes; i++) {
162  child = sceneGraphVRML2->getChild(i);
163  if (child->getTypeId() == SoVRMLShape::getClassTypeId()) {
164  int nbFaces = 0;
165  std::list<indexFaceSet *> ifs_list;
166  SoChildList *child2list = child->getChildren();
167  for (int j = 0; j < child2list->getLength(); j++) {
168  if (((SoNode *)child2list->get(j))->getTypeId() == SoVRMLIndexedFaceSet::getClassTypeId()) {
169  indexFaceSet *ifs = new indexFaceSet;
170  SoVRMLIndexedFaceSet *face_set;
171  face_set = (SoVRMLIndexedFaceSet *)child2list->get(j);
172  extractFaces(face_set, ifs);
173  ifs_list.push_back(ifs);
174  nbFaces++;
175  }
176  // if (((SoNode*)child2list->get(j))->getTypeId() ==
177  // SoVRMLIndexedLineSet::getClassTypeId())
178  // {
179  // std::cout << "> We found a line" << std::endl;
180  // SoVRMLIndexedLineSet * line_set;
181  // line_set = (SoVRMLIndexedLineSet*)child2list->get(j);
182  // extractLines(line_set);
183  // }
184  }
185  sc->bound.nbr++;
186  ifsToBound(&(sc->bound.ptr[iterShapes]), ifs_list);
187  destroyIfs(ifs_list);
188  iterShapes++;
189  }
190  }
191 
192  // if (factor != 1)
193  if (std::fabs(factor) > std::numeric_limits<double>::epsilon()) {
194  for (int i = 0; i < sc->bound.nbr; i++) {
195  for (int j = 0; j < sc->bound.ptr[i].point.nbr; j++) {
196  sc->bound.ptr[i].point.ptr[j].x = sc->bound.ptr[i].point.ptr[j].x * factor;
197  sc->bound.ptr[i].point.ptr[j].y = sc->bound.ptr[i].point.ptr[j].y * factor;
198  sc->bound.ptr[i].point.ptr[j].z = sc->bound.ptr[i].point.ptr[j].z * factor;
199  }
200  }
201  }
202 }
203 
204 void extractFaces(SoVRMLIndexedFaceSet *face_set, indexFaceSet *ifs)
205 {
206  // vpList<vpPoint> pointList;
207  // pointList.kill();
208  SoVRMLCoordinate *coord = (SoVRMLCoordinate *)(face_set->coord.getValue());
209  int coordSize = coord->point.getNum();
210 
211  ifs->nbPt = coordSize;
212  for (int i = 0; i < coordSize; i++) {
213  SbVec3f point(0, 0, 0);
214  point[0] = coord->point[i].getValue()[0];
215  point[1] = coord->point[i].getValue()[1];
216  point[2] = coord->point[i].getValue()[2];
217  vpPoint pt(point[0], point[1], point[2]);
218  ifs->pt.push_back(pt);
219  }
220 
221  SoMFInt32 indexList = face_set->coordIndex;
222  int indexListSize = indexList.getNum();
223 
224  ifs->nbIndex = indexListSize;
225  for (int i = 0; i < indexListSize; i++) {
226  int index = face_set->coordIndex[i];
227  ifs->index.push_back(index);
228  }
229 }
230 
231 void ifsToBound(Bound *bptr, std::list<indexFaceSet *> &ifs_list)
232 {
233  int nbPt = 0;
234  for (std::list<indexFaceSet *>::const_iterator it = ifs_list.begin(); it != ifs_list.end(); ++it) {
235  nbPt += (*it)->nbPt;
236  }
237  bptr->point.nbr = (Index)nbPt;
238  bptr->point.ptr = (Point3f *)malloc((unsigned int)nbPt * sizeof(Point3f));
239 
240  unsigned int iter = 0;
241  for (std::list<indexFaceSet *>::const_iterator it = ifs_list.begin(); it != ifs_list.end(); ++it) {
242  indexFaceSet *ifs = *it;
243  for (unsigned int j = 0; j < (unsigned int)ifs->nbPt; j++) {
244  bptr->point.ptr[iter].x = (float)ifs->pt[j].get_oX();
245  bptr->point.ptr[iter].y = (float)ifs->pt[j].get_oY();
246  bptr->point.ptr[iter].z = (float)ifs->pt[j].get_oZ();
247  iter++;
248  }
249  }
250 
251  unsigned int nbFace = 0;
252  std::list<int> indSize;
253  int indice = 0;
254  for (std::list<indexFaceSet *>::const_iterator it = ifs_list.begin(); it != ifs_list.end(); ++it) {
255  indexFaceSet *ifs = *it;
256  for (unsigned int j = 0; j < (unsigned int)ifs->nbIndex; j++) {
257  if (ifs->index[j] == -1) {
258  nbFace++;
259  indSize.push_back(indice);
260  indice = 0;
261  }
262  else
263  indice++;
264  }
265  }
266 
267  bptr->face.nbr = (Index)nbFace;
268  bptr->face.ptr = (Face *)malloc(nbFace * sizeof(Face));
269 
270  std::list<int>::const_iterator iter_indSize = indSize.begin();
271  for (unsigned int i = 0; i < indSize.size(); i++) {
272  bptr->face.ptr[i].vertex.nbr = (Index)*iter_indSize;
273  bptr->face.ptr[i].vertex.ptr = (Index *)malloc((unsigned int)*iter_indSize * sizeof(Index));
274  ++iter_indSize;
275  }
276 
277  int offset = 0;
278  indice = 0;
279  for (std::list<indexFaceSet *>::const_iterator it = ifs_list.begin(); it != ifs_list.end(); ++it) {
280  indexFaceSet *ifs = *it;
281  iter = 0;
282  for (unsigned int j = 0; j < (unsigned int)ifs->nbIndex; j++) {
283  if (ifs->index[j] != -1) {
284  bptr->face.ptr[indice].vertex.ptr[iter] = (Index)(ifs->index[j] + offset);
285  iter++;
286  }
287  else {
288  iter = 0;
289  indice++;
290  }
291  }
292  offset += ifs->nbPt;
293  }
294 }
295 
296 void destroyIfs(std::list<indexFaceSet *> &ifs_list)
297 {
298  for (std::list<indexFaceSet *>::const_iterator it = ifs_list.begin(); it != ifs_list.end(); ++it) {
299  delete *it;
300  }
301  ifs_list.clear();
302 }
303 #else
304 void set_scene_wrl(const char * /*str*/, Bound_scene * /*sc*/, float /*factor*/) { }
305 #endif
306 
307 /*
308  Convert the matrix format to deal with the one in the simulator
309 */
310 void vp2jlc_matrix(const vpHomogeneousMatrix &vpM, Matrix &jlcM)
311 {
312  for (unsigned int i = 0; i < 4; i++) {
313  for (unsigned int j = 0; j < 4; j++)
314  jlcM[j][i] = (float)vpM[i][j];
315  }
316 }
317 END_VISP_NAMESPACE
318 #endif
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ ioError
I/O error.
Definition: vpException.h:67
@ notInitialized
Used to indicate that a parameter is not initialized.
Definition: vpException.h:74
@ fatalError
Fatal error.
Definition: vpException.h:72
Implementation of an homogeneous matrix and operations on such kind of matrices.
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition: vpPoint.h:79