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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user