Sketcher: Sketch autoscale (#21084)

* Working scale prototype

* Call viewAll to fit geometries in the viewport post-scaling

* Exclude angle dimensions

* Scale the viewport rather than calling viewAll

* Scale dimension annotation along geometries

* Early return when counting more than one dimensional constraint

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Disable sketch autoscale if there are external geometries in the sketch

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add a setting to disable the feature _ and eventually parametrize

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check for objects in the viewport in the sketch's ancestry to decide wheter or not to autoscale

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* More consistent camera scaling

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check for visual indicator in the whole document

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Find visible items in nested assemblies

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Check visual elements in assemblies nested in assemblies

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Set the dimension even if the scaling fails

* Allow constraints that interact with the origin axis/root

* Remove unused variable

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Misc fixes from review

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
theo-vt
2025-06-09 12:31:44 -04:00
committed by GitHub
parent 53737ed389
commit 353c4eca55
17 changed files with 398 additions and 70 deletions

View File

@@ -606,16 +606,30 @@ void NavigationStyle::boxZoom(const SbBox2s& box)
// Set height or height angle of the camera
float scaleX = (float)sizeX/(float)size[0];
float scaleY = (float)sizeY/(float)size[1];
float scale = std::max<float>(scaleX, scaleY);
if (cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
float height = static_cast<SoOrthographicCamera*>(cam)->height.getValue() * scale;
static_cast<SoOrthographicCamera*>(cam)->height = height;
}
else if (cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
float height = static_cast<SoPerspectiveCamera*>(cam)->heightAngle.getValue() / 2.0f;
height = 2.0f * atan(tan(height) * scale);
static_cast<SoPerspectiveCamera*>(cam)->heightAngle = height;
float scaleFactor = std::max<float>(scaleX, scaleY);
doScale(cam, scaleFactor);
}
void NavigationStyle::scale(float factor)
{
SoCamera* cam = viewer->getSoRenderManager()->getCamera();
if (!cam) { // no camera
return;
}
// Find the current center of the screen
SbVec3f direction;
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
SbVec3f initCenter = cam->position.getValue() + cam->focalDistance.getValue() * direction;
// Move the camera to the origin for scaling
cam->position = cam->position.getValue() - initCenter;
// Scale the view
doScale(cam, factor);
// Move the camera back to it's initial position scaled
cam->position = cam->position.getValue() + initCenter * factor;
}
void NavigationStyle::viewAll()
@@ -954,7 +968,18 @@ void NavigationStyle::doZoom(SoCamera* camera, float logfactor, const SbVec2f& p
}
}
}
void NavigationStyle::doScale(SoCamera * cam, float factor)
{
if (cam->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
float height = static_cast<SoOrthographicCamera*>(cam)->height.getValue() * factor;
static_cast<SoOrthographicCamera*>(cam)->height = height;
}
else if (cam->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
float height = static_cast<SoPerspectiveCamera*>(cam)->heightAngle.getValue() / 2.0f;
height = 2.0f * atan(tan(height) * factor);
static_cast<SoPerspectiveCamera*>(cam)->heightAngle = height;
}
}
void NavigationStyle::doRotate(SoCamera * camera, float angle, const SbVec2f& pos)
{
SbBool zoomAtCur = this->zoomAtCursor;

View File

@@ -165,6 +165,8 @@ public:
void reorientCamera(SoCamera* camera, const SbRotation& rotation, const SbVec3f& rotationCenter);
void boxZoom(const SbBox2s& box);
// Scale the camera inplace
void scale(float factor);
virtual void viewAll();
void setViewingMode(const ViewerMode newmode);
@@ -221,6 +223,7 @@ protected:
virtual void zoomByCursor(const SbVec2f & thispos, const SbVec2f & prevpos);
void doZoom(SoCamera * camera, int wheeldelta, const SbVec2f& pos);
void doZoom(SoCamera * camera, float logzoomfactor, const SbVec2f& pos);
void doScale(SoCamera * camera, float factor);
void doRotate(SoCamera * camera, float angle, const SbVec2f& pos);
void spin(const SbVec2f & pointerpos);
SbBool doSpin();

View File

@@ -3378,6 +3378,10 @@ void View3DInventorViewer::boxZoom(const SbBox2s& box)
{
navigation->boxZoom(box);
}
void View3DInventorViewer::scale(float factor)
{
navigation->scale(factor);
}
SbBox3f View3DInventorViewer::getBoundingBox() const
{

View File

@@ -407,6 +407,10 @@ public:
* Zooms the viewport to the size of the bounding box.
*/
void boxZoom(const SbBox2s&);
/**
* Scale the viewport by a linear amount
*/
void scale(float factor);
/**
* Reposition the current camera so we can see the complete scene.
*/

View File

@@ -886,6 +886,13 @@ int SketchObject::setDatum(int ConstrId, double Datum)
return err;
}
double SketchObject::getDatum(int ConstrId) const
{
if (!this->Constraints[ConstrId]->isDimensional()) {
return 0.0;
}
return this->Constraints[ConstrId]->getValue();
}
int SketchObject::setDriving(int ConstrId, bool isdriving)
{
@@ -7596,6 +7603,22 @@ int SketchObject::getGeoIdFromCompleteGeometryIndex(int completeGeometryIndex) c
else
return (completeGeometryIndex - completeGeometryCount);
}
bool SketchObject::hasSingleScaleDefiningConstraint() const
{
const std::vector<Constraint*>& vals = this->Constraints.getValues();
bool foundOne = false;
for (auto val : vals) {
// An angle does not define scale
if (val->isDimensional() && val->Type != Angle) {
if (foundOne) {
return false;
}
foundOne = true;
}
}
return foundOne;
}
std::unique_ptr<const GeometryFacade> SketchObject::getGeometryFacade(int GeoId) const
{

View File

@@ -272,6 +272,8 @@ public:
int getGeoIdFromCompleteGeometryIndex(int completeGeometryIndex) const;
bool hasSingleScaleDefiningConstraint() const;
/// returns non zero if the sketch contains conflicting constraints
int hasConflicts() const;
/**
@@ -299,6 +301,8 @@ public:
int solve(bool updateGeoAfterSolving = true);
/// set the datum of a Distance or Angle constraint and solve
int setDatum(int ConstrId, double Datum);
/// get the datum of a Distance or Angle constraint
double getDatum(int ConstrId) const;
/// set the driving status of this constraint and solve
int setDriving(int ConstrId, bool isdriving);
/// get the driving status of this constraint

View File

@@ -75,6 +75,7 @@ SET(SketcherGui_SRCS
CommandCreateGeo.cpp
CommandConstraints.h
CommandConstraints.cpp
CommandSketcherTools.h
CommandSketcherTools.cpp
CommandSketcherBSpline.cpp
CommandSketcherOverlay.cpp

View File

@@ -42,16 +42,23 @@
#include <Gui/Document.h>
#include <Gui/MainWindow.h>
#include <Gui/Notifications.h>
#include <Gui/View3DInventor.h>
#include <Gui/Selection/Selection.h>
#include <Gui/Selection/SelectionObject.h>
#include <Mod/Sketcher/App/PythonConverter.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/Sketcher/App/SolverGeometryExtension.h>
#include <Gui/Application.h>
#include <Base/ServiceProvider.h>
#include <App/Services.h>
#include "CommandSketcherTools.h"
#include "DrawSketchHandler.h"
#include "SketchRectangularArrayDialog.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include <Inventor/actions/SoGetBoundingBoxAction.h>
#include "DrawSketchHandlerTranslate.h"
#include "DrawSketchHandlerOffset.h"
@@ -2522,3 +2529,24 @@ void CreateSketcherCommandsConstraintAccel()
rcCmdMgr.addCommand(new CmdSketcherPaste());
}
// clang-format on
void SketcherGui::centerScale(Sketcher::SketchObject* Obj, double scaleFactor)
{
std::vector<int> allGeoIds(Obj->Geometry.getValues().size());
std::iota(allGeoIds.begin(), allGeoIds.end(), 0);
Gui::Document* doc = Gui::Application::Instance->activeDocument();
auto* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
auto scaler = DrawSketchHandlerScale::make_centerScale(allGeoIds, scaleFactor, false);
scaler->setSketchGui(vp);
scaler->executeCommands();
if (auto* view3d = dynamic_cast<Gui::View3DInventor*>(doc->getActiveView())) {
auto viewer = view3d->getViewer();
bool isAnimating = viewer->isAnimationEnabled();
viewer->setAnimationEnabled(false);
viewer->scale(scaleFactor);
viewer->setAnimationEnabled(isAnimating);
}
}

View File

@@ -0,0 +1,17 @@
#ifndef SKETCHERGUI_CommandSketcherTools_H
#define SKETCHERGUI_CommandSketcherTools_H
#include <Mod/Sketcher/App/SketchObject.h>
namespace SketcherGui
{
// These functions are declared here to promote code reuse from other modules
/// Scale the sketch around it's origin by a factor
/// and will not abort the current transaction if it fails
void centerScale(Sketcher::SketchObject* Obj, double scale_factor);
} // namespace SketcherGui
#endif // SKETCHERGUI_CommandSketcherTools_H

View File

@@ -309,6 +309,10 @@ void DrawSketchHandler::activate(ViewProviderSketch* vp)
sketchgui->purgeHandler();
}
}
void DrawSketchHandler::setSketchGui(ViewProviderSketch* vp)
{
sketchgui = vp;
}
void DrawSketchHandler::deactivate()
{

View File

@@ -145,6 +145,7 @@ public:
virtual ~DrawSketchHandler();
void activate(ViewProviderSketch*);
void setSketchGui(ViewProviderSketch* vp);
void deactivate() override;
virtual void mouseMove(Base::Vector2d pos) = 0;

View File

@@ -40,6 +40,8 @@
#include "GeometryCreationMode.h"
#include "Utils.h"
#include <memory>
using namespace Sketcher;
namespace SketcherGui
@@ -71,6 +73,8 @@ public:
explicit DrawSketchHandlerScale(std::vector<int> listOfGeoIds)
: listOfGeoIds(listOfGeoIds)
, deleteOriginal(true)
, abortOnFail(true)
, allowOriginConstraint(false)
, refLength(0.0)
, length(0.0)
, scaleFactor(0.0)
@@ -83,6 +87,51 @@ public:
~DrawSketchHandlerScale() override = default;
static std::unique_ptr<DrawSketchHandlerScale>
make_centerScale(std::vector<int> listOfGeoIds, double scaleFactor, bool abortOnFail)
{
auto out = std::make_unique<DrawSketchHandlerScale>(listOfGeoIds);
out->referencePoint = Base::Vector2d(0.0, 0.0);
out->scaleFactor = scaleFactor;
out->abortOnFail = abortOnFail;
out->allowOriginConstraint = true;
return out;
}
public:
void executeCommands() override
{
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Scale geometries"));
createShape(false);
commandAddShapeGeometryAndConstraints();
if (deleteOriginal) {
deleteOriginalGeos();
}
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
e.reportException();
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to scale"));
if (abortOnFail) {
Gui::Command::abortCommand();
}
THROWM(Base::RuntimeError,
QT_TRANSLATE_NOOP(
"Notifications",
"Tool execution aborted") "\n") // This prevents constraints from being
// applied on non existing geometry
}
}
private:
void updateDataAndDrawToPosition(Base::Vector2d onSketchPos) override
{
@@ -109,36 +158,6 @@ private:
}
}
void executeCommands() override
{
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Scale geometries"));
createShape(false);
commandAddShapeGeometryAndConstraints();
if (deleteOriginal) {
deleteOriginalGeos();
}
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
e.reportException();
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to scale"));
Gui::Command::abortCommand();
THROWM(Base::RuntimeError,
QT_TRANSLATE_NOOP(
"Notifications",
"Tool execution aborted") "\n") // This prevents constraints from being
// applied on non existing geometry
}
}
void createAutoConstraints() override
{
// none
@@ -204,8 +223,12 @@ private:
std::vector<int> listOfGeoIds;
Base::Vector2d referencePoint, startPoint, endPoint;
bool deleteOriginal;
bool abortOnFail; // When the scale operation is part of a larger transaction, one might want
// to continue even if the scaling failed
bool allowOriginConstraint; // Conserve constraints with origin
double refLength, length, scaleFactor;
void deleteOriginalGeos()
{
std::stringstream stream;
@@ -340,48 +363,75 @@ private:
std::vector<int> geoIdsWhoAlreadyHasEqual = {};
for (auto& cstr : vals) {
if (skipConstraint(cstr)) {
continue;
}
int firstIndex = indexOfGeoId(listOfGeoIds, cstr->First);
int secondIndex = indexOfGeoId(listOfGeoIds, cstr->Second);
int thirdIndex = indexOfGeoId(listOfGeoIds, cstr->Third);
auto newConstr = std::unique_ptr<Constraint>(cstr->copy());
newConstr->First = firstCurveCreated + firstIndex;
newConstr->First = offsetGeoID(firstIndex, firstCurveCreated);
if ((cstr->Type == Symmetric || cstr->Type == Tangent || cstr->Type == Perpendicular
|| cstr->Type == Angle)
&& firstIndex >= 0 && secondIndex >= 0 && thirdIndex >= 0) {
newConstr->Second = firstCurveCreated + secondIndex;
newConstr->Third = firstCurveCreated + thirdIndex;
&& secondIndex != GeoEnum::GeoUndef && thirdIndex != GeoEnum::GeoUndef) {
newConstr->Second = offsetGeoID(secondIndex, firstCurveCreated);
newConstr->Third = offsetGeoID(thirdIndex, firstCurveCreated);
}
else if ((cstr->Type == Coincident || cstr->Type == Tangent
|| cstr->Type == Symmetric || cstr->Type == Perpendicular
|| cstr->Type == Parallel || cstr->Type == Equal || cstr->Type == Angle
|| cstr->Type == PointOnObject || cstr->Type == InternalAlignment)
&& firstIndex >= 0 && secondIndex >= 0
&& thirdIndex == GeoEnum::GeoUndef) {
newConstr->Second = firstCurveCreated + secondIndex;
&& secondIndex != GeoEnum::GeoUndef && thirdIndex == GeoEnum::GeoUndef) {
newConstr->Second = offsetGeoID(secondIndex, firstCurveCreated);
}
else if ((cstr->Type == Radius || cstr->Type == Diameter) && firstIndex >= 0) {
else if (cstr->Type == Radius || cstr->Type == Diameter) {
newConstr->setValue(newConstr->getValue() * scaleFactor);
}
else if ((cstr->Type == Distance || cstr->Type == DistanceX
|| cstr->Type == DistanceY)
&& firstIndex >= 0 && secondIndex >= 0) {
newConstr->Second = firstCurveCreated + secondIndex;
&& secondIndex != GeoEnum::GeoUndef) {
newConstr->Second = offsetGeoID(secondIndex, firstCurveCreated);
newConstr->setValue(newConstr->getValue() * scaleFactor);
}
else if ((cstr->Type == Block || cstr->Type == Weight) && firstIndex >= 0) {
newConstr->First = firstCurveCreated + firstIndex;
}
else {
continue;
}
// (cstr->Type == Block || cstr->Type == Weight)
ShapeConstraints.push_back(std::move(newConstr));
}
}
}
bool skipConstraint(const Constraint* constr) const
{
// We might want to skip (remove) a constraint if
return
// 1. it's first geometry is undefined => not a valid constraint, should not happen
(constr->First == GeoEnum::GeoUndef)
// 2. we do not want to have constraints that relate to the origin => it would break if
// the scale center is not the origin
|| (!allowOriginConstraint
&& (constr->First == GeoEnum::VAxis || constr->First == GeoEnum::HAxis
|| constr->Second == GeoEnum::VAxis || constr->Second == GeoEnum::HAxis
|| constr->Third == GeoEnum::VAxis || constr->Third == GeoEnum::HAxis))
// 3. it is linked to an external projected geometry => would be unstable
|| (constr->First != GeoEnum::GeoUndef && constr->First <= GeoEnum::RefExt)
|| (constr->Second != GeoEnum::GeoUndef && constr->Second <= GeoEnum::RefExt)
|| (constr->Third != GeoEnum::GeoUndef && constr->Third <= GeoEnum::RefExt);
}
// Offset the geom index to match the newly created one
// except if it is negative in which case it is external
// or origin which remain unchanged
// this assumes that a call to skipConstraint() has been
// performed and that the constraint is valid within the context
// of the scale operation
int offsetGeoID(int index, int firstCurveCreated)
{
return index < 0 ? index : index + firstCurveCreated;
}
Base::Vector3d getScaledPoint(Base::Vector3d&& pointToScale,
const Base::Vector2d& referencePoint,
double scaleFactor)

View File

@@ -37,14 +37,20 @@
#include <Gui/Notifications.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Gui/Document.h>
#include <Mod/Sketcher/App/GeometryFacade.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <App/Datums.h>
#include "EditDatumDialog.h"
#include "CommandSketcherTools.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "SketcherSettings.h"
#include "ui_InsertDatum.h"
#include <numeric>
using namespace SketcherGui;
@@ -222,6 +228,9 @@ void EditDatumDialog::accepted()
else {
auto unitString = newQuant.getUnit().getString();
unitString = Base::Tools::escapeQuotesFromString(unitString);
performAutoScale(newDatum);
Gui::cmdAppObjectArgs(sketch,
"setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr,
@@ -318,4 +327,102 @@ void EditDatumDialog::formEditorOpened(bool state)
}
}
// This function checks an object's visible flag recursively in a Gui::Document
// assuming that lastParent (if provided) is visible
bool isVisibleUpTo(App::DocumentObject* obj, Gui::Document* doc, App::DocumentObject* lastParent)
{
while (obj && obj != lastParent) {
auto parentviewprovider = doc->getViewProvider(obj);
if (!parentviewprovider || !parentviewprovider->isVisible()) {
return false;
}
obj = obj->getFirstParent();
}
return true;
}
bool hasVisualFeature(App::DocumentObject* obj, App::DocumentObject* rootObj, Gui::Document* doc)
{
auto docObjects = doc->getDocument()->getObjects();
for (auto object : docObjects) {
// Presumably, the sketch that is being edited has visual features, but
// that's not interesting
if (object == obj) {
continue;
}
// No need to continue analysis if the object's visible flag is down
bool visible = isVisibleUpTo(object, doc, rootObj);
if (!visible) {
continue;
}
App::DocumentObject* link = object->getLinkedObject();
if (link->getDocument() != doc->getDocument()) {
Gui::Document* linkDoc = Gui::Application::Instance->getDocument(link->getDocument());
if (linkDoc && hasVisualFeature(link, link, linkDoc)) {
return true;
}
continue;
}
// Skip objects that are not of geometric nature
if (!object->isDerivedFrom<App::GeoFeature>()) {
continue;
}
// Skip datum objects
if (object->isDerivedFrom<App::DatumElement>()) {
continue;
}
// Skip container objects because getting their bounging box might
// return a valid bounding box around annotations or datums
if (object->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) {
continue;
}
// Get the bounding box of the object
auto viewProvider = doc->getViewProvider(object);
if (viewProvider && viewProvider->getBoundingBox().IsValid()) {
return true;
}
}
return false;
}
void EditDatumDialog::performAutoScale(double newDatum)
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/dimensioning");
long autoScaleMode =
hGrp->GetInt("AutoScaleMode", static_cast<int>(SketcherGui::AutoScaleMode::Always));
// There is a single constraint in the sketch so it can
// be used as a reference to scale the geometries around the origin
// if there are external geometries, it is safe to assume that the sketch
// was drawn with these geometries as scale references (use <= 2 because
// the sketch axis are considered as external geometries)
if ((autoScaleMode == static_cast<int>(SketcherGui::AutoScaleMode::Always)
|| (autoScaleMode
== static_cast<int>(SketcherGui::AutoScaleMode::WhenNoScaleFeatureIsVisible)
&& !hasVisualFeature(sketch, nullptr, Gui::Application::Instance->activeDocument())))
&& sketch->getExternalGeometryCount() <= 2 && sketch->hasSingleScaleDefiningConstraint()) {
try {
double oldDatum = sketch->getDatum(ConstrNbr);
double scale_factor = newDatum / oldDatum;
float initLabelDistance = sketch->Constraints[ConstrNbr]->LabelDistance;
float initLabelPosition = sketch->Constraints[ConstrNbr]->LabelPosition;
centerScale(sketch, scale_factor);
sketch->setLabelDistance(ConstrNbr, initLabelDistance * scale_factor);
sketch->setLabelPosition(ConstrNbr, initLabelPosition * scale_factor);
}
catch (const Base::Exception& e) {
Base::Console().error("Exception performing autoscale: %s\n", e.what());
}
}
}
#include "moc_EditDatumDialog.cpp"

View File

@@ -65,6 +65,9 @@ private Q_SLOTS:
void drivingToggled(bool);
void datumChanged();
void formEditorOpened(bool);
private:
void performAutoScale(double newDatum);
};
} // namespace SketcherGui

View File

@@ -165,6 +165,9 @@ void SketcherSettings::saveSettings()
hGrp->SetBool("DimensioningDiameter", Diameter);
hGrp->SetBool("DimensioningRadius", Radius);
index = ui->autoScaleMode->currentIndex();
hGrp->SetInt("AutoScaleMode", index);
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/Tools");
@@ -221,6 +224,16 @@ void SketcherSettings::loadSettings()
index = Diameter ? (Radius ? 0 : 1) : 2;
ui->radiusDiameterMode->setCurrentIndex(index);
// The items have to be added in the same order
// as the AutoScaleMode enum
ui->autoScaleMode->clear();
ui->autoScaleMode->addItem(tr("Always"));
ui->autoScaleMode->addItem(tr("Never"));
ui->autoScaleMode->addItem(tr("When no scale feature is visible"));
index = hGrp->GetInt("AutoScaleMode", static_cast<int>(AutoScaleMode::Always));
ui->autoScaleMode->setCurrentIndex(index);
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/Tools");
ui->ovpVisibility->clear();
@@ -281,6 +294,8 @@ void SketcherSettings::resetSettingsToDefaults()
hGrp->RemoveBool("DimensioningDiameter");
hGrp->RemoveBool("DimensioningRadius");
hGrp->RemoveInt("AutoScaleMode");
hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/Tools");
// reset "OVP visibility" parameter

View File

@@ -128,6 +128,19 @@ private:
std::unique_ptr<Ui_SketcherSettingsAppearance> ui;
};
// Mode for the sketch autoscale feature which scales
// the geometry and zooms the camera when the first
// scale defining constraint is set
enum class AutoScaleMode : int
{
Always = 0,
Never = 1,
// Attempts to find scale reference objects int the viewport
// (such as a 3d body) and disable the feature if it finds one
WhenNoScaleFeatureIsVisible = 2
};
} // namespace SketcherGui
#endif // SKETCHERGUI_SKETCHERSETTINGS_H

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>500</width>
<height>536</height>
<height>592</height>
</rect>
</property>
<property name="windowTitle">
@@ -250,14 +250,17 @@ Requires to re-enter edit mode to take effect.</string>
<string>Dimension constraint</string>
</property>
<layout class="QGridLayout" name="gridLayout_general">
<item row="0" column="0">
<widget class="QLabel" name="dimensioningLabel">
<property name="text">
<string>Dimensioning constraints:</string>
<item row="1" column="1">
<widget class="QComboBox" name="radiusDiameterMode">
<property name="toolTip">
<string>While using the Dimension tool you may choose how to handle circles and arcs:
'Auto': The tool will apply radius to arcs and diameter to circles.
'Diameter': The tool will apply diameter to both arcs and circles.
'Radius': The tool will apply radius to both arcs and circles.</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="1">
<widget class="QComboBox" name="dimensioningMode">
<property name="toolTip">
<string>Select the type of dimensioning constraints for your toolbar:
@@ -275,16 +278,39 @@ This setting is only for the toolbar. Whichever you choose, all tools are always
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="radiusDiameterMode">
<property name="toolTip">
<string>While using the Dimension tool you may choose how to handle circles and arcs:
'Auto': The tool will apply radius to arcs and diameter to circles.
'Diameter': The tool will apply diameter to both arcs and circles.
'Radius': The tool will apply radius to both arcs and circles.</string>
<item row="0" column="0">
<widget class="QLabel" name="dimensioningLabel">
<property name="text">
<string>Dimensioning constraints:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="autoScaleModeLabel">
<property name="text">
<string>Scale upon first constraint</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="autoScaleMode">
<item>
<property name="text">
<string>Always</string>
</property>
</item>
<item>
<property name="text">
<string>Never</string>
</property>
</item>
<item>
<property name="text">
<string>Only if there is no visual scale indicator</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
@@ -307,7 +333,7 @@ This setting is only for the toolbar. Whichever you choose, all tools are always
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="1">
<widget class="QComboBox" name="ovpVisibility">
<property name="toolTip">
<string>Choose a visibility mode for the On-View-Parameters: