ViSP  2.9.0
vpMbHiddenFaces.h
1 /****************************************************************************
2  *
3  * $Id: vpMbTracker.h 4004 2012-11-23 17:34:44Z 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  * Generic model based tracker. This class declares the methods to implement in
35  * order to have a model based tracker.
36  *
37  * Authors:
38  * Romain Tallonneau
39  * AurĂ©lien Yol
40  *
41  *****************************************************************************/
42 #pragma once
43 
44 #ifndef vpMbHiddenFaces_HH
45 #define vpMbHiddenFaces_HH
46 
47 #include <visp/vpHomogeneousMatrix.h>
48 #include <visp/vpMeterPixelConversion.h>
49 #include <visp/vpPixelMeterConversion.h>
50 #include <visp/vpMbtPolygon.h>
51 
52 #ifdef VISP_HAVE_OGRE
53  #include <visp/vpAROgre.h>
54 #endif
55 
56 #include <vector>
57 #include <limits>
58 
67 template<class PolygonType = vpMbtPolygon>
69 {
70  private:
72  std::vector<PolygonType *> Lpol ;
74  unsigned int nbVisiblePolygon;
75 
76 #ifdef VISP_HAVE_OGRE
77  vpImage<unsigned char> ogreBackground;
78  bool ogreInitialised;
79  vpAROgre *ogre;
80  std::vector< Ogre::ManualObject* > lOgrePolygons;
81 #endif
82 
83  unsigned int setVisiblePrivate(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
84  bool &changed,
85  bool useOgre = false, bool testRoi = false,
88  ) ;
89 
90 
91  public :
92  vpMbHiddenFaces() ;
94 
95  void addPolygon(PolygonType *p) ;
96 
97 #ifdef VISP_HAVE_OGRE
98  void displayOgre(const vpHomogeneousMatrix &cMo);
99 #endif
100 
106  std::vector<PolygonType*>& getPolygon() {return Lpol;}
107 
108 #ifdef VISP_HAVE_OGRE
109  void initOgre(const vpCameraParameters &cam = vpCameraParameters());
110 #endif
111 
117  unsigned int getNbVisiblePolygon() const {return nbVisiblePolygon;}
118 
119 #ifdef VISP_HAVE_OGRE
120 
125  vpAROgre* getOgreContext(){return ogre;}
126 #endif
127 
128  bool isAppearing(const unsigned int i){ return Lpol[i]->isAppearing(); }
129 
130 
131 #ifdef VISP_HAVE_OGRE
132 
137  bool isOgreInitialised() { return ogreInitialised; }
138 #endif
139 
147  bool isVisible(const unsigned int i){ return Lpol[i]->isVisible(); }
148 
149 #ifdef VISP_HAVE_OGRE
150  bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index);
151 #endif
152 
154  inline PolygonType* operator[](const unsigned int i) { return Lpol[i];}
156  inline const PolygonType* operator[](const unsigned int i) const { return Lpol[i];}
157 
158  void reset();
159 
160 #ifdef VISP_HAVE_OGRE
161 
170  void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w) { ogreBackground.resize(h,w); }
171 #endif
172 
173  unsigned int setVisible(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed) ;
174  unsigned int setVisible(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
175  unsigned int setVisible(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
176 
177 #ifdef VISP_HAVE_OGRE
178  unsigned int setVisibleOgre(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
179  unsigned int setVisibleOgre(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed) ;
180 #endif
181 
186  inline unsigned int size() const { return (unsigned int)Lpol.size(); }
187 
188 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
189  bool depthTest;
191 
202  vp_deprecated bool getDepthTest(){return depthTest;}
210  vp_deprecated void setDepthTest(const bool &d){depthTest = d;}
211  unsigned int setVisible(const vpHomogeneousMatrix &cMo) ;
212 #endif
213 } ;
214 
218 template<class PolygonType>
220  : Lpol(), nbVisiblePolygon(0)
221 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
222  , depthTest(false)
223 #endif
224 
225 {
226 #ifdef VISP_HAVE_OGRE
227  ogreInitialised = false;
228  ogre = new vpAROgre();
229  ogre->setShowConfigDialog(false);
230  ogreBackground = vpImage<unsigned char>(480, 640);
231 #endif
232 }
233 
234 
238 template<class PolygonType>
240 {
241  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
242  if (Lpol[i]!=NULL){
243  delete Lpol[i] ;
244  }
245  Lpol[i] = NULL ;
246  }
247  Lpol.resize(0);
248 
249 #ifdef VISP_HAVE_OGRE
250  delete ogre;
251 #endif
252 }
253 
259 template<class PolygonType>
260 void
262 {
263  PolygonType *p_new = new PolygonType;
264  p_new->index = p->index;
265  p_new->setNbPoint(p->nbpt);
266  p_new->isvisible = p->isvisible;
267  for(unsigned int i = 0; i < p->nbpt; i++)
268  p_new->p[i]= p->p[i];
269  Lpol.push_back(p_new);
270 }
271 
275 template<class PolygonType>
276 void
278 {
279  nbVisiblePolygon = 0;
280  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
281  if (Lpol[i]!=NULL){
282  delete Lpol[i] ;
283  }
284  Lpol[i] = NULL ;
285  }
286  Lpol.resize(0);
287 }
288 
303 template<class PolygonType>
304 unsigned int
305 vpMbHiddenFaces<PolygonType>::setVisiblePrivate(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears,
306  bool &changed, bool useOgre, bool testRoi,
307  const vpImage<unsigned char> &I,
308  const vpCameraParameters &cam
309  )
310 {
311  nbVisiblePolygon = 0;
312  changed = false;
313 
314  vpTranslationVector cameraPos;
315 
316  if(useOgre){
317 #ifdef VISP_HAVE_OGRE
318  cMo.inverse().extract(cameraPos);
319  ogre->renderOneFrame(ogreBackground, cMo);
320 #else
321  vpTRACE("ViSP doesn't have Ogre3D, simple visibility test used");
322 #endif
323  }
324 
325  for (unsigned int i = 0; i < Lpol.size(); i += 1){
326  Lpol[i]->changeFrame(cMo);
327  Lpol[i]->isappearing = false;
328 
329  if(Lpol[i]->isVisible())
330  {
331  bool testDisappear = false;
332  unsigned int nbCornerInsidePrev = 0;
333 
334  if(testRoi){
335  nbCornerInsidePrev = Lpol[i]->getNbCornerInsidePrevImage();
336  if(Lpol[i]->getNbCornerInsideImage(I, cam) == 0)
337  testDisappear = true;
338  }
339 
340  if(!testDisappear){
341  if(useOgre)
342 #ifdef VISP_HAVE_OGRE
343  testDisappear = ((!Lpol[i]->isVisible(cMo, angleDisappears, true)) || !isVisibleOgre(cameraPos,i));
344 #else
345  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears));
346 #endif
347  else
348  testDisappear = (!Lpol[i]->isVisible(cMo, angleDisappears));
349  }
350 
351  // test if the face is still visible
352  if(testDisappear){
353 // std::cout << "Face " << i << " disappears" << std::endl;
354  changed = true;
355  Lpol[i]->isvisible = false;
356  }
357  else {
358  nbVisiblePolygon++;
359  Lpol[i]->isvisible = true;
360 
361  if(nbCornerInsidePrev > Lpol[i]->getNbCornerInsidePrevImage())
362  changed = true;
363  }
364  }
365  else
366  {
367  bool testAppear = true;
368 
369  if(testRoi && Lpol[i]->getNbCornerInsideImage(I, cam) == 0)
370  testAppear = false;
371 
372  if(testAppear){
373  if(useOgre)
374 #ifdef VISP_HAVE_OGRE
375  testAppear = ((Lpol[i]->isVisible(cMo, angleAppears, true)) && isVisibleOgre(cameraPos,i));
376 #else
377  testAppear = (Lpol[i]->isVisible(cMo, angleAppears));
378 #endif
379  else
380  testAppear = (Lpol[i]->isVisible(cMo, angleAppears));
381  }
382 
383  if(testAppear){
384 // std::cout << "Face " << i << " appears" << std::endl;
385  Lpol[i]->isvisible = true;
386  changed = true;
387  nbVisiblePolygon++;
388  }
389  else
390  Lpol[i]->isvisible = false;
391  }
392  }
393 
394 // std::cout << "Nombre de polygones visibles: " << nbVisiblePolygon << std::endl;
395  return nbVisiblePolygon;
396 }
397 
409 template<class PolygonType>
410 unsigned int
411 vpMbHiddenFaces<PolygonType>::setVisible(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
412 {
413  return setVisible(I, cam, cMo, angle, angle, changed);
414 }
415 
428 template<class PolygonType>
429 unsigned int
430 vpMbHiddenFaces<PolygonType>::setVisible(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
431 {
432  return setVisiblePrivate(cMo,angleAppears,angleDisappears,changed,false,true,I,cam);
433 }
434 
445 template<class PolygonType>
446 unsigned int
447 vpMbHiddenFaces<PolygonType>::setVisible(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
448 {
449  return setVisiblePrivate(cMo,angleAppears,angleDisappears,changed,false);
450 }
451 
452 #ifdef VISP_HAVE_OGRE
453 
458 template<class PolygonType>
459 void
461 {
462  ogreInitialised = true;
463  ogre->setCameraParameters(cam);
464  ogre->init(ogreBackground, false, true);
465 
466  for(unsigned int n = 0 ; n < Lpol.size(); n++){
467  Ogre::ManualObject* manual = ogre->getSceneManager()->createManualObject(Ogre::StringConverter::toString(n));
468 
469  manual->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
470  for(unsigned int i = 0; i < Lpol[n]->nbpt; i++){
471  manual->position( (Ogre::Real)Lpol[n]->p[i].get_oX(), (Ogre::Real)Lpol[n]->p[i].get_oY(), (Ogre::Real)Lpol[n]->p[i].get_oZ());
472  manual->colour(1.0, 1.0, 1.0);
473  manual->index(i);
474  }
475 
476  manual->index(0);
477  manual->end();
478 
479  ogre->getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
480 
481  lOgrePolygons.push_back(manual);
482  }
483 }
484 
490 template<class PolygonType>
491 void
493 {
494  if(ogreInitialised && !ogre->isWindowHidden()){
495  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
496  if(Lpol[i]->isVisible()){
497  lOgrePolygons[i]->setVisible(true);
498  }
499  else
500  lOgrePolygons[i]->setVisible(false);
501  }
502  ogre->display(ogreBackground, cMo);
503  }
504 }
505 
518 template<class PolygonType>
519 unsigned int
520 vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpImage<unsigned char>& I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
521 {
522  return setVisiblePrivate(cMo,angleAppears,angleDisappears,changed,true,true,I,cam);
523 }
524 
535 template<class PolygonType>
536 unsigned int
537 vpMbHiddenFaces<PolygonType>::setVisibleOgre(const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
538 {
539  return setVisiblePrivate(cMo,angleAppears,angleDisappears,changed,true);
540 }
541 
550 template<class PolygonType>
551 bool
552 vpMbHiddenFaces<PolygonType>::isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
553 {
554 // std::cout << "visible" << std::endl;
555  // A line is always visible
556  if(Lpol[index]->getNbPoint() <= 2){
557  lOgrePolygons[index]->setVisible(true);
558  Lpol[index]->isvisible = true;
559  return true;
560  }
561 
562  Ogre::Vector3 camera((Ogre::Real)cameraPos[0],(Ogre::Real)cameraPos[1],(Ogre::Real)cameraPos[2]);
563  if(!ogre->getCamera()->isVisible(lOgrePolygons[index]->getBoundingBox())){
564  lOgrePolygons[index]->setVisible(false);
565  Lpol[index]->isvisible = false;
566  return false;
567  }
568 
569  //Get the center of gravity
570  Ogre::Vector3 origin(0,0,0);
571  for(unsigned int j = 0 ; j < Lpol[index]->getNbPoint() ; j++){
572  Ogre::Vector3 tmp((Ogre::Real)Lpol[index]->getPoint(j).get_oX(), (Ogre::Real)Lpol[index]->getPoint(j).get_oY(), (Ogre::Real)Lpol[index]->getPoint(j).get_oZ());
573  origin += tmp;
574  }
575  origin /= (Ogre::Real)Lpol[index]->getNbPoint();
576  Ogre::Vector3 direction = origin - camera;
577 
578  Ogre::RaySceneQuery *mRaySceneQuery = ogre->getSceneManager()->createRayQuery(Ogre::Ray(camera, direction));
579  mRaySceneQuery->setSortByDistance(true);
580 
581  Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute();
582  Ogre::RaySceneQueryResult::iterator it = result.begin();
583 
584  bool visible = false;
585  double distance, distancePrev;
586  if(it != result.end()){
587  if(it->movable->getName().find("SimpleRenderable") != Ogre::String::npos) //Test if the ogreBackground is intersect in first
588  it++;
589 
590  if(it != result.end()){
591  distance = it->distance;
592  distancePrev = distance;
593  if(it->movable->getName() == Ogre::StringConverter::toString(index)){
594  visible = true;
595  }
596  else{
597  it++;
598  while(!visible && it != result.end()){
599  distance = it->distance;
600  //if(distance == distancePrev){
601  if(std::fabs(distance - distancePrev) < distance * std::numeric_limits<double>::epsilon()){
602  if(it->movable->getName() == Ogre::StringConverter::toString(index)){
603  visible = true;
604  break;
605  }
606  it++;
607  distancePrev = distance;
608  }
609  else
610  break;
611  }
612  }
613  }
614  }
615 
616  if(visible){
617  lOgrePolygons[index]->setVisible(true);
618  Lpol[index]->isvisible = true;
619  }
620  else{
621  lOgrePolygons[index]->setVisible(false);
622  Lpol[index]->isvisible = false;
623  }
624 
625  ogre->getSceneManager()->destroyQuery(mRaySceneQuery);
626 
627  return Lpol[index]->isvisible;
628 }
629 #endif //VISP_HAVE_OGRE
630 
631 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS
632 
641 template<class PolygonType>
642 unsigned int
644 {
645  nbVisiblePolygon = 0 ;
646 
647  for(unsigned int i = 0 ; i < Lpol.size() ; i++){
648  if (Lpol[i]->isVisible(cMo, depthTest)){
649  nbVisiblePolygon++;
650  }
651  }
652  return nbVisiblePolygon ;
653 }
654 #endif //VISP_BUILD_DEPRECATED_FUNCTIONS
655 
656 #endif // vpMbHiddenFaces
657 
const PolygonType * operator[](const unsigned int i) const
operator[] as reader.
bool isAppearing(const unsigned int i)
Implementation of the polygons management for the model-based trackers.
Ogre::Camera * getCamera()
Definition: vpAROgre.h:142
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
#define vpTRACE
Definition: vpDebug.h:418
unsigned int getNbVisiblePolygon() const
void setShowConfigDialog(const bool showConfigDialog)
Definition: vpAROgre.h:221
void setBackgroundSizeOgre(const unsigned int &h, const unsigned int &w)
PolygonType * operator[](const unsigned int i)
operator[] as modifier.
Implementation of an augmented reality viewer.
Definition: vpAROgre.h:90
bool renderOneFrame(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:565
unsigned int setVisibleOgre(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angleAppears, const double &angleDisappears, bool &changed)
vp_deprecated void setDepthTest(const bool &d)
Ogre::SceneManager * getSceneManager()
Definition: vpAROgre.h:148
virtual void display(const vpImage< unsigned char > &I, const vpHomogeneousMatrix &cMw)
Definition: vpAROgre.cpp:601
bool depthTest
Boolean specifying if a polygon has to be entirely in front of the camera or not. ...
unsigned int setVisible(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, const double &angle, bool &changed)
void initOgre(const vpCameraParameters &cam=vpCameraParameters())
bool isVisibleOgre(const vpTranslationVector &cameraPos, const unsigned int &index)
vpAROgre * getOgreContext()
virtual void init(vpImage< unsigned char > &I, bool bufferedKeys=false, bool hidden=false)
Definition: vpAROgre.cpp:135
void setCameraParameters(const vpCameraParameters &cameraP)
Definition: vpAROgre.cpp:641
Generic class defining intrinsic camera parameters.
void resize(const unsigned int h, const unsigned int w)
set the size of the image
Definition: vpImage.h:532
void extract(vpRotationMatrix &R) const
void addPolygon(PolygonType *p)
unsigned int size() const
vp_deprecated bool getDepthTest()
vpHomogeneousMatrix inverse() const
bool isWindowHidden()
Definition: vpAROgre.h:158
bool isVisible(const unsigned int i)
void displayOgre(const vpHomogeneousMatrix &cMo)
Class that consider the case of a translation vector.
std::vector< PolygonType * > & getPolygon()