diff --git a/src/Gui/SoDatumLabel.cpp b/src/Gui/SoDatumLabel.cpp
index 9ab80a1f4b..05d005880a 100644
--- a/src/Gui/SoDatumLabel.cpp
+++ b/src/Gui/SoDatumLabel.cpp
@@ -615,11 +615,13 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action)
}
// Perp Lines
glBegin(GL_LINES);
+ if (length != 0.) {
glVertex2f(p1[0], p1[1]);
glVertex2f(perp1[0], perp1[1]);
glVertex2f(p2[0], p2[1]);
glVertex2f(perp2[0], perp2[1]);
+ }
glVertex2f(par1[0], par1[1]);
glVertex2f(par2[0], par2[1]);
diff --git a/src/Gui/TaskView/TaskImage.cpp b/src/Gui/TaskView/TaskImage.cpp
index c9d955b0b1..980446d490 100644
--- a/src/Gui/TaskView/TaskImage.cpp
+++ b/src/Gui/TaskView/TaskImage.cpp
@@ -37,12 +37,14 @@
#include
#include
+#include
#include
#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -240,8 +242,6 @@ void TaskImage::rejectScale()
ui->pushButtonCancel->hide();
ui->quantitySpinBox->setEnabled(false);
ui->checkBoxOutside->setEnabled(true);
-
- scale->clearPoints();
}
void TaskImage::onInteractiveScale()
@@ -250,7 +250,7 @@ void TaskImage::onInteractiveScale()
View3DInventorViewer* viewer = getViewer();
if (viewer) {
auto vp = Application::Instance->getViewProvider(feature.get());
- scale = new InteractiveScale(viewer, vp);
+ scale = new InteractiveScale(viewer, vp, getNorm());
connect(scale, &InteractiveScale::selectedPoints,
this, &TaskImage::selectedPoints);
}
@@ -403,31 +403,51 @@ void TaskImage::updateIcon()
ui->previewLabel->size()));
}
+SbVec3f TaskImage::getNorm()
+{
+ if (feature.expired())
+ return SbVec3f(0., 0., 1.);
+
+ // Get imagePlane normal
+ Base::Vector3d RN(0, 0, 1);
+
+ // move to position of Sketch
+ Base::Placement Plz = feature->Placement.getValue();
+ Base::Rotation tmp(Plz.getRotation());
+ tmp.multVec(RN, RN);
+ Plz.setRotation(tmp);
+ return SbVec3f(RN.x, RN.y, RN.z);
+}
+
// ----------------------------------------------------------------------------
-InteractiveScale::InteractiveScale(View3DInventorViewer* view, ViewProvider* vp)
+InteractiveScale::InteractiveScale(View3DInventorViewer* view, ViewProvider* vp, SbVec3f normal)
: active{false}
, allowOutsideImage{false}
, viewer{view}
, viewProv{vp}
+ , norm{normal}
{
- coords = new SoCoordinate3;
- coords->ref();
root = new SoAnnotation;
root->ref();
+ root->renderCaching = SoSeparator::OFF;
- root->addChild(coords);
-
- SoBaseColor* color = new SoBaseColor;
- color->rgb.setValue(1.0F, 0.0F, 0.0F);
- root->addChild(color);
- root->addChild(new SoLineSet);
+ measureLabel = new SoDatumLabel();
+ measureLabel->ref();
+ measureLabel->norm.setValue(norm);
+ measureLabel->string = "";
+ measureLabel->textColor = SbColor(1.0f, 0.149f, 0.0f);
+ measureLabel->size.setValue(17);
+ measureLabel->lineWidth = 2.0;
+ measureLabel->useAntialiasing = false;
+ measureLabel->param1 = 0.;
+ measureLabel->param2 = 0.;
}
InteractiveScale::~InteractiveScale()
{
- coords->unref();
root->unref();
+ measureLabel->unref();
}
void InteractiveScale::activate(bool allowOutside)
@@ -447,6 +467,8 @@ void InteractiveScale::activate(bool allowOutside)
void InteractiveScale::deactivate()
{
if (viewer) {
+ points.clear();
+ root->removeChild(measureLabel);
static_cast(viewer->getSceneGraph())->removeChild(root);
viewer->setEditing(false);
viewer->removeEventCallback(SoLocation2Event::getClassTypeId(), InteractiveScale::getMousePosition, this);
@@ -473,12 +495,6 @@ double InteractiveScale::getDistance(const SbVec3f& pt) const
return (points[0] - pt).length();
}
-void InteractiveScale::clearPoints()
-{
- points.clear();
- coords->point.setNum(0);
-}
-
void InteractiveScale::findPointOnPlane(SoEventCallback * ecb)
{
if (allowOutsideImage) {
@@ -516,13 +532,13 @@ void InteractiveScale::collectPoint(const SbVec3f& pos3d)
{
if (points.empty()) {
points.push_back(pos3d);
- coords->point.set1Value(0, pos3d);
+
+ root->addChild(measureLabel);
}
else if (points.size() == 1) {
double distance = getDistance(pos3d);
if (distance > Base::Precision::Confusion()) {
points.push_back(pos3d);
- coords->point.set1Value(1, pos3d);
}
else {
Base::Console().Warning(std::string("Image scale"), "The second point is too close. Retry!\n");
@@ -551,9 +567,39 @@ void InteractiveScale::getMousePosition(void * ud, SoEventCallback * ecb)
if (scale->points.size() == 1) {
ecb->setHandled();
- auto pos2d = l2e->getPosition();
- auto pos3d = view->getPointOnFocalPlane(pos2d);
- scale->coords->point.set1Value(1, pos3d);
+ SbVec3f pos3d;
+ if (scale->allowOutsideImage) {
+ auto pos2d = l2e->getPosition();
+ pos3d = view->getPointOnFocalPlane(pos2d);
+ }
+ else {
+ std::unique_ptr pp(view->getPointOnRay(l2e->getPosition(), scale->viewProv));
+ if (pp.get()) {
+ pos3d = pp->getPoint();
+ }
+ else {
+ return;
+ }
+ }
+
+ Base::Quantity quantity;
+ quantity.setValue((pos3d - scale->points[0]).length());
+ quantity.setUnit(Base::Unit::Length);
+
+ //Update the displayed distance
+ double factor;
+ QString unitStr, valueStr;
+ valueStr = quantity.getUserString(factor, unitStr);
+ scale->measureLabel->string = SbString(valueStr.toUtf8().constData());
+
+ //Update the points.
+ scale->measureLabel->pnts.setNum(2);
+ SbVec3f* verts = scale->measureLabel->pnts.startEditing();
+
+ verts[0] = scale->points[0];
+ verts[1] = pos3d;
+
+ scale->measureLabel->pnts.finishEditing();
}
}
diff --git a/src/Gui/TaskView/TaskImage.h b/src/Gui/TaskView/TaskImage.h
index 43bc490171..b75ec22930 100644
--- a/src/Gui/TaskView/TaskImage.h
+++ b/src/Gui/TaskView/TaskImage.h
@@ -33,9 +33,8 @@
class SbVec3f;
class SoEventCallback;
-class SoCoordinate3;
class SoSeparator;
-class SoLineSet;
+class SoDatumLabel;
namespace Gui {
@@ -46,7 +45,7 @@ class InteractiveScale : public QObject
Q_OBJECT
public:
- explicit InteractiveScale(View3DInventorViewer* view, ViewProvider* vp);
+ explicit InteractiveScale(View3DInventorViewer* view, ViewProvider* vp, SbVec3f normal);
~InteractiveScale();
void activate(bool allowOutside);
void deactivate();
@@ -55,7 +54,6 @@ public:
}
double getDistance() const;
double getDistance(const SbVec3f&) const;
- void clearPoints();
private:
static void getMouseClick(void * ud, SoEventCallback * ecb);
@@ -71,11 +69,12 @@ Q_SIGNALS:
private:
bool active;
bool allowOutsideImage;
- SoCoordinate3* coords;
SoSeparator* root;
+ SoDatumLabel* measureLabel;
QPointer viewer;
ViewProvider* viewProv;
std::vector points;
+ SbVec3f norm;
};
class Ui_TaskImage;
@@ -102,6 +101,7 @@ private:
void startScale();
void acceptScale();
void rejectScale();
+ SbVec3f getNorm();
void restore(const Base::Placement&);
void onPreview();