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

SourceForge.net Logo

©2005-2011 Laurent Ribon