Main MRPT website > C++ reference
MRPT logo
CGeneralizedCylinder.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef opengl_CGeneralizedCylinder_H
00029 #define opengl_CGeneralizedCylinder_H
00030 
00031 #include <mrpt/opengl/CRenderizableDisplayList.h>
00032 #include <mrpt/opengl/CPolyhedron.h>
00033 #include <mrpt/opengl/CSetOfTriangles.h>
00034 #include <mrpt/math/geometry.h>
00035 #include <mrpt/math/CMatrixTemplate.h>
00036 
00037 namespace mrpt  {
00038 namespace opengl        {
00039         using namespace std;
00040         using namespace mrpt::math;
00041         class OPENGL_IMPEXP CGeneralizedCylinder;
00042         // This must be added to any CSerializable derived class:
00043         DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE(CGeneralizedCylinder,CRenderizableDisplayList, OPENGL_IMPEXP)
00044         /**
00045           * This object represents any figure obtained by extruding any profile along a given axis. The profile should lie over a x=0 plane, and the axis must be roughly perpendicular to this plane. In particular, it should be almost perpendicular to the Z axis.
00046           * \ingroup mrpt_opengl_grp
00047           */
00048         class OPENGL_IMPEXP CGeneralizedCylinder:public CRenderizableDisplayList        {
00049                 DEFINE_SERIALIZABLE(CGeneralizedCylinder)
00050         public:
00051                 /**
00052                   * Auxiliary struct holding any quadrilateral, represented by foour points.
00053                   */
00054                 struct OPENGL_IMPEXP TQuadrilateral     {
00055                 private:
00056                         /**
00057                           * Automatically compute a vector normal to this quadrilateral.
00058                           */
00059                         void calculateNormal();
00060                 public:
00061                         /**
00062                           * Quadrilateral`'s points.
00063                           */
00064                         TPoint3D points[4];
00065                         /**
00066                           * Normal vector.
00067                           */ 
00068                         double normal[3];
00069                         /**
00070                           * Given a polygon with 4 already positions allocated, this method fills it with the quadrilateral points.
00071                           * \sa mrpt::math::TPolygon3D
00072                           */ 
00073                         inline void getAsPolygonUnsafe(mrpt::math::TPolygon3D &vec) const       {
00074                                 vec[0]=points[0];
00075                                 vec[1]=points[1];
00076                                 vec[2]=points[2];
00077                                 vec[3]=points[3];
00078                         }
00079                         /**
00080                           * Constructor from 4 points.
00081                           */ 
00082                         TQuadrilateral(const TPoint3D &p1,const TPoint3D &p2,const TPoint3D &p3,const TPoint3D &p4)     {
00083                                 points[0]=p1;
00084                                 points[1]=p2;
00085                                 points[2]=p3;
00086                                 points[3]=p4;
00087                                 calculateNormal();
00088                         }
00089                         /**
00090                           * Construction from any array of four compatible objects.
00091                           */ 
00092                         template<class T> TQuadrilateral(const T (&p)[4])       {
00093                                 for (int i=0;i<4;i++) points[i]=p[i];
00094                                 calculateNormal();
00095                         }
00096                         /**
00097                           * Empty constructor. Initializes to garbage.
00098                           */ 
00099                         TQuadrilateral()        {}
00100                         /**
00101                           * Destructor.
00102                           */ 
00103                         ~TQuadrilateral()       {}
00104                 };
00105         protected:
00106                 /**
00107                   * Cylinder's axis. It's represented as a pose because it holds the angle to get to the next pose.
00108                   */
00109                 vector<CPose3D> axis;
00110                 /**
00111                   * Object's generatrix, that is, profile which will be extruded.
00112                   */
00113                 vector<TPoint3D> generatrix;
00114                 /**
00115                   * Mutable object with mesh information, used to avoid repeated computations.
00116                   */
00117                 mutable std::vector<TQuadrilateral> mesh;
00118                 /**
00119                   * Mutable object with the cylinder's points, used to avoid repeated computations.
00120                   */
00121                 mutable CMatrixTemplate<TPoint3D> pointsMesh;
00122                 /**
00123                   * Mutable flag which tells if recalculations are needed.
00124                   */
00125                 mutable bool meshUpToDate;
00126                 /**
00127                   * Mutable set of data used in ray tracing.
00128                   * \sa mrpt::math::TPolygonWithPlane
00129                   */
00130                 mutable vector<TPolygonWithPlane> polys;
00131                 /**
00132                   * Mutable flag telling whether ray tracing temporary data must be recalculated or not.
00133                   */
00134                 mutable bool polysUpToDate;
00135                 /**
00136                   * Boolean variable which determines if the profile is closed at each section.
00137                   */
00138                 bool closed;
00139                 /**
00140                   * Flag to determine whether the object is fully visible or only some sections are.
00141                   */
00142                 bool fullyVisible;
00143                 /**
00144                   * First visible section, if fullyVisible is set to false.
00145                   * \sa fullyVisible,lastSection
00146                   */
00147                 size_t firstSection;
00148                 /**
00149                   * Last visible section, if fullyVisible is set to false.
00150                   * \sa fullyVisible,firstSection
00151                   */
00152                 size_t lastSection;
00153         public:
00154                 /**
00155                   * Creation of generalized cylinder from axis and generatrix
00156                   */
00157                 static CGeneralizedCylinderPtr Create(const std::vector<TPoint3D> &axis,const std::vector<TPoint3D> &generatrix)        {
00158                         return CGeneralizedCylinderPtr(new CGeneralizedCylinder(axis,generatrix));
00159                 }
00160                 /**
00161                   * Render.
00162                   * \sa mrpt::opengl::CRenderizable
00163                   */
00164                 void render_dl() const;
00165                 /**
00166                   * Ray tracing.
00167                   * \sa mrpt::opengl::CRenderizable.
00168                   */
00169                 virtual bool traceRay(const mrpt::poses::CPose3D &o,double &dist) const;
00170                 /**
00171                   * Get axis's spatial coordinates.
00172                   */
00173                 inline void getAxis(std::vector<TPoint3D> &a) const     {
00174                         //a=axis;
00175                         size_t N=axis.size();
00176                         a.resize(N);
00177                         for (size_t i=0;i<N;i++)        {
00178                                 a[i].x=axis[i].x();
00179                                 a[i].y=axis[i].y();
00180                                 a[i].z=axis[i].z();
00181                         }
00182                 }
00183                 /**
00184                   * Get axis, including angular coordinates.
00185                   */
00186                 inline void getAxis(std::vector<CPose3D> &a) const      {
00187                         a=axis;
00188                 }
00189                 /**
00190                   * Set the axis points.
00191                   */
00192                 inline void setAxis(const std::vector<TPoint3D> &a)     {
00193                         generatePoses(a,axis);
00194                         meshUpToDate=false;
00195                         fullyVisible=true;
00196                         CRenderizableDisplayList::notifyChange();
00197                 }
00198                 /**
00199                   * Get cylinder's profile.
00200                   */
00201                 inline void getGeneratrix(std::vector<TPoint3D> &g) const       {
00202                         g=generatrix;
00203                 }
00204                 /**
00205                   * Set cylinder's profile.
00206                   */
00207                 inline void setGeneratrix(const std::vector<TPoint3D> g)        {
00208                         generatrix=g;
00209                         meshUpToDate=false;
00210                         CRenderizableDisplayList::notifyChange();
00211                 }
00212                 /**
00213                   * Returns true if each section is a closed polygon.
00214                   */
00215                 inline bool isClosed() const    {
00216                         return closed;
00217                 }
00218                 /**
00219                   * Set whether each section is a closed polygon or not.
00220                   */
00221                 inline void setClosed(bool c=true)      {
00222                         closed=c;
00223                         meshUpToDate=false;
00224                         CRenderizableDisplayList::notifyChange();
00225                 }
00226                 /**
00227                   * Get a polyhedron containing the starting point of the cylinder (its "base").
00228                   * \sa getEnd,mrpt::opengl::CPolyhedron
00229                   */
00230                 void getOrigin(CPolyhedronPtr &poly) const;
00231                 /**
00232                   * Get a polyhedron containing the ending point of the cylinder (its "base").
00233                   * \sa getOrigin,mrpt::opengl::CPolyhedron
00234                   */
00235                 void getEnd(CPolyhedronPtr &poly) const;
00236                 /**
00237                   * Get the cylinder as a set of polygons in 3D.
00238                   * \sa mrpt::math::TPolygon3D
00239                   */
00240                 void generateSetOfPolygons(std::vector<TPolygon3D> &res) const;
00241                 /**
00242                   * Get a polyhedron consisting of a set of closed sections of the cylinder.
00243                   * \sa mrpt::opengl::CPolyhedron
00244                   */
00245                 void getClosedSection(size_t index1,size_t index2,CPolyhedronPtr &poly) const;
00246                 /**
00247                   * Get a polyhedron consisting of a single section of the cylinder.
00248                   * \sa mrpt::opengl::CPolyhedron
00249                   */
00250                 inline void getClosedSection(size_t index,CPolyhedronPtr &poly) const   {
00251                         getClosedSection(index,index,poly);
00252                 }
00253                 /**
00254                   * Get the number of sections in this cylinder.
00255                   */
00256                 inline size_t getNumberOfSections() const       {
00257                         return axis.size()?(axis.size()-1):0;
00258                 }
00259                 /**
00260                   * Get how many visible sections are in the cylinder.
00261                   */
00262                 inline size_t getVisibleSections() const        {
00263                         return fullyVisible?getNumberOfSections():(lastSection-firstSection);
00264                 }
00265                 /**
00266                   * Gets the cylinder's visible sections.
00267                   */
00268                 void getVisibleSections(size_t &first,size_t &last) const       {
00269                         if (fullyVisible)       {
00270                                 first=0;
00271                                 last=getNumberOfSections();
00272                         }       else    {
00273                                 first=firstSection;
00274                                 last=lastSection;
00275                         }
00276                 }
00277                 /**
00278                   * Sets all sections visible.
00279                   */
00280                 inline void setAllSectionsVisible()     {
00281                         fullyVisible=true;
00282                         CRenderizableDisplayList::notifyChange();
00283                 }
00284                 /**
00285                   * Hides all sections.
00286                   */
00287                 inline void setAllSectionsInvisible(size_t pointer=0)   {
00288                         fullyVisible=false;
00289                         firstSection=pointer;
00290                         lastSection=pointer;
00291                         CRenderizableDisplayList::notifyChange();
00292                 }
00293                 /**
00294                   * Sets which sections are visible.
00295                   * \throw std::logic_error on wrongly defined bounds.
00296                   */
00297                 inline void setVisibleSections(size_t first,size_t last)        {
00298                         fullyVisible=false;
00299                         if (first>last||last>getNumberOfSections()) throw std::logic_error("Wrong bound definition");
00300                         firstSection=first;
00301                         lastSection=last;
00302                         CRenderizableDisplayList::notifyChange();
00303                 }
00304                 /**
00305                   * Adds another visible section at the start of the cylinder. The cylinder must have an invisble section to display.
00306                   * \throw std::logic_error if there is no section to add to the displaying set.
00307                   * \sa addVisibleSectionAtEnd,removeVisibleSectionAtStart,removeVisibleSectionAtEnd
00308                   */
00309                 inline void addVisibleSectionAtStart()  {
00310                         if (fullyVisible||firstSection==0) throw std::logic_error("No more sections");
00311                         firstSection--;
00312                         CRenderizableDisplayList::notifyChange();
00313                 }
00314                 /**
00315                   * Adds another visible section at the end of the cylinder. The cylinder must have an invisible section to display.
00316                   * \throw std::logic_error if there is no section to add to the displaying set.
00317                   * \sa addVisibleSectionAtStart,removeVisibleSectionAtStart,removeVisibleSectionAtEnd
00318                   */
00319                 inline void addVisibleSectionAtEnd()    {
00320                         if (fullyVisible||lastSection==getNumberOfSections()) throw std::logic_error("No more sections");
00321                         lastSection++;
00322                         CRenderizableDisplayList::notifyChange();
00323                 }
00324                 /**
00325                   * Removes a visible section from the start of the currently visible set.
00326                   * \throw std::logic_error if there are no visible sections.
00327                   * \sa addVisibleSectionAtStart,addVisibleSectionAtEnd,removeVisibleSectionAtEnd
00328                   */
00329                 void removeVisibleSectionAtStart();
00330                 /**
00331                   * Removes a visible section from the ending of the currently visible set.
00332                   * \throw std::logic_error when there is no such section.
00333                   * \sa addVisibleSectionAtStart,addVisibleSectionAtEnd,removeVisibleSectionAtStart
00334                   */
00335                 void removeVisibleSectionAtEnd();
00336                 /**
00337                   * Gets the axis pose of the first section, returning false if there is no such pose.
00338                   */
00339                 bool getFirstSectionPose(mrpt::poses::CPose3D &p);
00340                 /**
00341                   * Gets the axis pose of the last section, returning false if there is no such pose.
00342                   */
00343                 bool getLastSectionPose(mrpt::poses::CPose3D &p);
00344                 /**
00345                   * Gets the axis pose of the first visible section, returning false if there is no such pose.
00346                   */
00347                 bool getFirstVisibleSectionPose(mrpt::poses::CPose3D &p);
00348                 /**
00349                   * Gets the axis pose of the last section, returning false if there is no such pose.
00350                   */
00351                 bool getLastVisibleSectionPose(mrpt::poses::CPose3D &p);
00352                 /**
00353                   * Updates the mutable set of polygons used in ray tracing.
00354                   */
00355                 void updatePolys() const;
00356         private:
00357                 /**
00358                   * Updates the axis, transforming each point into a pose pointing to the next section.
00359                   */
00360                 void generatePoses(const std::vector<TPoint3D> &pIn,std::vector<CPose3D> &pOut);
00361                 /**
00362                   * Updates the mutable mesh.
00363                   */
00364                 void updateMesh() const;
00365                 /**
00366                   * Given a vector of polyhedrons, gets the starting and ending iterators to the section to be actually rendered.
00367                   */
00368                 void getMeshIterators(const vector<TQuadrilateral> &m,vector<TQuadrilateral>::const_iterator &begin,vector<TQuadrilateral>::const_iterator &end) const;
00369                 /**
00370                   * Basic constructor with default initialization.
00371                   */
00372                 CGeneralizedCylinder():axis(),generatrix(),mesh(),meshUpToDate(false),polysUpToDate(false),closed(false),fullyVisible(true)     {}
00373                 /**
00374                   * Constructor with axis and generatrix.
00375                   */
00376                 CGeneralizedCylinder(const std::vector<TPoint3D> &a,const std::vector<TPoint3D> &g):generatrix(g),mesh(),meshUpToDate(false),polysUpToDate(false),closed(false),fullyVisible(true)      {
00377                         generatePoses(a,axis);
00378                 }
00379                 /**
00380                   * Destructor.
00381                   */
00382                 virtual ~CGeneralizedCylinder() {};
00383         };
00384 }
00385 }
00386 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011