PartDesign: Add preview TaskBox to all feature task dialogs

This commit is contained in:
Kacper Donat
2025-07-06 16:31:42 +02:00
parent 6caceacb95
commit 802af4c464
27 changed files with 242 additions and 41 deletions

View File

@@ -63,6 +63,8 @@ void DlgSettingsGeneral::saveSettings()
ui->checkObjectNaming->onSave();
ui->checkAllowCompoundBody->onSave();
ui->comboDefaultProfileTypeForHole->onSave();
ui->checkShowFinalPreview->onSave();
ui->checkShowTransparentPreview->onSave();
ui->checkSwitchToTask->onSave();
}
@@ -74,6 +76,8 @@ void DlgSettingsGeneral::loadSettings()
ui->checkObjectNaming->onRestore();
ui->checkAllowCompoundBody->onRestore();
ui->comboDefaultProfileTypeForHole->onRestore();
ui->checkShowFinalPreview->onRestore();
ui->checkShowTransparentPreview->onRestore();
ui->checkSwitchToTask->onRestore();
}

View File

@@ -21,11 +21,11 @@
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkBooleanCheck" native="true">
<property name="text" stdset="0">
<widget class="Gui::PrefCheckBox" name="checkBooleanCheck">
<property name="text">
<string>Automatically check model after boolean operation</string>
</property>
<property name="checked" stdset="0">
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
@@ -37,11 +37,11 @@
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::PrefCheckBox" name="checkBooleanRefine" native="true">
<property name="text" stdset="0">
<widget class="Gui::PrefCheckBox" name="checkBooleanRefine">
<property name="text">
<string>Automatically refine model after boolean operation</string>
</property>
<property name="checked" stdset="0">
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
@@ -53,11 +53,11 @@
</widget>
</item>
<item row="2" column="0">
<widget class="Gui::PrefCheckBox" name="checkSketchBaseRefine" native="true">
<property name="text" stdset="0">
<widget class="Gui::PrefCheckBox" name="checkSketchBaseRefine">
<property name="text">
<string>Automatically refine model after applying operations</string>
</property>
<property name="checked" stdset="0">
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
@@ -84,8 +84,8 @@
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="Gui::PrefCheckBox" name="checkObjectNaming" native="true">
<property name="text" stdset="0">
<widget class="Gui::PrefCheckBox" name="checkObjectNaming">
<property name="text">
<string>Add name of base object</string>
</property>
<property name="prefEntry" stdset="0">
@@ -172,6 +172,50 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxPreview">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Preview</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="Gui::PrefCheckBox" name="checkShowFinalPreview">
<property name="text">
<string>Show final result by default when editing feature</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>ShowFinal</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/PartDesign/Preview</cstring>
</property>
</widget>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="checkShowTransparentPreview">
<property name="text">
<string>Show transparent preview overlay by default when editing feature</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>ShowTransparentPreview</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/PartDesign/Preview</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBoxExperimental">
<property name="enabled">
@@ -213,7 +257,7 @@
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -227,13 +271,13 @@
</widget>
<customwidgets>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QWidget</extends>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
</customwidgets>

View File

@@ -117,6 +117,11 @@ SoPreviewShape::SoPreviewShape()
SoSeparator::addChild(annotation);
}
void SoPreviewShape::initClass()
{
SO_NODE_INIT_CLASS(SoPreviewShape, SoSeparator, "Separator");
}
EXTENSION_PROPERTY_SOURCE(PartGui::ViewProviderPreviewExtension, Gui::ViewProviderExtension)
ViewProviderPreviewExtension::ViewProviderPreviewExtension()

View File

@@ -57,6 +57,7 @@ public:
static const SbColor defaultColor;
SoPreviewShape();
static void initClass();
SoSFColor color;
SoSFFloat transparency;

View File

