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://mrpt.sourceforge.net/                            |
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           */
00047         class OPENGL_IMPEXP CGeneralizedCylinder:public CRenderizableDisplayList        {
00048                 DEFINE_SERIALIZABLE(CGeneralizedCylinder)
00049         public:
00050                 /**
00051                   * Auxiliary struct holding any quadrilateral, represented by foour points.
00052                   */
00053                 struct OPENGL_IMPEXP TQuadrilateral     {
00054                 private:
00055                         /**
00056                           * Automatically compute a vector normal to this quadrilateral.
00057                           */
00058                         void calculateNormal();
00059                 public:
00060                         /**
00061                           * Quadrilateral`'s points.
00062                           */
00063                         TPoint3D points[4];
00064                         /**
00065                           * Normal vector.
00066                           */ 
00067                         double normal[3];
00068                         /**
00069                           * Given a polygon with 4 already positions allocated, this method fills it with the quadrilateral points.
00070                           * \sa mrpt::math::TPolygon3D
00071                           */ 
00072                         inline void getAsPolygonUnsafe(mrpt::math::TPolygon3D &vec) const       {
00073                                 vec[0]=points[0];
00074                                 vec[1]=points[1];
00075                                 vec[2]=points[2];
00076                                 vec[3]=points[3];
00077                         }
00078                         /**
00079                           * Constructor from 4 points.
00080                           */ 
00081                         TQuadrilateral(const TPoint3D &p1,const TPoint3D &p2,const TPoint3D &p3,const TPoint3D &p4)     {
00082                                 points[0]=p1;
00083                                 points[1]=p2;
00084                                 points[2]=p3;
00085                                 points[3]=p4;
00086                                 calculateNormal();
00087                         }
00088                         /**
00089                           * Construction from any array of four compatible objects.
00090                           */ 
00091                         template<class T> TQuadrilateral(const T (&p)[4])       {
00092                                 for (int i=0;i<4;i++) points[i]=p[i];
00093                                 calculateNormal();
00094                         }
00095                         /**
00096                           * Empty constructor. Initializes to garbage.
00097                           */ 
00098                         TQuadrilateral()        {}
00099                         /**
00100                           * Destructor.
00101                           */ 
00102                         ~TQuadrilateral()       {}
00103                 };
00104         protected:
00105                 /**
00106                   * Cylinder's axis. It's represented as a pose because it holds the angle to get to the next pose.
00107                   */
00108                 vector<CPose3D> axis;
00109                 /**
00110                   * Object's generatrix, that is, profile which will be extruded.
00111                   */
00112                 vector<TPoint3D> generatrix;
00113                 /**
00114                   * Mutable object with mesh information, used to avoid repeated computations.
00115                   */
00116                 mutable std::vector<TQuadrilateral> mesh;
00117                 /**
00118                   * Mutable object with the cylinder's points, used to avoid repeated computations.
00119                   */
00120                 mutable CMatrixTemplate<TPoint3D> pointsMesh;
00121                 /**
00122                   * Mutable flag which tells if recalculations are needed.
00123                   */
00124                 mutable bool meshUpToDate;
00125                 /**
00126                   * Mutable set of data used in ray tracing.
00127                   * \sa mrpt::math::TPolygonWithPlane
00128                   */
00129                 mutable vector<TPolygonWithPlane> polys;
00130                 /**
00131                   * Mutable flag telling whether ray tracing temporary data must be recalculated or not.
00132                   */
00133                 mutable bool polysUpToDate;
00134                 /**
00135                   * Boolean variable which determines if the profile is closed at each section.
00136                   */
00137                 bool closed;
00138                 /**
00139                   * Flag to determine whether the object is fully visible or only some sections are.
00140                   */
00141                 bool fullyVisible;
00142                 /**
00143                   * First visible section, if fullyVisible is set to false.
00144                   * \sa fullyVisible,lastSection
00145                   */
00146                 size_t firstSection;
00147                 /**
00148                   * Last visible section, if fullyVisible is set to false.
00149                   * \sa fullyVisible,firstSection
00150                   */
00151                 size_t lastSection;
00152         public:
00153                 /**
00154                   * Creation of generalized cylinder from axis and generatrix
00155                   */
00156                 static CGeneralizedCylinderPtr Create(const std::vector<TPoint3D> &axis,const std::vector<TPoint3D> &generatrix)        {
00157                         return CGeneralizedCylinderPtr(new CGeneralizedCylinder(axis,generatrix));
00158                 }
00159                 /**
00160                   * Render.
00161                   * \sa mrpt::opengl::CRenderizable
00162                   */
00163                 void render_dl() const;
00164                 /**
00165                   * Ray tracing.
00166                   * \sa mrpt::opengl::CRenderizable.
00167                   */
00168                 virtual bool traceRay(const mrpt::poses::CPose3D &o,double &dist) const;
00169                 /**
00170                   * Get axis's spatial coordinates.
00171                   */
00172                 inline void getAxis(std::vector<TPoint3D> &a) const     {
00173                         //a=axis;
00174                         size_t N=axis.size();
00175                         a.resize(N);
00176                         for (size_t i=0;i<N;i++)        {
00177                                 a[i].x=axis[i].x();
00178                                 a[i].y=axis[i].y();
00179                                 a[i].z=axis[i].z();
00180                         }
00181                 }
00182                 /**
00183                   * Get axis, including angular coordinates.
00184                   */
00185                 inline void getAxis(std::vector<CPose3D> &a) const      {
00186                         a=axis;
00187                 }
00188                 /**
00189                   * Set the axis points.
00190                   */
00191                 inline void setAxis(const std::vector<TPoint3D> &a)     {
00192                         generatePoses(a,axis);
00193                         meshUpToDate=false;
00194                         fullyVisible=true;
00195                         CRenderizableDisplayList::notifyChange();
00196                 }
00197                 /**
00198                   * Get cylinder's profile.
00199                   */
00200                 inline void getGeneratrix(std::vector<TPoint3D> &g) const       {
00201                         g=generatrix;
00202                 }
00203                 /**
00204                   * Set cylinder's profile.
00205                   */
00206                 inline void setGeneratrix(const std::vector<TPoint3D> g)        {
00207                         generatrix=g;
00208                         meshUpToDate=false;
00209                         CRenderizableDisplayList::notifyChange();
00210                 }
00211                 /**
00212                   * Returns true if each section is a closed polygon.
00213                   */
00214                 inline bool isClosed() const    {
00215                         return closed;
00216                 }
00217                 /**
00218                   * Set whether each section is a closed polygon or not.
00219                   */
00220                 inline void setClosed(bool c=true)      {
00221                         closed=c;
00222                         meshUpToDate=false;
00223                         CRenderizableDisplayList::notifyChange();
00224                 }
00225                 /**
00226                   * Get a polyhedron containing the starting point of the cylinder (its "base").
00227                   * \sa getEnd,mrpt::opengl::CPolyhedron
00228                   */
00229                 void getOrigin(CPolyhedronPtr &poly) const;
00230                 /**
00231                   * Get a polyhedron containing the ending point of the cylinder (its "base").
00232                   * \sa getOrigin,mrpt::opengl::CPolyhedron
00233                   */
00234                 void getEnd(CPolyhedronPtr &poly) const;
00235                 /**
00236                   * Get the cylinder as a set of polygons in 3D.
00237                   * \sa mrpt::math::TPolygon3D
00238                   */
00239                 void generateSetOfPolygons(std::vector<TPolygon3D> &res) const;
00240                 /**
00241                   * Get a polyhedron consisting of a set of closed sections of the cylinder.
00242                   * \sa mrpt::opengl::CPolyhedron
00243                   */
00244                 void getClosedSection(size_t index1,size_t index2,CPolyhedronPtr &poly) const;
00245                 /**
00246                   * Get a polyhedron consisting of a single section of the cylinder.
00247                   * \sa mrpt::opengl::CPolyhedron
00248                   */
00249                 inline void getClosedSection(size_t index,CPolyhedronPtr &poly) const   {
00250                         getClosedSection(index,index,poly);
00251                 }
00252                 /**
00253                   * Get the number of sections in this cylinder.
00254                   */
00255                 inline size_t getNumberOfSections() const       {
00256                         return axis.size()?(axis.size()-1):0;
00257                 }
00258                 /**
00259                   * Get how many visible sections are in the cylinder.
00260                   */
00261                 inline size_t getVisibleSections() const        {
00262                         return fullyVisible?getNumberOfSections():(lastSection-firstSection);
00263                 }
00264                 /**
00265                   * Gets the cylinder's visible sections.
00266                   */
00267                 void getVisibleSections(size_t &first,size_t &last) const       {
00268                         if (fullyVisible)       {
00269                                 first=0;
00270                                 last=getNumberOfSections();
00271                         }       else    {
00272                                 first=firstSection;
00273                                 last=lastSection;
00274                         }
00275                 }
00276                 /**
00277                   * Sets all sections visible.
00278                   */
00279                 inline void setAllSectionsVisible()     {
00280                         fullyVisible=true;
00281                         CRenderizableDisplayList::notifyChange();
00282                 }
00283                 /**
00284                   * Hides all sections.
00285                   */
00286                 inline void setAllSectionsInvisible(size_t pointer=0)   {
00287                         fullyVisible=false;
00288                         firstSection=pointer;
00289                         lastSection=pointer;
00290                         CRenderizableDisplayList::notifyChange();
00291                 }
00292                 /**
00293                   * Sets which sections are visible.
00294                   * \throw std::logic_error on wrongly defined bounds.
00295                   */
00296                 inline void setVisibleSections(size_t first,size_t last)        {
00297                         fullyVisible=false;
00298                         if (first>last||last>getNumberOfSections()) throw std::logic_error("Wrong bound definition");
00299                         firstSection=first;
00300                         lastSection=last;
00301                         CRenderizableDisplayList::notifyChange();
00302                 }
00303                 /**
00304                   * Adds another visible section at the start of the cylinder. The cylinder must have an invisble section to display.
00305                   * \throw std::logic_error if there is no section to add to the displaying set.
00306                   * \sa addVisibleSectionAtEnd,removeVisibleSectionAtStart,removeVisibleSectionAtEnd
00307                   */
00308                 inline void addVisibleSectionAtStart()  {
00309                         if (fullyVisible||firstSection==0) throw std::logic_error("No more sections");
00310                         firstSection--;
00311                         CRenderizableDisplayList::notifyChange();
00312                 }
00313                 /**
00314                   * Adds another visible section at the end of the cylinder. The cylinder must have an invisible section to display.
00315                   * \throw std::logic_error if there is no section to add to the displaying set.
00316                   * \sa addVisibleSectionAtStart,removeVisibleSectionAtStart,removeVisibleSectionAtEnd
00317                   */
00318                 inline void addVisibleSectionAtEnd()    {
00319                         if (fullyVisible||lastSection==getNumberOfSections()) throw std::logic_error("No more sections");
00320                         lastSection++;
00321                         CRenderizableDisplayList::notifyChange();
00322                 }
00323                 /**
00324                   * Removes a visible section from the start of the currently visible set.
00325                   * \throw std::logic_error if there are no visible sections.
00326                   * \sa addVisibleSectionAtStart,addVisibleSectionAtEnd,removeVisibleSectionAtEnd
00327                   */
00328                 void removeVisibleSectionAtStart();
00329                 /**
00330                   * Removes a visible section from the ending of the currently visible set.
00331                   * \throw std::logic_error when there is no such section.
00332                   * \sa addVisibleSectionAtStart,addVisibleSectionAtEnd,removeVisibleSectionAtStart
00333                   */
00334                 void removeVisibleSectionAtEnd();
00335                 /**
00336                   * Gets the axis pose of the first section, returning false if there is no such pose.
00337                   */
00338                 bool getFirstSectionPose(mrpt::poses::CPose3D &p);
00339                 /**
00340                   * Gets the axis pose of the last section, returning false if there is no such pose.
00341                   */
00342                 bool getLastSectionPose(mrpt::poses::CPose3D &p);
00343                 /**
00344                   * Gets the axis pose of the first visible section, returning false if there is no such pose.
00345                   */
00346                 bool getFirstVisibleSectionPose(mrpt::poses::CPose3D &p);
00347                 /**
00348                   * Gets the axis pose of the last section, returning false if there is no such pose.
00349                   */
00350                 bool getLastVisibleSectionPose(mrpt::poses::CPose3D &p);
00351                 /**
00352                   * Updates the mutable set of polygons used in ray tracing.
00353                   */
00354                 void updatePolys() const;
00355         private:
00356                 /**
00357                   * Updates the axis, transforming each point into a pose pointing to the next section.
00358                   */
00359                 void generatePoses(const std::vector<TPoint3D> &pIn,std::vector<CPose3D> &pOut);
00360                 /**
00361                   * Updates the mutable mesh.
00362                   */
00363                 void updateMesh() const;
00364                 /**
00365                   * Given a vector of polyhedrons, gets the starting and ending iterators to the section to be actually rendered.
00366                   */
00367                 void getMeshIterators(const vector<TQuadrilateral> &m,vector<TQuadrilateral>::const_iterator &begin,vector<TQuadrilateral>::const_iterator &end) const;
00368                 /**
00369                   * Basic constructor with default initialization.
00370                   */
00371                 CGeneralizedCylinder():axis(),generatrix(),mesh(),meshUpToDate(false),polysUpToDate(false),closed(false),fullyVisible(true)     {}
00372                 /**
00373                   * Constructor with axis and generatrix.
00374                   */
00375                 CGeneralizedCylinder(const std::vector<TPoint3D> &a,const std::vector<TPoint3D> &g):generatrix(g),mesh(),meshUpToDate(false),polysUpToDate(false),closed(false),fullyVisible(true)      {
00376                         generatePoses(a,axis);
00377                 }
00378                 /**
00379                   * Destructor.
00380                   */
00381                 virtual ~CGeneralizedCylinder() {};
00382         };
00383 }
00384 }
00385 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011