Skip to content

Commit 1531ef3

Browse files
committed
The cross section box orientation can now be setup via the 'advanced' button
1 parent fd1f2f2 commit 1531ef3

File tree

6 files changed

+565
-39
lines changed

6 files changed

+565
-39
lines changed

libs/qCC_db/ccClipBox.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ bool ccClipBox::move3D(const CCVector3d& uInput)
436436
{
437437
//we guess the rotation order by comparing the current screen 'normal'
438438
//and the vector prod of u and the current rotation axis
439-
CCVector3d Rb(0,0,0);
439+
CCVector3d Rb(0, 0, 0);
440440
switch(m_activeComponent)
441441
{
442442
case X_MINUS_TORUS:
@@ -464,7 +464,9 @@ bool ccClipBox::move3D(const CCVector3d& uInput)
464464

465465
CCVector3d R = Rb;
466466
if (m_glTransEnabled)
467+
{
467468
m_glTrans.applyRotation(R);
469+
}
468470

469471
CCVector3d RxU = R.cross(u);
470472

@@ -480,12 +482,12 @@ bool ccClipBox::move3D(const CCVector3d& uInput)
480482
}
481483

482484
//angle is proportional to absolute displacement
483-
double angle_rad = u.norm()/m_box.getDiagNorm() * M_PI;
485+
double angle_rad = u.norm() / m_box.getDiagNorm() * M_PI;
484486
if (maxDot < 0.0)
485487
angle_rad = -angle_rad;
486488

487489
ccGLMatrixd rotMat;
488-
rotMat.initFromParameters(angle_rad,Rb,CCVector3d(0,0,0));
490+
rotMat.initFromParameters(angle_rad, Rb, CCVector3d(0, 0, 0));
489491

490492
CCVector3 C = m_box.getCenter();
491493
ccGLMatrixd transMat;

qCC/bin_other/history.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
v2.6.3.1 - 03/XX/2016
44

55
- Enhancements:
6+
67
* Camera sensors can now be created 'freely' (i.e. not necessarily attached to a given entity) and moved freely in the DB tree
78

9+
* The cross section box orientation can now be setup via the 'advanced' button
10+
811
- Bug fixes:
912
* The meshes over the user-specified limit (display options) were ALWAYS decimated (and not only when the mouse is moved)
1013
* 2D area label picking was broken (first corner was misplaced)

qCC/ccBoundingBoxEditorDlg.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ ccBoundingBoxEditorDlg::ccBoundingBoxEditorDlg(QWidget* parent/*=0*/)
2929
{
3030
setupUi(this);
3131

32+
showBoxAxes(false);
33+
3234
xDoubleSpinBox->setMinimum(-1.0e9);
3335
yDoubleSpinBox->setMinimum(-1.0e9);
3436
zDoubleSpinBox->setMinimum(-1.0e9);
@@ -58,6 +60,16 @@ ccBoundingBoxEditorDlg::ccBoundingBoxEditorDlg(QWidget* parent/*=0*/)
5860
connect(dyDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateYWidth(double)));
5961
connect(dzDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateZWidth(double)));
6062