@@ -222,6 +222,45 @@ short Transformed::mustExecute() const
}
return PartDesign::Feature::mustExecute();
}
App::DocumentObjectExecReturn* Transformed::recomputePreview()
{
const auto mode = static_cast<Mode>(TransformMode.getValue());
const auto makeCompoundOfToolShapes = [this]() {
BRep_Builder builder;
TopoDS_Compound compound;
builder.MakeCompound(compound);
for (const auto& original : getOriginals()) {
if (auto* feature = freecad_cast<FeatureAddSub*>(original)) {
const auto& shape = feature->AddSubShape.getShape();
if (shape.isNull()) {
continue;
}
builder.Add(compound, shape.getShape());
}
}
return compound;
};
switch (mode) {
case Mode::TransformToolShapes:
PreviewShape.setValue(makeCompoundOfToolShapes());
return StdReturn;
case Mode::TransformBody:
PreviewShape.setValue(getBaseShape());
return StdReturn;
default:
return FeatureRefine::recomputePreview();
}
}
void Transformed::onChanged(const App::Property* prop)
{
if (prop == &TransformMode) {

View File

@@ -94,6 +94,8 @@ public:
short mustExecute() const override;
//@}
App::DocumentObjectExecReturn* recomputePreview() override;
void onChanged(const App::Property* prop) override;
/** returns the compound of the shapes that were rejected during the last execute

View File

@@ -44,6 +44,7 @@ set(PartDesignGui_UIC_SRCS
TaskScaledParameters.ui
TaskMultiTransformParameters.ui
TaskShapeBinder.ui
TaskPreviewParameters.ui
TaskPrimitiveParameters.ui
TaskPipeParameters.ui
TaskPipeOrientation.ui

View File

@@ -339,6 +339,7 @@ TaskDlgChamferParameters::TaskDlgChamferParameters(ViewProviderChamfer* DressUpV
parameter = new TaskChamferParameters(DressUpView);
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgChamferParameters::~TaskDlgChamferParameters() = default;

View File

@@ -34,6 +34,8 @@
#include <Mod/PartDesign/App/Feature.h>
#include <Mod/PartDesign/App/Body.h>
#include "ui_TaskPreviewParameters.h"
#include "TaskFeatureParameters.h"
#include "TaskSketchBasedParameters.h"
@@ -44,6 +46,55 @@ using namespace Gui;
* Task Feature Parameters *
*********************************************************************/
TaskPreviewParameters::TaskPreviewParameters(ViewProvider* vp, QWidget* parent)
: TaskBox(BitmapFactory().pixmap("tree-pre-sel"), tr("Preview"), true, parent)
, vp(vp)
, ui(std::make_unique<Ui_TaskPreviewParameters>())
{
vp->showPreviousFeature(!hGrp->GetBool("ShowFinal", false));
vp->showPreview(hGrp->GetBool("ShowTransparentPreview", true));
auto* proxy = new QWidget(this);
ui->setupUi(proxy);
ui->showFinalCheckBox->setChecked(vp->isVisible());
ui->showTransparentPreviewCheckBox->setChecked(vp->isPreviewEnabled());
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(ui->showTransparentPreviewCheckBox,
&QCheckBox::checkStateChanged,
this,
&TaskPreviewParameters::onShowPreviewChanged);
connect(ui->showFinalCheckBox,
&QCheckBox::checkStateChanged,
this,
&TaskPreviewParameters::onShowFinalChanged);
#else
connect(ui->showTransparentPreviewCheckBox,
&QCheckBox::stateChanged,
this,
&TaskPreviewParameters::onShowPreviewChanged);
connect(ui->showFinalCheckBox,
&QCheckBox::stateChanged,
this,
&TaskPreviewParameters::onShowFinalChanged);
#endif
groupLayout()->addWidget(proxy);
}
TaskPreviewParameters::~TaskPreviewParameters() = default;
void TaskPreviewParameters::onShowFinalChanged(bool show)
{
vp->showPreviousFeature(!show);
}
void TaskPreviewParameters::onShowPreviewChanged(bool show)
{
vp->showPreview(show);
}
TaskFeatureParameters::TaskFeatureParameters(PartDesignGui::ViewProvider *vp, QWidget *parent,
const std::string& pixmapname, const QString& parname)
: TaskBox(Gui::BitmapFactory().pixmap(pixmapname.c_str()), parname, true, parent)
@@ -52,9 +103,6 @@ TaskFeatureParameters::TaskFeatureParameters(PartDesignGui::ViewProvider *vp, QW
{
Gui::Document* doc = vp->getDocument();
this->attachDocument(doc);
vp->showPreviousFeature(true);
vp->showPreview(true);
}
void TaskFeatureParameters::slotDeletedObject(const Gui::ViewProviderDocumentObject& Obj)
@@ -83,7 +131,8 @@ void TaskFeatureParameters::recomputeFeature()
* Task Dialog *
*********************************************************************/
TaskDlgFeatureParameters::TaskDlgFeatureParameters(PartDesignGui::ViewProvider *vp)
: vp(vp)
: preview(new TaskPreviewParameters(vp))
, vp(vp)
{
assert(vp);
}

View File

@@ -33,6 +33,28 @@
namespace PartDesignGui {
class Ui_TaskPreviewParameters;
class TaskPreviewParameters : public Gui::TaskView::TaskBox
{
Q_OBJECT
public:
explicit TaskPreviewParameters(ViewProvider* vp, QWidget* parent = nullptr);
~TaskPreviewParameters() override;
public Q_SLOTS:
void onShowPreviewChanged(bool show);
void onShowFinalChanged(bool show);
private:
ViewProvider* vp;
std::unique_ptr<Ui_TaskPreviewParameters> ui;
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/PartDesign/Preview");
};
/// Convenience class to collect common methods for all SketchBased features
class TaskFeatureParameters : public Gui::TaskView::TaskBox,
public Gui::DocumentObserver
@@ -141,6 +163,9 @@ public:
return nullptr;
}
protected:
PartDesignGui::TaskPreviewParameters* preview;
private:
PartDesignGui::ViewProvider* vp;
};

View File

@@ -206,6 +206,7 @@ TaskDlgFilletParameters::TaskDlgFilletParameters(ViewProviderFillet* DressUpView
parameter = new TaskFilletParameters(DressUpView);
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgFilletParameters::~TaskDlgFilletParameters() = default;

View File

@@ -713,6 +713,7 @@ TaskDlgHelixParameters::TaskDlgHelixParameters(ViewProviderHelix* HelixView)
{
assert(HelixView);
Content.push_back(new TaskHelixParameters(HelixView));
Content.push_back(preview);
}

View File

@@ -1159,6 +1159,7 @@ TaskDlgHoleParameters::TaskDlgHoleParameters(ViewProviderHole* HoleView)
parameter = new TaskHoleParameters(HoleView);
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgHoleParameters::~TaskDlgHoleParameters() = default;

View File

@@ -432,6 +432,7 @@ TaskDlgLinearPatternParameters::TaskDlgLinearPatternParameters(
parameter = new TaskLinearPatternParameters(LinearPatternView);
Content.push_back(parameter);
Content.push_back(preview);
}
#include "moc_TaskLinearPatternParameters.cpp"

View File

@@ -381,6 +381,7 @@ TaskDlgLoftParameters::TaskDlgLoftParameters(ViewProviderLoft* LoftView, bool ne
parameter = new TaskLoftParameters(LoftView, newObj);
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgLoftParameters::~TaskDlgLoftParameters() = default;

View File

@@ -246,6 +246,7 @@ TaskDlgMirroredParameters::TaskDlgMirroredParameters(ViewProviderMirrored* Mirro
parameter = new TaskMirroredParameters(MirroredView);
Content.push_back(parameter);
Content.push_back(preview);
}
#include "moc_TaskMirroredParameters.cpp"

View File

@@ -559,6 +559,7 @@ TaskDlgMultiTransformParameters::TaskDlgMultiTransformParameters(
parameter->setEnabledTransaction(false);
Content.push_back(parameter);
Content.push_back(preview);
}
#include "moc_TaskMultiTransformParameters.cpp"

View File

@@ -140,6 +140,7 @@ TaskDlgPadParameters::TaskDlgPadParameters(ViewProviderPad *PadView, bool /*newO
: TaskDlgExtrudeParameters(PadView), parameters(new TaskPadParameters(PadView))
{
Content.push_back(parameters);
Content.push_back(preview);
}
//==== calls from the TaskView ===============================================================

View File

@@ -1132,6 +1132,7 @@ TaskDlgPipeParameters::TaskDlgPipeParameters(ViewProviderPipe* PipeView, bool ne
Content.push_back(parameter);
Content.push_back(orientation);
Content.push_back(scaling);
Content.push_back(preview);
parameter->stateHandler = stateHandler;
orientation->stateHandler = stateHandler;

View File

@@ -151,6 +151,7 @@ TaskDlgPocketParameters::TaskDlgPocketParameters(ViewProviderPocket *PocketView)
: TaskDlgExtrudeParameters(PocketView), parameters(new TaskPocketParameters(PocketView))
{
Content.push_back(parameters);
Content.push_back(preview);
}
#include "moc_TaskPocketParameters.cpp"

View File

@@ -426,6 +426,7 @@ TaskDlgPolarPatternParameters::TaskDlgPolarPatternParameters(
parameter = new TaskPolarPatternParameters(PolarPatternView);
Content.push_back(parameter);
Content.push_back(preview);
}
#include "moc_TaskPolarPatternParameters.cpp"

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PartDesignGui::TaskPreviewParameters</class>
<widget class="QWidget" name="PartDesignGui::TaskPreviewParameters">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>364</width>
<height>62</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="showFinalCheckBox">
<property name="text">
<string>Show final result</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showTransparentPreviewCheckBox">
<property name="text">
<string>Show preview overlay</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -985,6 +985,7 @@ TaskDlgPrimitiveParameters::TaskDlgPrimitiveParameters(ViewProviderPrimitive* Pr
Content.push_back(primitive);
parameter = new PartGui::TaskAttacher(PrimitiveView, nullptr, QString(), tr("Attachment"));
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgPrimitiveParameters::~TaskDlgPrimitiveParameters() = default;

View File

@@ -713,6 +713,7 @@ TaskDlgRevolutionParameters::TaskDlgRevolutionParameters(ViewProviderRevolution
{
assert(RevolutionView);
Content.push_back(new TaskRevolutionParameters(RevolutionView, "PartDesign_Revolution", tr("Revolution Parameters")));
Content.push_back(preview);
}
TaskDlgGrooveParameters::TaskDlgGrooveParameters(ViewProviderGroove *GrooveView)
@@ -720,6 +721,7 @@ TaskDlgGrooveParameters::TaskDlgGrooveParameters(ViewProviderGroove *GrooveView)
{
assert(GrooveView);
Content.push_back(new TaskRevolutionParameters(GrooveView, "PartDesign_Groove", tr("Groove Parameters")));
Content.push_back(preview);
}

View File

@@ -272,6 +272,7 @@ TaskDlgThicknessParameters::TaskDlgThicknessParameters(ViewProviderThickness* Dr
parameter = new TaskThicknessParameters(DressUpView);
Content.push_back(parameter);
Content.push_back(preview);
}
TaskDlgThicknessParameters::~TaskDlgThicknessParameters() = default;

View File

@@ -42,6 +42,7 @@
#include "ViewProviderTransformed.h"
#include "TaskTransformedParameters.h"
#include <BRep_Builder.hxx>
#include <Inventor/nodes/SoTransform.h>
using namespace PartDesignGui;
@@ -109,8 +110,6 @@ void ViewProviderTransformed::updatePreview()
return;
}
transforms.pop_front();
Gui::coinRemoveAllChildren(pcPreviewRoot);
for (const auto& transform : transforms) {
@@ -135,23 +134,6 @@ void ViewProviderTransformed::updatePreview()
ViewProvider::updatePreview();
}
Part::TopoShape ViewProviderTransformed::getPreviewShape() const
{
if (auto feature = getObject<PartDesign::Transformed>()) {
auto originals = feature->getOriginals();
if (originals.empty()) {
return {};
}
if (auto first = freecad_cast<PartDesign::Feature*>(originals.front())) {
return first->PreviewShape.getShape();
}
}
return {};
}
void ViewProviderTransformed::handleTransformedResult(PartDesign::Transformed* pcTransformed) {
unsigned rejected = 0;

View File

@@ -51,8 +51,6 @@ public:
void recomputeFeature(bool recompute=true);
void setupContextMenu(QMenu*, QObject*, const char*) override;
Part::TopoShape getPreviewShape() const override;
/// signals if the transformation contains errors
boost::signals2::signal<void (QString msg)> signalDiagnosis;