00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
00287 for (int i= 0; i < 5; ++i)
00288 {
00289 GLC_3DWidget::instanceHandle(i)->multMatrix(moveMatrix);
00290 }
00291
00292
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
00307 GLC_Material* pMaterial= new GLC_Material(m_Color);
00308 pMaterial->setOpacity(m_Opacity);
00309
00310
00311 GLC_3DViewInstance cuttingPlaneInstance= GLC_Factory::instance()->createCuttingPlane(m_Center, m_Normal, m_L1, m_L2, pMaterial);
00312 GLC_3DWidget::add3DViewInstance(cuttingPlaneInstance);
00313
00314
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
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
00329 GLC_3DRep normalLine(pArrow);
00330 normalLine.addGeom(pDisc);
00331 GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(normalLine));
00332 GLC_3DWidget::set3DViewInstanceVisibility(1, false);
00333
00334
00335 const double initRadius= 1;
00336
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
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
00353 pDisc= new GLC_Disc(initRadius);
00354 pMaterial= new GLC_Material(Qt::blue);
00355 pMaterial->setOpacity(m_Opacity);
00356 pDisc->replaceMasterMaterial(pMaterial);
00357
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
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
00374 QVector<GLC_Matrix4x4> rotations(3);
00375 rotations[0].setMatRot(glc::Y_AXIS, glc::PI / 2.0);
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);
00378
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