63+
connect(xOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
64+
connect(xOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
65+
connect(xOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
66+
connect(yOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
67+
connect(yOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
68+
connect(yOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
69+
connect(zOriXDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
70+
connect(zOriYDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
71+
connect(zOriZDoubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(onAxisValueChanged(double)));
72+
6173
defaultPushButton->setVisible(false);
6274
lastPushButton->setVisible(s_lastBBox.isValid());
6375
checkBaseInclusion();
@@ -196,6 +208,30 @@ void ccBoundingBoxEditorDlg::resetToLast()
196208

197209
void ccBoundingBoxEditorDlg::saveBoxAndAccept()
198210
{
211+
if (oriGroupBox->isVisible())
212+
{
213+
CCVector3 X, Y, Z;
214+
getBoxAxes(X, Y, Z);
215+
X.normalize();
216+
Y.normalize();
217+
Z.normalize();
218+
if ( X.norm2d() == 0
219+
|| Y.norm2d() == 0
220+
|| Z.norm2d() == 0 )
221+
{
222+
ccLog::Error("Invalid axes definition: at least two vectors are colinear");
223+
return;
224+
}
225+
226+
//if ( fabs(X.dot(Y)) > 1.0e-6
227+
// || fabs(Y.dot(Z)) > 1.0e-6
228+
// || fabs(Z.dot(X)) > 1.0e-6 )
229+
//{
230+
// ccLog::Error("Invalid axes definition: vectors must be orthogonal");
231+
// return;
232+
//}
233+
}
234+
199235
s_lastBBox = m_currentBBox;
200236

201237
accept();
@@ -349,3 +385,90 @@ void ccBoundingBoxEditorDlg::reflectChanges(int dummy)
349385
dzDoubleSpinBox->blockSignals(false);
350386
}
351387
}
388+
389+
void ccBoundingBoxEditorDlg::showBoxAxes(bool state)
390+
{
391+
oriGroupBox->setVisible(state);
392+
393+
resize(QSize(600, state ? 400 : 250));
394+
}
395+
396+
void ccBoundingBoxEditorDlg::setBoxAxes(const CCVector3& X, const CCVector3& Y, const CCVector3& Z)
397+
{
398+
//if (xOriFrame->isEnabled())
399+
{
400+
xOriXDoubleSpinBox->setValue(X.x);
401+
xOriYDoubleSpinBox->setValue(X.y);
402+
xOriZDoubleSpinBox->setValue(X.z);
403+
}
404+
405+
//if (yOriFrame->isEnabled())
406+
{
407+
yOriXDoubleSpinBox->setValue(Y.x);
408+
yOriYDoubleSpinBox->setValue(Y.y);
409+
yOriZDoubleSpinBox->setValue(Y.z);
410+
}
411+
412+
//if (zOriFrame->isEnabled())
413+
{
414+
zOriXDoubleSpinBox->setValue(Z.x);
415+
zOriYDoubleSpinBox->setValue(Z.y);
416+
zOriZDoubleSpinBox->setValue(Z.z);
417+
}
418+
}
419+
420+
void ccBoundingBoxEditorDlg::getBoxAxes(CCVector3& X, CCVector3& Y, CCVector3& Z)
421+
{
422+
X = CCVector3( static_cast<PointCoordinateType>(xOriXDoubleSpinBox->value()),
423+
static_cast<PointCoordinateType>(xOriYDoubleSpinBox->value()),
424+
static_cast<PointCoordinateType>(xOriZDoubleSpinBox->value()) );
425+
426+
Y = CCVector3( static_cast<PointCoordinateType>(yOriXDoubleSpinBox->value()),
427+
static_cast<PointCoordinateType>(yOriYDoubleSpinBox->value()),
428+
static_cast<PointCoordinateType>(yOriZDoubleSpinBox->value()) );
429+
430+
Z = CCVector3( static_cast<PointCoordinateType>(zOriXDoubleSpinBox->value()),
431+
static_cast<PointCoordinateType>(zOriYDoubleSpinBox->value()),
432+
static_cast<PointCoordinateType>(zOriZDoubleSpinBox->value()) );
433+
}
434+
435+
void ccBoundingBoxEditorDlg::onAxisValueChanged(double)
436+
{
437+
CCVector3 X, Y, Z;
438+
getBoxAxes(X, Y, Z);
439+
440+
QDoubleSpinBox* vecSpinBoxes[3] = { 0, 0, 0 };
441+
CCVector3 N(0, 0, 0);
442+
if (oriXCheckBox->isChecked())
443+
{
444+
N = Y.cross(Z);
445+
vecSpinBoxes[0] = xOriXDoubleSpinBox;
446+
vecSpinBoxes[1] = xOriYDoubleSpinBox;
447+
vecSpinBoxes[2] = xOriZDoubleSpinBox;
448+
}
449+
else if (oriYCheckBox->isChecked())
450+
{
451+
N = Z.cross(X);
452+
vecSpinBoxes[0] = yOriXDoubleSpinBox;
453+
vecSpinBoxes[1] = yOriYDoubleSpinBox;
454+
vecSpinBoxes[2] = yOriZDoubleSpinBox;
455+
}
456+
else if (oriZCheckBox->isChecked())
457+
{
458+
N = X.cross(Y);
459+
vecSpinBoxes[0] = zOriXDoubleSpinBox;
460+
vecSpinBoxes[1] = zOriYDoubleSpinBox;
461+
vecSpinBoxes[2] = zOriZDoubleSpinBox;
462+
}
463+
else
464+
{
465+
assert(false);
466+
}
467+
468+
for (int i=0; i<3; ++i)
469+
{
470+
vecSpinBoxes[i]->blockSignals(true);
471+
vecSpinBoxes[i]->setValue(N.u[i]);
472+
vecSpinBoxes[i]->blockSignals(false);
473+
}
474+
}

qCC/ccBoundingBoxEditorDlg.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,20 @@ class ccBoundingBoxEditorDlg : public QDialog, public Ui::BoundingBoxEditorDialo
3434
explicit ccBoundingBoxEditorDlg(QWidget* parent = 0);
3535

3636
//! Returns bounding box
37-
ccBBox getBox() const { return m_currentBBox; }
37+
const ccBBox& getBox() const { return m_currentBBox; }
3838

39-
//! Sets (minimal) base box
39+
//! Sets the (minimal) base box
4040
/** \param box base box
4141
\param isMinimal set whether the user must define a bounding-box at least as large as this one
4242
**/
4343
void setBaseBBox(const ccBBox& box, bool isMinimal = true);
4444

45+
//! Sets the box axes
46+
void setBoxAxes(const CCVector3& X, const CCVector3& Y, const CCVector3& Z);
47+
48+
//! Returns the box axes
49+
void getBoxAxes(CCVector3& X, CCVector3& Y, CCVector3& Z);
50+
4551
//! Whether the warning about bounding box inclusion in the base one should be displayed or not
4652
/** True by default.
4753
**/
@@ -53,9 +59,12 @@ class ccBoundingBoxEditorDlg : public QDialog, public Ui::BoundingBoxEditorDialo
5359
//! Returns whether 'keep square' mode is enabled or not
5460
bool keepSquare() const;
5561

56-
//! Sets 2D mode ('dim' line will be hidden)
62+
//! Sets 2D mode (the line 'dim' will be hidden)
5763
void set2DMode(bool state, unsigned char dim);
5864

65+
//! Whether to display or not the box axes
66+
void showBoxAxes(bool state);
67+
5968
public slots:
6069

6170
//overloaded from QDialog
@@ -77,6 +86,9 @@ protected slots:
7786
void updateCurrentBBox(double dummy = 0.0);
7887
//! Reflects changes on bbox
7988
void reflectChanges(int dummy = 0);
89+
90+
//! Slot called anytime a component of the box axes is modified
91+
void onAxisValueChanged(double);
8092

8193
protected:
8294

qCC/ccClippingBoxTool.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,23 +116,59 @@ void ccClippingBoxTool::editBox()
116116
if (!m_clipBox)
117117
return;
118118

119-
ccBBox box = m_clipBox->getBox();
119+
ccBBox box;
120+
ccGLMatrix transformation;
121+
m_clipBox->get(box, transformation);
120122

121123
ccBoundingBoxEditorDlg bbeDlg(this);
122124
bbeDlg.setBaseBBox(box, false);
123125
bbeDlg.showInclusionWarning(false);
124126
bbeDlg.setWindowTitle("Edit clipping box");
127+
128+
//show the box 'axes' (orientation)
129+
bbeDlg.showBoxAxes(true);
130+
//transformation.invert();
131+
bbeDlg.setBoxAxes( transformation.getColumnAsVec3D(0),
132+
transformation.getColumnAsVec3D(1),
133+
transformation.getColumnAsVec3D(2) );
125134

126135
if (!bbeDlg.exec())
127136
return;
128137

129138
box = bbeDlg.getBox();
130139
m_clipBox->setBox(box);
131140

141+
//construct the local box orientation matrix
142+
{
143+
CCVector3 X, Y, Z;
144+
bbeDlg.getBoxAxes(X, Y, Z);
145+
//make sure the vectors define an orthogonal basis
146+
Z = X.cross(Y);
147+
Y = Z.cross(X);
148+
149+
X.normalize();
150+
Y.normalize();
151+
Z.normalize();
152+
ccGLMatrix rotMat;
153+
rotMat.setColumn(0, X);
154+
rotMat.setColumn(1, Y);
155+
rotMat.setColumn(2, Z);
156+
157+
CCVector3 C = box.getCenter();
158+
ccGLMatrix transMat;
159+
transMat.setTranslation(-C);
160+
transMat = rotMat.inverse() * transMat;
161+
transMat.setTranslation(transMat.getTranslationAsVec3D() + C);
162+
163+
m_clipBox->setGLTransformation(transMat.inverse());
164+
}
165+
132166
//onBoxModified(&box); //DGM: automatically called by 'm_clipBox'
133167

134168
if (m_associatedWin)
169+
{
135170
m_associatedWin->redraw();
171+
}
136172
}
137173

138174
void ccClippingBoxTool::toggleInteractors(bool state)
@@ -355,7 +391,7 @@ void ccClippingBoxTool::exportSlice()
355391
if (!obj)
356392
return;
357393

358-
ccHObject* result = GetSlice(obj,m_clipBox,false);
394+
ccHObject* result = GetSlice(obj, m_clipBox, false);
359395

360396
if (result)
361397
{
@@ -537,7 +573,7 @@ void ccClippingBoxTool::extractSlicesAndContours(bool extractSlices, bool extrac
537573
//single cloud: easy
538574
assert(slices.size() == 1);
539575

540-
slices[0] = GetSlice(obj,m_clipBox,false);
576+
slices[0] = GetSlice(obj, m_clipBox, false);
541577
if (!slices[0])
542578
{
543579
//error message already issued

0 commit comments

Comments
 (0)