glc_cuttingplane.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  Version 2.0.0 Beta 1, packaged on April 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU General Public License as published by
00011  the Free Software Foundation; either version 2 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU General Public License for more details.
00018 
00019  You should have received a copy of the GNU General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023  *****************************************************************************/
00025 
00026 #include "glc_cuttingplane.h"
00027 #include "../glc_factory.h"
00028 #include "../maths/glc_line3d.h"
00029 #include "../maths/glc_geomtools.h"
00030 #include "../geometry/glc_arrow.h"
00031 #include "../geometry/glc_disc.h"
00032 #include "glc_pullmanipulator.h"
00033 #include "glc_rotationmanipulator.h"
00034 
00035 GLC_CuttingPlane::GLC_CuttingPlane(const GLC_Point3d& center, const GLC_Vector3d& normal, double l1, double l2, GLC_3DWidgetManagerHandle*  pWidgetManagerHandle)
00036 : GLC_3DWidget(pWidgetManagerHandle)
00037 , m_Center(center)
00038 , m_Normal(normal)
00039 , m_CompMatrix()
00040 , m_L1(l1)
00041 , m_L2(l2)
00042 , m_Color(Qt::darkGreen)
00043 , m_Opacity(0.3)
00044 , m_ManipulatorOffsetFactor(1.0)
00045 , m_ScaleFactor(1.0)
00046 , m_SelectionIndex(-1)
00047 , m_CurrentManipulator(TranslationManipulator)
00048 , m_pCurrentManipulator(NULL)
00049 , m_CurrentNavigatorPosition()
00050 {
00051         if (NULL != pWidgetManagerHandle)
00052         {
00053                 create3DviewInstance();
00054         }
00055 
00056         if (glc::Z_AXIS != m_Normal)
00057         {
00058                 if (m_Normal != -glc::Z_AXIS)
00059                 {
00060                         m_CompMatrix.setMatRot(glc::Z_AXIS, m_Normal);
00061                 }
00062                 else
00063                 {
00064                         m_CompMatrix.setMatRot(glc::X_AXIS, glc::PI);
00065                 }
00066         }
00067 
00068 }
00069 
00070 GLC_CuttingPlane::GLC_CuttingPlane(const GLC_CuttingPlane& cuttingPlane)
00071 : GLC_3DWidget(cuttingPlane)
00072 , m_Center(cuttingPlane.m_Center)
00073 , m_Normal(cuttingPlane.m_Normal)
00074 , m_CompMatrix(cuttingPlane.m_CompMatrix)
00075 , m_L1(cuttingPlane.m_L1)
00076 , m_L2(cuttingPlane.m_L2)
00077 , m_Color(cuttingPlane.m_Color)
00078 , m_Opacity(cuttingPlane.m_Opacity)
00079 , m_ManipulatorOffsetFactor(cuttingPlane.m_ManipulatorOffsetFactor)
00080 , m_ScaleFactor(cuttingPlane.m_ScaleFactor)
00081 , m_SelectionIndex(cuttingPlane.m_SelectionIndex)
00082 , m_CurrentManipulator(cuttingPlane.m_CurrentManipulator)
00083 , m_pCurrentManipulator(NULL)
00084 , m_CurrentNavigatorPosition(cuttingPlane.m_CurrentNavigatorPosition)
00085 {
00086         if (NULL != cuttingPlane.m_pCurrentManipulator)
00087         {
00088                 m_pCurrentManipulator= cuttingPlane.m_pCurrentManipulator->clone();
00089         }
00090 }
00091 
00092 GLC_CuttingPlane::~GLC_CuttingPlane()
00093 {
00094         delete m_pCurrentManipulator;
00095 }
00096 
00097 GLC_CuttingPlane& GLC_CuttingPlane::operator=(const GLC_CuttingPlane& cuttingPlane)
00098 {
00099         GLC_3DWidget::operator=(cuttingPlane);
00100 
00101         m_Center= cuttingPlane.m_Center;
00102         m_Normal= cuttingPlane.m_Normal;
00103         m_CompMatrix= cuttingPlane.m_CompMatrix;
00104         m_L1= cuttingPlane.m_L1;
00105         m_L2= cuttingPlane.m_L2;
00106         m_Color= cuttingPlane.m_Color;
00107         m_Opacity= cuttingPlane.m_Opacity;
00108         m_CurrentNavigatorPosition= cuttingPlane.m_CurrentNavigatorPosition;
00109         delete m_pCurrentManipulator;
00110         if (NULL != cuttingPlane.m_pCurrentManipulator)
00111         {
00112                 m_pCurrentManipulator= cuttingPlane.m_pCurrentManipulator->clone();
00113         }
00114 
00115         return *this;
00116 }
00117 
00118 void GLC_CuttingPlane::updateLength(double l1, double l2)
00119 {
00120         m_L1= l1;
00121         m_L2= l2;
00122 
00123         if (GLC_3DWidget::has3DWidgetManager())
00124         {
00125                 GLC_3DWidget::remove3DViewInstance();
00126                 create3DviewInstance();
00127         }
00128 }
00129 
00130 void GLC_CuttingPlane::updateWidgetRep()
00131 {
00132         const double viewTangent= GLC_3DWidget::widgetManagerHandle()->viewportTangent();
00133         const GLC_Point3d eye(GLC_3DWidget::widgetManagerHandle()->cameraHandle()->eye());
00134         const double distanceToNormal= (m_CurrentNavigatorPosition - eye).length();
00135         const double viewWidth= distanceToNormal * viewTangent;
00136 
00137         m_ScaleFactor= viewWidth * 0.1;
00138         m_ManipulatorOffsetFactor= m_ScaleFactor * (-0.01);
00139 
00140         moveManipulatorRep(m_CurrentNavigatorPosition);
00141 }
00142 
00143 glc::WidgetEventFlag GLC_CuttingPlane::select(const GLC_Point3d& pos, GLC_uint)
00144 {
00145         Q_ASSERT(NULL == m_pCurrentManipulator);
00146         Q_ASSERT(TranslationManipulator == m_CurrentManipulator);
00147 
00149         GLC_Viewport* pViewport= GLC_3DWidget::widgetManagerHandle()->viewport();
00150         m_pCurrentManipulator= new GLC_PullManipulator(pViewport, m_Normal);
00151 
00152         m_pCurrentManipulator->enterManipulateState(pos);
00153         m_CurrentNavigatorPosition= pos;
00154 
00155         GLC_3DWidget::set3DViewInstanceVisibility(1, true);
00156 
00157         updateWidgetRep();
00158 
00159         return glc::BlockedEvent;
00160 }
00161 
00162 glc::WidgetEventFlag GLC_CuttingPlane::mousePressed(const GLC_Point3d& pos, Qt::MouseButton button, GLC_uint id)
00163 {
00164         glc::WidgetEventFlag returnFlag= glc::IgnoreEvent;
00165         if (button == Qt::LeftButton)
00166         {
00167                 const int selectedInstanceIndex= GLC_3DWidget::indexOfIntsanceId(id);
00168                 if (selectedInstanceIndex > 0)
00169                 {
00170                         m_SelectionIndex= selectedInstanceIndex;
00171                         if (m_CurrentManipulator == RotationManipulator)
00172                         {
00173                                 delete m_pCurrentManipulator;
00174                                 m_pCurrentManipulator= rotationNavigator(selectedInstanceIndex);
00175                         }
00176                         m_pCurrentManipulator->enterManipulateState(pos);
00177                 }
00178                 else
00179                 {
00180                         if (NULL != m_pCurrentManipulator)
00181                         {
00182                                 if (m_CurrentManipulator == RotationManipulator)
00183                                 {
00184                                         delete m_pCurrentManipulator;
00185                                         m_pCurrentManipulator= NULL;
00186                                 }
00187                                 else
00188                                 {
00189                                         m_pCurrentManipulator->enterManipulateState(pos);
00190                                 }
00191 
00192                         }
00193                         m_CurrentNavigatorPosition= pos;
00194                         updateWidgetRep();
00195                 }
00196 
00197                 returnFlag= glc::BlockedEvent;
00198         }
00199 
00200         return returnFlag;
00201 }
00202 
00203 glc::WidgetEventFlag GLC_CuttingPlane::mouseReleased(Qt::MouseButton button)
00204 {
00205         glc::WidgetEventFlag returnFlag= glc::IgnoreEvent;
00206         if ((button == Qt::LeftButton) && (m_SelectionIndex != -1))
00207         {
00208 
00209                 // get selected instance index
00210 
00211                 if (m_CurrentManipulator == TranslationManipulator)
00212                 {
00213                         GLC_3DWidget::set3DViewInstanceVisibility(1, false);
00214                         GLC_3DWidget::set3DViewInstanceVisibility(2, true);
00215                         GLC_3DWidget::set3DViewInstanceVisibility(3, true);
00216                         GLC_3DWidget::set3DViewInstanceVisibility(4, true);
00217 
00218                         returnFlag= glc::BlockedEvent;
00219                         m_CurrentManipulator= RotationManipulator;
00220                         delete m_pCurrentManipulator;
00221                         m_pCurrentManipulator= NULL;
00222 
00223                         moveManipulatorRep(m_CurrentNavigatorPosition);
00224                 }
00225                 else if (m_CurrentManipulator == RotationManipulator)
00226                 {
00227                         GLC_3DWidget::set3DViewInstanceVisibility(1, true);
00228                         GLC_3DWidget::set3DViewInstanceVisibility(2, false);
00229                         GLC_3DWidget::set3DViewInstanceVisibility(3, false);
00230                         GLC_3DWidget::set3DViewInstanceVisibility(4, false);
00231 
00232                         returnFlag= glc::BlockedEvent;
00233                         m_CurrentManipulator= TranslationManipulator;
00234 
00235                         delete m_pCurrentManipulator;
00236 
00237                         GLC_Viewport* pViewport= GLC_3DWidget::widgetManagerHandle()->viewport();
00238                         m_pCurrentManipulator= new GLC_PullManipulator(pViewport, m_Normal);
00239                         m_pCurrentManipulator->enterManipulateState(m_CurrentNavigatorPosition);
00240 
00241                         moveManipulatorRep(m_CurrentNavigatorPosition);
00242                 }
00243                 m_SelectionIndex= -1;
00244         }
00245         return returnFlag;
00246 }
00247 
00248 glc::WidgetEventFlag GLC_CuttingPlane::unselect(const GLC_Point3d&, GLC_uint)
00249 {
00250         Q_ASSERT(m_SelectionIndex == -1);
00251         for (int i= 0; i < 4; ++i)
00252         {
00253                 GLC_3DWidget::set3DViewInstanceVisibility(1 + i, false);
00254         }
00255         delete m_pCurrentManipulator;
00256         m_pCurrentManipulator= NULL;
00257 
00258         m_CurrentManipulator= TranslationManipulator;
00259 
00260         return glc::AcceptEvent;
00261 }
00262 
00263 glc::WidgetEventFlag GLC_CuttingPlane::mouseMove(const GLC_Point3d& pos, Qt::MouseButtons button, GLC_uint)
00264 {
00265         glc::WidgetEventFlag returnFlag= glc::IgnoreEvent;
00266         if (button & Qt::LeftButton)
00267         {
00268                 if (NULL != m_pCurrentManipulator)
00269                 {
00270                         if (m_SelectionIndex != -1)
00271                         {
00272                                 moveManipulatorRep(m_CurrentNavigatorPosition);
00273                                 m_SelectionIndex= -1;
00274                         }
00275                         GLC_Matrix4x4 moveMatrix(m_pCurrentManipulator->manipulate(pos));
00276 
00277                         // Update plane normal
00278                         if (m_CurrentManipulator == RotationManipulator)
00279                         {
00280                                 m_Normal= moveMatrix.rotationMatrix() * m_Normal;
00281                         }
00282                         m_CompMatrix= moveMatrix * m_CompMatrix;
00283                         m_Center= moveMatrix * m_Center;
00284                         m_CurrentNavigatorPosition= moveMatrix * m_CurrentNavigatorPosition;
00285 
00286                         // Update the instance
00287                         for (int i= 0; i < 5; ++i)
00288                         {
00289                                 GLC_3DWidget::instanceHandle(i)->multMatrix(moveMatrix);
00290                         }
00291 
00292                         // Plane throw intersection and plane normal and camera up vector
00293                         m_pCurrentManipulator->enterManipulateState(m_pCurrentManipulator->previousPosition());
00294 
00295                         emit asChanged();
00296                         returnFlag= glc::AcceptEvent;
00297                 }
00298         }
00299 
00300         return returnFlag;
00301 }
00302 
00303 void GLC_CuttingPlane::create3DviewInstance()
00304 {
00305         Q_ASSERT(GLC_3DWidget::isEmpty());
00306         // The cutting plane material
00307         GLC_Material* pMaterial= new GLC_Material(m_Color);
00308         pMaterial->setOpacity(m_Opacity);
00309 
00310         // Cutting plane 3Dview instance
00311         GLC_3DViewInstance cuttingPlaneInstance= GLC_Factory::instance()->createCuttingPlane(m_Center, m_Normal, m_L1, m_L2, pMaterial);
00312         GLC_3DWidget::add3DViewInstance(cuttingPlaneInstance);
00313 
00314         // Normal arrow geometry
00315         GLC_Arrow* pArrow= new GLC_Arrow(GLC_Point3d(), -glc::Z_AXIS, GLC_3DWidget::widgetManagerHandle()->cameraHandle()->forward().normalize());
00316         pArrow->setLineWidth(4.5);
00317         pArrow->setHeadLength(0.15);
00318         QColor arrowColor(Qt::red);
00319         arrowColor.setAlphaF(0.4);
00320         pArrow->setWireColor(arrowColor);
00321 
00322         //Base arrow disc
00323         pMaterial= new GLC_Material(Qt::red);
00324         pMaterial->setOpacity(m_Opacity);
00325         GLC_Disc* pDisc= new GLC_Disc(0.3);
00326         pDisc->replaceMasterMaterial(pMaterial);
00327 
00328         // Normal arrow + base instance
00329         GLC_3DRep normalLine(pArrow);
00330         normalLine.addGeom(pDisc);
00331         GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(normalLine));
00332         GLC_3DWidget::set3DViewInstanceVisibility(1, false);
00333 
00334         // Rotation manipulator
00335         const double initRadius= 1;
00336         // Arrond X axis
00337         pDisc= new GLC_Disc(initRadius);
00338         pMaterial= new GLC_Material(Qt::red);
00339         pMaterial->setOpacity(m_Opacity);
00340         pDisc->replaceMasterMaterial(pMaterial);
00341         pDisc->setAngle(glc::PI);
00342         GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc));
00343         GLC_3DWidget::set3DViewInstanceVisibility(2, false);
00344         // Arround Y axis
00345         pDisc= new GLC_Disc(initRadius);
00346         pMaterial= new GLC_Material(Qt::green);
00347         pMaterial->setOpacity(m_Opacity);
00348         pDisc->replaceMasterMaterial(pMaterial);
00349         pDisc->setAngle(glc::PI);
00350         GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc));
00351         GLC_3DWidget::set3DViewInstanceVisibility(3, false);
00352         // Arround Z axis
00353         pDisc= new GLC_Disc(initRadius);
00354         pMaterial= new GLC_Material(Qt::blue);
00355         pMaterial->setOpacity(m_Opacity);
00356         pDisc->replaceMasterMaterial(pMaterial);
00357         //pDisc->setAngle(glc::PI / 2.0);
00358         GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(pDisc));
00359         GLC_3DWidget::set3DViewInstanceVisibility(4, false);
00360 }
00361 
00362 void GLC_CuttingPlane::moveManipulatorRep(const GLC_Point3d& pos)
00363 {
00364         // Create the widget rotation matrix
00365         const GLC_Matrix4x4 rotationMatrix(m_CompMatrix.rotationMatrix());
00366 
00367         const GLC_Matrix4x4 translationMatrix(pos);
00368         const GLC_Matrix4x4 offsetMatrix(m_Normal * m_ManipulatorOffsetFactor);
00369         GLC_Matrix4x4 scaleMatrix;
00370         scaleMatrix.setMatScaling(m_ScaleFactor, m_ScaleFactor, m_ScaleFactor);
00371         GLC_3DWidget::instanceHandle(1)->setMatrix(offsetMatrix * translationMatrix * rotationMatrix *scaleMatrix);
00372 
00373         // Rotation manipulator
00374         QVector<GLC_Matrix4x4> rotations(3);
00375         rotations[0].setMatRot(glc::Y_AXIS, glc::PI / 2.0); // X
00376         rotations[0]= GLC_Matrix4x4(glc::X_AXIS, -glc::PI / 2.0) * rotations[0];
00377         rotations[1].setMatRot(glc::X_AXIS, -glc::PI / 2.0); // Y
00378         // Z
00379         for (int i= 0; i < 3; ++i)
00380         {
00381                 GLC_3DWidget::instanceHandle(2 + i)->setMatrix(offsetMatrix * translationMatrix * rotationMatrix * rotations.at(i) * scaleMatrix);
00382         }
00383 
00384         GLC_Arrow* pArrow= dynamic_cast<GLC_Arrow*>(GLC_3DWidget::instanceHandle(1)->geomAt(0));
00385         Q_ASSERT(NULL != pArrow);
00386 
00387         pArrow->setViewDir(GLC_3DWidget::widgetManagerHandle()->cameraHandle()->forward().normalize());
00388 }
00389 
00390 GLC_AbstractManipulator* GLC_CuttingPlane::rotationNavigator(int index)
00391 {
00392         index= index - 2;
00393         Q_ASSERT((index > -1) && (index < 3));
00394 
00395         const GLC_Matrix4x4 rotationMatrix(m_CompMatrix.rotationMatrix());
00396         GLC_Vector3d axis;
00397         if (index == 0)
00398         {
00399                 axis= rotationMatrix * glc::X_AXIS;
00400         }
00401         else if (index == 1)
00402         {
00403                 axis= rotationMatrix * glc::Y_AXIS;
00404         }
00405         else
00406         {
00407                 axis= rotationMatrix * glc::Z_AXIS;
00408         }
00409         GLC_AbstractManipulator* pManipulator= new GLC_RotationManipulator(GLC_3DWidget::widgetManagerHandle()->viewport(), GLC_Line3d(m_CurrentNavigatorPosition, axis));
00410 
00411         return pManipulator;
00412 }
00413 

SourceForge.net Logo

©2005 Laurent Ribon