00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
00276 for (int i= 0; i < 5; ++i)
00277 {
00278 GLC_3DWidget::instanceHandle(i)->multMatrix(moveMatrix);
00279 }
00280
00281
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
00296 GLC_Material* pMaterial= new GLC_Material(m_Color);
00297 pMaterial->setOpacity(m_Opacity);
00298
00299
00300 GLC_3DViewInstance cuttingPlaneInstance= GLC_Factory::instance()->createCuttingPlane(m_Center, m_Normal, m_L1, m_L2, pMaterial);
00301 GLC_3DWidget::add3DViewInstance(cuttingPlaneInstance);
00302
00303
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
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
00318 GLC_3DRep normalLine(pArrow);
00319 normalLine.addGeom(pDisc);
00320 GLC_3DWidget::add3DViewInstance(GLC_3DViewInstance(normalLine));
00321 GLC_3DWidget::set3DViewInstanceVisibility(1, false);
00322
00323
00324 const double initRadius= 1;
00325
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
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
00342 pDisc= new GLC_Disc(initRadius);
00343 pMaterial= new GLC_Material(Qt::blue);
00344 pMaterial->setOpacity(m_Opacity);
00345 pDisc->replaceMasterMaterial(pMaterial);
00346
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
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
00375 QVector<GLC_Matrix4x4> rotations(3);
00376 rotations[0].setMatRot(glc::Y_AXIS, glc::PI / 2.0);
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);
00379
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