Merge pull request #14433 from kadet1090/feature-ui-for-up-to-shape

GUI: Add UI for Up To Shape feature
This commit is contained in:
Chris Hennes
2024-06-10 11:06:25 -05:00
committed by GitHub
20 changed files with 695 additions and 141 deletions

View File

@@ -61,6 +61,10 @@ public:
//@{
short mustExecute() const override;
void setupObject() override;
const char* getViewProviderName() const override {
return "PartDesignGui::ViewProviderExtrude";
}
//@}
protected:

View File

@@ -126,6 +126,7 @@ PyMOD_INIT_FUNC(PartDesignGui)
PartDesignGui::ViewProviderPython ::init();
PartDesignGui::ViewProviderBody ::init();
PartDesignGui::ViewProviderSketchBased ::init();
PartDesignGui::ViewProviderExtrude ::init();
PartDesignGui::ViewProviderPocket ::init();
PartDesignGui::ViewProviderHole ::init();
PartDesignGui::ViewProviderPad ::init();

View File

@@ -65,6 +65,8 @@ SET(PartDesignGuiViewProvider_SRCS
ViewProviderBody.h
ViewProviderSketchBased.cpp
ViewProviderSketchBased.h
ViewProviderExtrude.cpp
ViewProviderExtrude.h
ViewProviderPad.cpp
ViewProviderPad.h
ViewProviderHole.cpp

View File

@@ -23,15 +23,18 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QSignalBlocker>
# include <QAction>
#endif
#include <App/Document.h>
#include <Base/UnitsApi.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureExtrude.h>
#include <Mod/Part/Gui/ReferenceHighlighter.h>
#include "ui_TaskPadPocketParameters.h"
#include "TaskExtrudeParameters.h"
#include "TaskTransformedParameters.h"
#include "ReferenceSelection.h"
@@ -40,7 +43,7 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskExtrudeParameters */
TaskExtrudeParameters::TaskExtrudeParameters(ViewProviderSketchBased *SketchBasedView, QWidget *parent,
TaskExtrudeParameters::TaskExtrudeParameters(ViewProviderExtrude *SketchBasedView, QWidget *parent,
const std::string& pixmapname, const QString& parname)
: TaskSketchBasedParameters(SketchBasedView, parent, pixmapname, parname)
, propReferenceAxis(nullptr)
@@ -161,9 +164,24 @@ void TaskExtrudeParameters::setupDialog()
ui->lineFaceName->setProperty("FaceName", QByteArray(upToFace.c_str()));
updateShapeName();
updateShapeFaces();
translateModeList(index);
unselectShapeFaceAction = new QAction(tr("Remove"), this);
unselectShapeFaceAction->setShortcut(QKeySequence::Delete);
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
// display shortcut behind the context menu entry
unselectShapeFaceAction->setShortcutVisibleInContextMenu(true);
#endif
ui->listWidgetReferences->addAction(unselectShapeFaceAction);
ui->listWidgetReferences->setContextMenuPolicy(Qt::ActionsContextMenu);
connectSlots();
ui->checkBoxAllFaces->setChecked(ui->listWidgetReferences->count() == 0);
this->propReferenceAxis = &(extrude->ReferenceAxis);
@@ -215,14 +233,90 @@ void TaskExtrudeParameters::connectSlots()
this, &TaskExtrudeParameters::onMidplaneChanged);
connect(ui->checkBoxReversed, &QCheckBox::toggled,
this, &TaskExtrudeParameters::onReversedChanged);
connect(ui->checkBoxAllFaces, &QCheckBox::toggled,
this, &TaskExtrudeParameters::onAllFacesToggled);
connect(ui->changeMode, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskExtrudeParameters::onModeChanged);
connect(ui->buttonFace, &QPushButton::toggled,
this, &TaskExtrudeParameters::onButtonFace);
connect(ui->buttonFace, &QToolButton::toggled,
this, &TaskExtrudeParameters::onSelectFaceToggle);
connect(ui->buttonShape, &QToolButton::toggled,
this, &TaskExtrudeParameters::onSelectShapeToggle);
connect(ui->lineFaceName, &QLineEdit::textEdited,
this, &TaskExtrudeParameters::onFaceName);
connect(ui->checkBoxUpdateView, &QCheckBox::toggled,
this, &TaskExtrudeParameters::onUpdateView);
connect(ui->buttonShapeFace, &QToolButton::toggled,
this, &TaskExtrudeParameters::onSelectShapeFacesToggle);
connect(ui->listWidgetReferences, &QListWidget::item,
this, &TaskExtrudeParameters::onSelectShapeFacesToggle);
connect(unselectShapeFaceAction, &QAction::triggered,
this, &TaskExtrudeParameters::onUnselectShapeFacesTrigger);
}
void TaskExtrudeParameters::onSelectShapeFacesToggle(bool checked)
{
if (checked) {
setSelectionMode(SelectShapeFaces);
ui->buttonShapeFace->setText(tr("Preview"));
} else {
setSelectionMode(None);
ui->buttonShapeFace->setText(tr("Select faces"));
}
}
void PartDesignGui::TaskExtrudeParameters::onUnselectShapeFacesTrigger()
{
auto selected = ui->listWidgetReferences->selectedItems();
auto faces = getShapeFaces();
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
faces.erase(std::remove_if(faces.begin(), faces.end(), [selected](const std::string &face) {
for (auto &item : selected) {
if (item->text().toStdString() == face) {
return true;
}
}
return false;
}));
extrude->UpToShape.setValue(extrude->UpToShape.getValue(), faces);
updateShapeFaces();
}
void TaskExtrudeParameters::setSelectionMode(SelectionMode mode)
{
if (selectionMode == mode) {
return;
}
ui->buttonShapeFace->setChecked(mode == SelectShapeFaces);
ui->buttonFace->setChecked(mode == SelectFace);
ui->buttonShape->setChecked(mode == SelectShape);
selectionMode = mode;
switch (mode) {
case SelectShape:
onSelectReference(AllowSelection::WHOLE);
Gui::Selection().addSelectionGate(new SelectionFilterGate("SELECT Part::Feature COUNT 1"));
break;
case SelectFace:
onSelectReference(AllowSelection::FACE);
break;
case SelectShapeFaces:
onSelectReference(AllowSelection::FACE);
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces(getShapeFaces());
break;
case SelectReferenceAxis:
onSelectReference(AllowSelection::EDGE | AllowSelection::PLANAR | AllowSelection::CIRCLE);
break;
default:
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces({});
onSelectReference(AllowSelection::NONE);
}
}
void TaskExtrudeParameters::tryRecomputeFeature()
@@ -239,27 +333,29 @@ void TaskExtrudeParameters::tryRecomputeFeature()
void TaskExtrudeParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// if we have an edge selection for the extrude direction
if (!selectionFace) {
selectedReferenceAxis(msg);
}
// if we have a selection of a face
else {
QString refText = onAddSelection(msg);
if (refText.length() > 0) {
QSignalBlocker block(ui->lineFaceName);
ui->lineFaceName->setText(refText);
ui->lineFaceName->setProperty("FeatureName", QByteArray(msg.pObjectName));
ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName));
// Turn off reference selection mode
ui->buttonFace->setChecked(false);
}
else {
clearFaceName();
}
switch (selectionMode) {
case SelectShape:
selectedShape(msg);
break;
case SelectShapeFaces:
selectedShapeFace(msg);
break;
case SelectFace:
selectedFace(msg);
break;
case SelectReferenceAxis:
selectedReferenceAxis(msg);
break;
default:
// no-op
break;
}
}
else if (msg.Type == Gui::SelectionChanges::ClrSelection && selectionFace) {
else if (msg.Type == Gui::SelectionChanges::ClrSelection && selectionMode == SelectFace) {
clearFaceName();
}
}
@@ -268,15 +364,103 @@ void TaskExtrudeParameters::selectedReferenceAxis(const Gui::SelectionChanges& m
{
std::vector<std::string> edge;
App::DocumentObject* selObj;
if (getReferencedSelection(vp->getObject(), msg, selObj, edge) && selObj) {
exitSelectionMode();
setSelectionMode(None);
propReferenceAxis->setValue(selObj, edge);
tryRecomputeFeature();
// update direction combobox
fillDirectionCombo();
}
}
void TaskExtrudeParameters::selectedShapeFace(const Gui::SelectionChanges& msg)
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto document = extrude->getDocument();
if (strcmp(msg.pDocName, document->getName()) != 0) {
return;
}
auto base = static_cast<Part::Feature*>(extrude->UpToShape.getValue());
if (strcmp(msg.pObjectName, base->getNameInDocument()) != 0) {
return;
}
std::vector<std::string> faces = getShapeFaces();
std::string subName(msg.pSubName);
if (subName.empty()) {
return;
}
auto positionInList = std::find(faces.begin(), faces.end(), subName);
if (positionInList != faces.end()) { //If it's found then it's in the list so we remove it.
faces.erase(positionInList);
}
else { //if it's not found then it's not yet in the list so we add it.
faces.push_back(subName);
}
extrude->UpToShape.setValue(base, faces);
updateShapeFaces();
tryRecomputeFeature();
}
void PartDesignGui::TaskExtrudeParameters::selectedFace(const Gui::SelectionChanges& msg)
{
QString refText = onAddSelection(msg);
if (refText.length() > 0) {
QSignalBlocker block(ui->lineFaceName);
ui->lineFaceName->setText(refText);
ui->lineFaceName->setProperty("FeatureName", QByteArray(msg.pObjectName));
ui->lineFaceName->setProperty("FaceName", QByteArray(msg.pSubName));
// Turn off reference selection mode
ui->buttonFace->setChecked(false);
}
else {
clearFaceName();
}
setSelectionMode(None);
}
void PartDesignGui::TaskExtrudeParameters::selectedShape(const Gui::SelectionChanges& msg)
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto document = extrude->getDocument();
if (strcmp(msg.pDocName, document->getName()) != 0) {
return;
}
Gui::Selection().clearSelection();
auto base = extrude->getBaseObject();
auto ref = document->getObject(msg.pObjectName);
extrude->UpToShape.setValue(ref);
ui->checkBoxAllFaces->setChecked(true);
setSelectionMode(None);
updateShapeName();
updateShapeFaces();
tryRecomputeFeature();
}
void TaskExtrudeParameters::clearFaceName()
{
QSignalBlocker block(ui->lineFaceName);
@@ -286,6 +470,52 @@ void TaskExtrudeParameters::clearFaceName()
}
void TaskExtrudeParameters::updateShapeName()
{
QSignalBlocker block(ui->lineShapeName);
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto shape = extrude->UpToShape.getValue();
if (shape) {
ui->lineShapeName->setText(QString::fromStdString(shape->getFullName()));
} else {
ui->lineShapeName->setText({});
ui->lineShapeName->setPlaceholderText(tr("No shape selected"));
}
}
void TaskExtrudeParameters::updateShapeFaces()
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto faces = getShapeFaces();
ui->listWidgetReferences->clear();
for (auto &ref : faces) {
ui->listWidgetReferences->addItem(QString::fromStdString(ref));
}
if (selectionMode == SelectShapeFaces) {
static_cast<ViewProviderExtrude*>(vp)->highlightShapeFaces(faces);
}
}
std::vector<std::string> PartDesignGui::TaskExtrudeParameters::getShapeFaces()
{
std::vector<std::string> faces;
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
auto allRefs = extrude->UpToShape.getSubValues();
std::copy_if(
allRefs.begin(), allRefs.end(),
std::back_inserter(faces),
[](const std::string& ref) { return boost::starts_with(ref, "Face"); }
);
return faces;
}
void TaskExtrudeParameters::onLengthChanged(double len)
{
PartDesign::FeatureExtrude* extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
@@ -418,7 +648,7 @@ void TaskExtrudeParameters::addAxisToCombo(App::DocumentObject* linkObj, std::st
lnk.setValue(linkObj, std::vector<std::string>(1, linkSubname));
}
void TaskExtrudeParameters::setCheckboxes(Modes mode, Type type)
void TaskExtrudeParameters::setCheckboxes(Mode mode, Type type)
{
// disable/hide everything unless we are sure we don't need it
// exception: the direction parameters are in any case visible
@@ -430,10 +660,11 @@ void TaskExtrudeParameters::setCheckboxes(Modes mode, Type type)
bool isMidplaneVisible = false;
bool isReversedEnabled = false;
bool isFaceEditVisible = false;
bool isShapeEditVisible = false;
bool isTaperEditVisible = false;
bool isTaperEdit2Visible = false;
if (mode == Modes::Dimension) {
if (mode == Mode::Dimension) {
isLengthEditVisible = true;
ui->lengthEdit->selectNumber();
QMetaObject::invokeMethod(ui->lengthEdit, "setFocus", Qt::QueuedConnection);
@@ -443,22 +674,22 @@ void TaskExtrudeParameters::setCheckboxes(Modes mode, Type type)
// Reverse only makes sense if Midplane is not true
isReversedEnabled = !ui->checkBoxMidplane->isChecked();
}
else if (mode == Modes::ThroughAll && type == Type::Pocket) {
else if (mode == Mode::ThroughAll && type == Type::Pocket) {
isOffsetEditVisible = true;
isOffsetEditEnabled = false; // offset may have some meaning for through all but it doesn't work
isMidplaneEnabled = true;
isMidplaneVisible = true;
isReversedEnabled = !ui->checkBoxMidplane->isChecked();
}
else if (mode == Modes::ToLast && type == Type::Pad) {
else if (mode == Mode::ToLast && type == Type::Pad) {
isOffsetEditVisible = true;
isReversedEnabled = true;
}
else if (mode == Modes::ToFirst) {
else if (mode == Mode::ToFirst) {
isOffsetEditVisible = true;
isReversedEnabled = true;
}
else if (mode == Modes::ToFace) {
else if (mode == Mode::ToFace) {
isOffsetEditVisible = true;
isReversedEnabled = true;
isFaceEditVisible = true;
@@ -467,7 +698,15 @@ void TaskExtrudeParameters::setCheckboxes(Modes mode, Type type)
if (ui->lineFaceName->property("FeatureName").isNull())
ui->buttonFace->setChecked(true);
}
else if (mode == Modes::TwoDimensions) {
else if (mode == Mode::ToShape) {
isReversedEnabled = true;
isShapeEditVisible = true;
if (!ui->checkBoxAllFaces->isChecked()) {
ui->buttonShapeFace->setChecked(true);
}
}
else if (mode == Mode::TwoDimensions) {
isLengthEditVisible = true;
isLengthEdit2Visible = true;
isTaperEditVisible = true;
@@ -506,6 +745,8 @@ void TaskExtrudeParameters::setCheckboxes(Modes mode, Type type)
if (!isFaceEditVisible) {
ui->buttonFace->setChecked(false);
}
ui->upToShapeList->setVisible(isShapeEditVisible);
}
void TaskExtrudeParameters::onDirectionCBChanged(int num)
@@ -525,13 +766,11 @@ void TaskExtrudeParameters::onDirectionCBChanged(int num)
// when the link is empty we are either in selection mode
// or we are normal to a face
App::PropertyLinkSub& lnk = *(axesInList[num]);
if (num == DirectionModes::Select) {
// to distinguish that this is the direction selection
selectionFace = false;
setSelectionMode(SelectReferenceAxis);
setDirectionMode(num);
TaskSketchBasedParameters::onSelectReference(AllowSelection::EDGE |
AllowSelection::PLANAR |
AllowSelection::CIRCLE);
}
else {
if (lnk.getValue()) {
@@ -543,9 +782,9 @@ void TaskExtrudeParameters::onDirectionCBChanged(int num)
}
// in case the user is in selection mode, but changed his mind before selecting anything
exitSelectionMode();
setSelectionMode(None);
setDirectionMode(num);
extrude->ReferenceAxis.setValue(lnk.getValue(), lnk.getSubValues());
tryRecomputeFeature();
updateDirectionEdits();
@@ -561,10 +800,27 @@ void TaskExtrudeParameters::onAlongSketchNormalChanged(bool on)
void TaskExtrudeParameters::onDirectionToggled(bool on)
{
if (on)
if (on) {
ui->groupBoxDirection->show();
else
}
else {
ui->groupBoxDirection->hide();
}
}
void PartDesignGui::TaskExtrudeParameters::onAllFacesToggled(bool on)
{
ui->upToShapeFaces->setVisible(!on);
ui->buttonShapeFace->setChecked(false);
if (on) {
auto extrude = static_cast<PartDesign::FeatureExtrude*>(vp->getObject());
extrude->UpToShape.setValue(extrude->UpToShape.getValue());
updateShapeFaces();
tryRecomputeFeature();
}
}
void TaskExtrudeParameters::onXDirectionEditChanged(double len)
@@ -678,18 +934,28 @@ void TaskExtrudeParameters::getReferenceAxis(App::DocumentObject*& obj, std::vec
}
}
void TaskExtrudeParameters::onButtonFace(const bool checked)
void TaskExtrudeParameters::onSelectFaceToggle(const bool checked)
{
if (!checked)
if (!checked) {
handleLineFaceNameNo();
else
}
else {
handleLineFaceNameClick(); // sets placeholder text
setSelectionMode(SelectFace);
}
}
// to distinguish that this is the direction selection
selectionFace = true;
void PartDesignGui::TaskExtrudeParameters::onSelectShapeToggle(const bool checked)
{
if (checked) {
setSelectionMode(SelectShape);
// only faces are allowed
TaskSketchBasedParameters::onSelectReference(checked ? AllowSelection::FACE : AllowSelection::NONE);
ui->lineShapeName->setText({});
ui->lineShapeName->setPlaceholderText(tr("Click on a shape in the model"));
} else {
setSelectionMode(None);
updateShapeName();
}
}
void TaskExtrudeParameters::onFaceName(const QString& text)
@@ -897,4 +1163,22 @@ void TaskExtrudeParameters::handleLineFaceNameNo()
ui->lineFaceName->setPlaceholderText(tr("No face selected"));
}
TaskDlgExtrudeParameters::TaskDlgExtrudeParameters(PartDesignGui::ViewProviderExtrude* vp)
: TaskDlgSketchBasedParameters(vp)
{}
bool TaskDlgExtrudeParameters::accept()
{
getTaskParameters()->setSelectionMode(TaskExtrudeParameters::None);
return TaskDlgSketchBasedParameters::accept();
}
bool TaskDlgExtrudeParameters::reject()
{
getTaskParameters()->setSelectionMode(TaskExtrudeParameters::None);
return TaskDlgSketchBasedParameters::reject();
}
#include "moc_TaskExtrudeParameters.cpp"

View File

@@ -24,7 +24,7 @@
#define GUI_TASKVIEW_TaskExtrudeParameters_H
#include "TaskSketchBasedParameters.h"
#include "ViewProviderSketchBased.h"
#include "ViewProviderExtrude.h"
class Ui_TaskPadPocketParameters;
@@ -52,7 +52,30 @@ class TaskExtrudeParameters : public TaskSketchBasedParameters
};
public:
TaskExtrudeParameters(ViewProviderSketchBased *SketchBasedView, QWidget *parent,
enum class Type {
Pad,
Pocket
};
enum class Mode {
Dimension,
ThroughAll,
ToLast = ThroughAll,
ToFirst,
ToFace,
TwoDimensions,
ToShape,
};
enum SelectionMode {
None,
SelectFace,
SelectShape,
SelectShapeFaces,
SelectReferenceAxis
};
TaskExtrudeParameters(ViewProviderExtrude *ExtrudeView, QWidget *parent,
const std::string& pixmapname, const QString& parname);
~TaskExtrudeParameters() override;
@@ -63,18 +86,7 @@ public:
bool hasSketch = true);
void applyParameters(QString facename);
enum class Type {
Pad,
Pocket
};
enum class Modes {
Dimension,
ThroughAll,
ToLast = ThroughAll,
ToFirst,
ToFace,
TwoDimensions
};
void setSelectionMode(SelectionMode mode);
protected Q_SLOTS:
void onLengthChanged(double);
@@ -85,17 +97,22 @@ protected Q_SLOTS:
void onDirectionCBChanged(int);
void onAlongSketchNormalChanged(bool);
void onDirectionToggled(bool);
void onAllFacesToggled(bool);
void onXDirectionEditChanged(double);
void onYDirectionEditChanged(double);
void onZDirectionEditChanged(double);
void onMidplaneChanged(bool);
void onReversedChanged(bool);
void onButtonFace(const bool checked = true);
void onFaceName(const QString& text);
void onSelectFaceToggle(const bool checked = true);
void onSelectShapeToggle(const bool checked = true);
void onSelectShapeFacesToggle(const bool checked);
void onUnselectShapeFacesTrigger();
virtual void onModeChanged(int);
protected:
void setCheckboxes(Modes mode, Type type);
void setCheckboxes(Mode mode, Type type);
void setupDialog();
void readValuesFromHistory();
void changeEvent(QEvent *e) override;
@@ -122,18 +139,45 @@ protected:
void handleLineFaceNameNo();
private:
void selectedReferenceAxis(const Gui::SelectionChanges& msg);
void selectedFace(const Gui::SelectionChanges& msg);
void selectedShape(const Gui::SelectionChanges& msg);
void selectedShapeFace(const Gui::SelectionChanges& msg);
void tryRecomputeFeature();
void translateFaceName();
void connectSlots();
bool hasProfileFace(PartDesign::ProfileBased*) const;
void selectedReferenceAxis(const Gui::SelectionChanges& msg);
void clearFaceName();
void updateShapeName();
void updateShapeFaces();
std::vector<std::string> getShapeFaces();
protected:
QWidget* proxy;
QAction* unselectShapeFaceAction;
std::unique_ptr<Ui_TaskPadPocketParameters> ui;
bool selectionFace;
std::vector<std::unique_ptr<App::PropertyLinkSub>> axesInList;
SelectionMode selectionMode = None;
};
class TaskDlgExtrudeParameters : public TaskDlgSketchBasedParameters
{
Q_OBJECT
public:
explicit TaskDlgExtrudeParameters(PartDesignGui::ViewProviderExtrude *vp);
~TaskDlgExtrudeParameters() override = default;
bool accept() override;
bool reject() override;
protected:
virtual TaskExtrudeParameters* getTaskParameters() = 0;
};
} //namespace PartDesignGui

View File

@@ -72,6 +72,7 @@ void TaskPadParameters::translateModeList(int index)
ui->changeMode->addItem(tr("To first"));
ui->changeMode->addItem(tr("Up to face"));
ui->changeMode->addItem(tr("Two dimensions"));
ui->changeMode->addItem(tr("Up to shape"));
ui->changeMode->setCurrentIndex(index);
}
@@ -80,27 +81,27 @@ void TaskPadParameters::updateUI(int index)
// update direction combobox
fillDirectionCombo();
// set and enable checkboxes
setCheckboxes(static_cast<Modes>(index), Type::Pad);
setCheckboxes(static_cast<Mode>(index), Type::Pad);
}
void TaskPadParameters::onModeChanged(int index)
{
PartDesign::Pad* pcPad = static_cast<PartDesign::Pad*>(vp->getObject());
switch (static_cast<Modes>(index)) {
case Modes::Dimension:
switch (static_cast<Mode>(index)) {
case Mode::Dimension:
pcPad->Type.setValue("Length");
// Avoid error message
if (ui->lengthEdit->value() < Base::Quantity(Precision::Confusion(), Base::Unit::Length))
ui->lengthEdit->setValue(5.0);
break;
case Modes::ToLast:
case Mode::ToLast:
pcPad->Type.setValue("UpToLast");
break;
case Modes::ToFirst:
case Mode::ToFirst:
pcPad->Type.setValue("UpToFirst");
break;
case Modes::ToFace:
case Mode::ToFace:
// Note: ui->checkBoxReversed is purposely enabled because the selected face
// could be a circular one around the sketch
pcPad->Type.setValue("UpToFace");
@@ -109,9 +110,12 @@ void TaskPadParameters::onModeChanged(int index)
handleLineFaceNameClick(); // sets placeholder text
}
break;
case Modes::TwoDimensions:
case Mode::TwoDimensions:
pcPad->Type.setValue("TwoLengths");
break;
case Mode::ToShape:
pcPad->Type.setValue("UpToShape");
break;
}
updateUI(index);
@@ -121,7 +125,7 @@ void TaskPadParameters::onModeChanged(int index)
void TaskPadParameters::apply()
{
QString facename = QString::fromLatin1("None");
if (static_cast<Modes>(getMode()) == Modes::ToFace) {
if (static_cast<Mode>(getMode()) == Mode::ToFace) {
facename = getFaceName();
}
applyParameters(facename);
@@ -133,10 +137,9 @@ void TaskPadParameters::apply()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgPadParameters::TaskDlgPadParameters(ViewProviderPad *PadView, bool /*newObj*/)
: TaskDlgSketchBasedParameters(PadView)
: TaskDlgExtrudeParameters(PadView), parameters(new TaskPadParameters(PadView))
{
assert(vp);
Content.push_back ( new TaskPadParameters(PadView ) );
Content.push_back(parameters);
}
//==== calls from the TaskView ===============================================================

View File

@@ -55,15 +55,20 @@ private:
};
/// simulation dialog for the TaskView
class TaskDlgPadParameters : public TaskDlgSketchBasedParameters
class TaskDlgPadParameters : public TaskDlgExtrudeParameters
{
Q_OBJECT
public:
explicit TaskDlgPadParameters(ViewProviderPad *PadView, bool newObj=false);
ViewProviderPad* getPadView() const
{ return static_cast<ViewProviderPad*>(vp); }
ViewProviderPad* getPadView() const { return static_cast<ViewProviderPad*>(vp); }
protected:
TaskExtrudeParameters* getTaskParameters() override { return parameters; };
private:
TaskPadParameters* parameters;
};
} //namespace PartDesignGui

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>300</width>
<height>598</height>
<height>772</height>
</rect>
</property>
<property name="windowTitle">
@@ -40,14 +40,14 @@
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefQuantitySpinBox" name="lengthEdit">
<property name="keyboardTracking">
<widget class="Gui::PrefQuantitySpinBox" name="lengthEdit" native="true">
<property name="keyboardTracking" stdset="0">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
<property name="minimum">
<property name="minimum" stdset="0">
<double>0.000000000000000</double>
</property>
</widget>
@@ -60,8 +60,8 @@
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::PrefQuantitySpinBox" name="lengthEdit2">
<property name="keyboardTracking">
<widget class="Gui::PrefQuantitySpinBox" name="lengthEdit2" native="true">
<property name="keyboardTracking" stdset="0">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
@@ -77,8 +77,8 @@
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::PrefQuantitySpinBox" name="offsetEdit">
<property name="keyboardTracking">
<widget class="Gui::PrefQuantitySpinBox" name="offsetEdit" native="true">
<property name="keyboardTracking" stdset="0">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
@@ -88,8 +88,118 @@
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="upToShapeList">
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="_2">
<item row="0" column="1">
<widget class="QLineEdit" name="lineShapeName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QToolButton" name="buttonShape">
<property name="minimumSize">
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="text">
<string>Select shape</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkBoxAllFaces">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Applies length symmetrically to sketch plane</string>
</property>
<property name="text">
<string>Select all faces</string>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="upToShapeFaces" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="buttonShapeFace">
<property name="toolTip">
<string>Click button to enter selection mode,
click again to end selection</string>
</property>
<property name="text">
<string>Select</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listWidgetReferences">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="1">
<widget class="QLineEdit" name="lineFaceName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QToolButton" name="buttonFace">
<property name="minimumSize">
@@ -106,13 +216,6 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineFaceName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
@@ -321,8 +424,8 @@ measured along the specified direction</string>
</widget>
</item>
<item>
<widget class="Gui::PrefQuantitySpinBox" name="taperEdit">
<property name="keyboardTracking">
<widget class="Gui::PrefQuantitySpinBox" name="taperEdit" native="true">
<property name="keyboardTracking" stdset="0">
<bool>false</bool>
</property>
<property name="unit" stdset="0">
@@ -345,8 +448,8 @@ measured along the specified direction</string>
</widget>
</item>
<item>
<widget class="Gui::PrefQuantitySpinBox" name="taperEdit2">
<property name="keyboardTracking">
<widget class="Gui::PrefQuantitySpinBox" name="taperEdit2" native="true">
<property name="keyboardTracking" stdset="0">
<bool>false</bool>
</property>
<property name="unit" stdset="0">

View File

@@ -73,6 +73,7 @@ void TaskPocketParameters::translateModeList(int index)
ui->changeMode->addItem(tr("To first"));
ui->changeMode->addItem(tr("Up to face"));
ui->changeMode->addItem(tr("Two dimensions"));
ui->changeMode->addItem(tr("Up to shape"));
ui->changeMode->setCurrentIndex(index);
}
@@ -81,15 +82,15 @@ void TaskPocketParameters::updateUI(int index)
// update direction combobox
fillDirectionCombo();
// set and enable checkboxes
setCheckboxes(static_cast<Modes>(index), Type::Pocket);
setCheckboxes(static_cast<Mode>(index), Type::Pocket);
}
void TaskPocketParameters::onModeChanged(int index)
{
PartDesign::Pocket* pcPocket = static_cast<PartDesign::Pocket*>(vp->getObject());
switch (static_cast<Modes>(index)) {
case Modes::Dimension:
switch (static_cast<Mode>(index)) {
case Mode::Dimension:
// Why? See below for "UpToFace"
if (oldLength < Precision::Confusion())
oldLength = 5.0;
@@ -97,15 +98,15 @@ void TaskPocketParameters::onModeChanged(int index)
ui->lengthEdit->setValue(oldLength);
pcPocket->Type.setValue("Length");
break;
case Modes::ThroughAll:
case Mode::ThroughAll:
oldLength = pcPocket->Length.getValue();
pcPocket->Type.setValue("ThroughAll");
break;
case Modes::ToFirst:
case Mode::ToFirst:
oldLength = pcPocket->Length.getValue();
pcPocket->Type.setValue("UpToFirst");
break;
case Modes::ToFace:
case Mode::ToFace:
// Note: ui->checkBoxReversed is purposely enabled because the selected face
// could be a circular one around the sketch
// Also note: Because of the code at the beginning of Pocket::execute() which is used
@@ -119,10 +120,13 @@ void TaskPocketParameters::onModeChanged(int index)
handleLineFaceNameClick(); // sets placeholder text
}
break;
case Modes::TwoDimensions:
case Mode::TwoDimensions:
oldLength = pcPocket->Length.getValue();
pcPocket->Type.setValue("TwoLengths");
break;
case Mode::ToShape:
pcPocket->Type.setValue("UpToShape");
break;
}
updateUI(index);
@@ -132,7 +136,7 @@ void TaskPocketParameters::onModeChanged(int index)
void TaskPocketParameters::apply()
{
QString facename = QString::fromLatin1("None");
if (static_cast<Modes>(getMode()) == Modes::ToFace) {
if (static_cast<Mode>(getMode()) == Mode::ToFace) {
facename = getFaceName();
}
applyParameters(facename);
@@ -144,10 +148,9 @@ void TaskPocketParameters::apply()
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgPocketParameters::TaskDlgPocketParameters(ViewProviderPocket *PocketView)
: TaskDlgSketchBasedParameters(PocketView)
: TaskDlgExtrudeParameters(PocketView), parameters(new TaskPocketParameters(PocketView))
{
assert(vp);
Content.push_back ( new TaskPocketParameters(PocketView ) );
Content.push_back(parameters);
}
#include "moc_TaskPocketParameters.cpp"

View File

@@ -58,7 +58,7 @@ private:
};
/// simulation dialog for the TaskView
class TaskDlgPocketParameters : public TaskDlgSketchBasedParameters
class TaskDlgPocketParameters : public TaskDlgExtrudeParameters
{
Q_OBJECT
@@ -67,6 +67,12 @@ public:
ViewProviderPocket* getPocketView() const
{ return static_cast<ViewProviderPocket*>(vp); }
protected:
TaskExtrudeParameters* getTaskParameters() override { return parameters; }
private:
TaskPocketParameters* parameters;
};
} //namespace PartDesignGui

View File

@@ -106,7 +106,6 @@ void TaskSketchBasedParameters::finishReferenceSelection(App::DocumentObject* pr
void TaskSketchBasedParameters::onSelectReference(AllowSelectionFlags allow) {
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
PartDesign::ProfileBased* pcSketchBased = dynamic_cast<PartDesign::ProfileBased*>(vp->getObject());
if (pcSketchBased) {
// The solid this feature will be fused to

View File

@@ -163,6 +163,8 @@ public:
/// Exit the selection mode of the associated task panel
void exitSelectionMode();
static void removeItemFromListWidget(QListWidget* widget, const QString& itemstr);
protected:
/** Setup the standalone UI.
* Call this in the derived destructor with ViewProvider.
@@ -212,7 +214,7 @@ protected:
void fillPlanesCombo(ComboLinks& combolinks, Part::Part2DObject* sketch);
/**
* Returns the base transformed object
* Returns the base transformed objectfromStdString
* For stand alone features it will be objects associated with this object
* For features inside multitransform it will be the base multitransform object
*/
@@ -258,8 +260,6 @@ private:
void changeEvent(QEvent* event) override;
static void removeItemFromListWidget(QListWidget* widget, const QString& itemstr);
protected:
enum class SelectionMode
{

View File

@@ -63,7 +63,7 @@ std::string ViewProviderDressUp::featureIcon() const
bool ViewProviderDressUp::setEdit(int ModNum) {
if (ModNum == ViewProvider::Default ) {
if (ModNum == ViewProvider::Default) {
// Here we should prevent edit of a Feature with missing base
// Otherwise it could call unhandled exception.
PartDesign::DressUp* dressUp = static_cast<PartDesign::DressUp*>(getObject());
@@ -84,7 +84,6 @@ bool ViewProviderDressUp::setEdit(int ModNum) {
}
}
void ViewProviderDressUp::highlightReferences(const bool on)
{
PartDesign::DressUp* pcDressUp = static_cast<PartDesign::DressUp*>(getObject());
@@ -100,31 +99,25 @@ void ViewProviderDressUp::highlightReferences(const bool on)
std::vector<std::string> edges = pcDressUp->Base.getSubValuesStartsWith("Edge");
if (on) {
if (!faces.empty() && originalFaceMaterials.empty()) {
originalFaceMaterials = vp->ShapeAppearance.getValues();
std::vector<App::Material> materials = originalFaceMaterials;
if (!faces.empty()) {
std::vector<App::Material> materials = vp->ShapeAppearance.getValues();
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(), ShapeAppearance.getDiffuseColor());
highlighter.getFaceMaterials(faces, materials);
vp->ShapeAppearance.setValues(materials);
vp->setHighlightedFaces(materials);
}
if (!edges.empty() && originalLineColors.empty()) {
originalLineColors = vp->LineColorArray.getValues();
std::vector<App::Color> colors = originalLineColors;
if (!edges.empty()) {
std::vector<App::Color> colors = vp->LineColorArray.getValues();
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(), LineColor.getValue());
highlighter.getEdgeColors(edges, colors);
vp->LineColorArray.setValues(colors);
vp->setHighlightedEdges(colors);
}
} else {
if (!faces.empty() && !originalFaceMaterials.empty()) {
vp->ShapeAppearance.setValues(originalFaceMaterials);
originalFaceMaterials.clear();
}
if (!edges.empty() && !originalLineColors.empty()) {
vp->LineColorArray.setValues(originalLineColors);
originalLineColors.clear();
}
vp->unsetHighlightedFaces();
vp->unsetHighlightedEdges();
}
}

View File

@@ -58,11 +58,6 @@ public:
protected:
bool setEdit(int ModNum) override;
private:
std::vector<App::Material> originalFaceMaterials;
std::vector<App::Color> originalLineColors;
};

View File

@@ -0,0 +1,64 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMenu>
#endif
#include <App/Document.h>
#include <Gui/Application.h>
#include <Mod/PartDesign/App/FeatureExtrude.h>
#include <Mod/Part/Gui/ReferenceHighlighter.h>
#include "TaskExtrudeParameters.h"
#include "ViewProviderExtrude.h"
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderExtrude, PartDesignGui::ViewProviderSketchBased)
void PartDesignGui::ViewProviderExtrude::highlightShapeFaces(const std::vector<std::string>& faces)
{
auto extrude = static_cast<PartDesign::FeatureExtrude*>(getObject());
auto base = static_cast<Part::Feature*>(extrude->UpToShape.getValue());
auto baseViewProvider =
static_cast<PartGui::ViewProviderPart*>(Gui::Application::Instance->getViewProvider(base));
baseViewProvider->unsetHighlightedFaces();
baseViewProvider->updateView();
if (faces.size() > 0) {
std::vector<App::Color> colors = baseViewProvider->DiffuseColor.getValues();
auto color = baseViewProvider->ShapeAppearance.getDiffuseColor();
PartGui::ReferenceHighlighter highlighter(base->Shape.getValue(), color);
highlighter.getFaceColors(faces, colors);
baseViewProvider->setHighlightedFaces(colors);
}
}

View File

@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (c) 2024 Kacper Donat <kacper@kadet.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PARTGUI_ViewProviderExtrude_H
#define PARTGUI_ViewProviderExtrude_H
#include "ViewProviderSketchBased.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderExtrude : public ViewProviderSketchBased
{
PROPERTY_HEADER_WITH_OVERRIDE(PartDesignGui::ViewProviderExtrude);
public:
ViewProviderExtrude() = default;
~ViewProviderExtrude() override = default;
void highlightShapeFaces(const std::vector<std::string>& faces);
};
} // namespace PartDesignGui
#endif // PARTGUI_ViewProviderExtrude_H

View File

@@ -32,7 +32,7 @@
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderPad,PartDesignGui::ViewProviderSketchBased)
PROPERTY_SOURCE(PartDesignGui::ViewProviderPad, PartDesignGui::ViewProviderExtrude)
ViewProviderPad::ViewProviderPad()
{

View File

@@ -24,11 +24,11 @@
#ifndef PARTGUI_ViewProviderPad_H
#define PARTGUI_ViewProviderPad_H
#include "ViewProviderSketchBased.h"
#include "ViewProviderExtrude.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderPad : public ViewProviderSketchBased
class PartDesignGuiExport ViewProviderPad : public ViewProviderExtrude
{
PROPERTY_HEADER_WITH_OVERRIDE(PartDesignGui::ViewProviderPad);

View File

@@ -33,7 +33,7 @@
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderPocket,PartDesignGui::ViewProviderSketchBased)
PROPERTY_SOURCE(PartDesignGui::ViewProviderPocket, PartDesignGui::ViewProviderExtrude)
ViewProviderPocket::ViewProviderPocket()
{

View File

@@ -24,12 +24,12 @@
#ifndef PARTGUI_ViewProviderPocket_H
#define PARTGUI_ViewProviderPocket_H
#include "ViewProviderSketchBased.h"
#include "ViewProviderExtrude.h"
namespace PartDesignGui {
class PartDesignGuiExport ViewProviderPocket : public ViewProviderSketchBased
class PartDesignGuiExport ViewProviderPocket : public ViewProviderExtrude
{
PROPERTY_HEADER_WITH_OVERRIDE(PartDesignGui::ViewProviderPocket);