Fix "Show only Visible Constraints" option (#23187)

Co-authored-by: Matthias Danner <28687794+matthiasdanner@users.noreply.github.com>
This commit is contained in:
matthiasdanner
2025-09-22 17:54:24 +02:00
committed by GitHub
parent 78ea999336
commit 5f52aa5901
9 changed files with 182 additions and 15 deletions

View File

@@ -87,6 +87,7 @@ Constraint* Constraint::copy() const
temp->isDriving = this->isDriving;
temp->InternalAlignmentIndex = this->InternalAlignmentIndex;
temp->isInVirtualSpace = this->isInVirtualSpace;
temp->isVisible = this->isVisible;
temp->isActive = this->isActive;
temp->elements = this->elements;
// Do not copy tag, otherwise it is considered a clone, and a "rename" by the expression engine.
@@ -161,6 +162,7 @@ void Constraint::Save(Writer& writer) const
<< "LabelPosition=\"" << LabelPosition << "\" "
<< "IsDriving=\"" << (int)isDriving << "\" "
<< "IsInVirtualSpace=\"" << (int)isInVirtualSpace << "\" "
<< "IsVisible=\"" << (int)isVisible << "\" "
<< "IsActive=\"" << (int)isActive << "\" ";
// Save elements
@@ -230,6 +232,10 @@ void Constraint::Restore(XMLReader& reader)
isInVirtualSpace = reader.getAttribute<bool>("IsInVirtualSpace");
}
if (reader.hasAttribute("IsVisible")) {
isVisible = reader.getAttribute<bool>("IsVisible");
}
if (reader.hasAttribute("IsActive")) {
isActive = reader.getAttribute<bool>("IsActive");
}

View File

@@ -216,6 +216,7 @@ public:
// index of pole in a bspline). It is not a GeoId!!
int InternalAlignmentIndex {-1};
bool isInVirtualSpace {false};
bool isVisible {true};
bool isActive {true};

View File

@@ -1344,6 +1344,69 @@ int SketchObject::toggleVirtualSpace(int ConstrId)
}
int SketchObject::setVisibility(std::vector<int> constrIds, bool isVisible)
{
// no need to check input data validity as this is an sketchobject managed operation.
Base::StateLocker lock(managedoperation, true);
if (constrIds.empty())
return 0;
std::sort(constrIds.begin(), constrIds.end());
const std::vector<Constraint*>& vals = this->Constraints.getValues();
if (constrIds.front() < 0 || constrIds.back() >= int(vals.size()))
return -1;
std::vector<Constraint*> newVals(vals);
for (auto cid : constrIds) {
// clone the changed Constraint
if (vals[cid]->isVisible != isVisible) {
Constraint* constNew = vals[cid]->clone();
constNew->isVisible = isVisible;
newVals[cid] = constNew;
}
}
this->Constraints.setValues(std::move(newVals));
// Solver didn't actually update, but we need this to inform view provider
// to redraw
signalSolverUpdate();
return 0;
}
int SketchObject::setVisibility(int ConstrId, bool isVisible)
{
// no need to check input data validity as this is an sketchobject managed operation.
Base::StateLocker lock(managedoperation, true);
const std::vector<Constraint*>& vals = this->Constraints.getValues();
if (ConstrId < 0 || ConstrId >= int(vals.size()))
return -1;
// copy the list
std::vector<Constraint*> newVals(vals);
// clone the changed Constraint
Constraint* constNew = vals[ConstrId]->clone();
constNew->isVisible = isVisible;
newVals[ConstrId] = constNew;
this->Constraints.setValues(std::move(newVals));
// Solver didn't actually update, but we need this to inform view provider
// to redraw
signalSolverUpdate();
return 0;
}
int SketchObject::setUpSketch()
{
lastDoF = solvedSketch.setUpSketch(

View File

@@ -384,6 +384,10 @@ public:
int getVirtualSpace(int ConstrId, bool& isinvirtualspace) const;
/// toggle the driving status of this constraint
int toggleVirtualSpace(int ConstrId);
/// set the visibility of this constraint
int setVisibility(int ConstrId, bool isVisible);
/// set the visibility of a group of constraints at once
int setVisibility(std::vector<int> constrIds, bool isVisible);
/// move this point to a new location and solve
int moveGeometries(const std::vector<GeoElementId>& geoEltIds,
const Base::Vector3d& toPoint,

View File

@@ -465,6 +465,12 @@ class SketchObject(Part2DObject):
"""
...
def setVisibility(self) -> None:
"""
Set the visibility of a constraint
"""
...
def getVirtualSpace(self) -> bool:
"""
Get the VirtualSpace status of a constraint

View File

@@ -1051,6 +1051,57 @@ PyObject* SketchObjectPy::setVirtualSpace(PyObject* args)
throw Py::TypeError(error);
}
PyObject* SketchObjectPy::setVisibility(PyObject* args)
{
PyObject* isVisible;
PyObject* id_or_ids;
if (!PyArg_ParseTuple(args, "OO!", &id_or_ids, &PyBool_Type, &isVisible)) {
return nullptr;
}
if (PyObject_TypeCheck(id_or_ids, &(PyList_Type))
|| PyObject_TypeCheck(id_or_ids, &(PyTuple_Type))) {
std::vector<int> constrIds;
Py::Sequence list(id_or_ids);
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
if (PyLong_Check((*it).ptr())) {
constrIds.push_back(PyLong_AsLong((*it).ptr()));
}
}
try {
int ret =
this->getSketchObjectPtr()->setVisibility(constrIds, Base::asBoolean(isVisible));
if (ret == -1) {
throw Py::TypeError("Impossible to set visibility!");
}
}
catch (const Base::ValueError& e) {
throw Py::ValueError(e.getMessage());
}
Py_Return;
}
else if (PyLong_Check(id_or_ids)) {
if (this->getSketchObjectPtr()->setVisibility(PyLong_AsLong(id_or_ids),
Base::asBoolean(isVisible))) {
std::stringstream str;
str << "Not able set visibility for constraint with the given index: "
<< PyLong_AsLong(id_or_ids);
PyErr_SetString(PyExc_ValueError, str.str().c_str());
return nullptr;
}
Py_Return;
}
std::string error = std::string("type must be list of Constraint Ids, not ");
error += id_or_ids->ob_type->tp_name;
throw Py::TypeError(error);
}
PyObject* SketchObjectPy::getVirtualSpace(PyObject* args)
{
int constrid;

View File

@@ -104,8 +104,8 @@ void EditModeConstraintCoinManager::updateVirtualSpace()
SbBool* sws = editModeScenegraphNodes.constrGroup->enable.startEditing();
for (size_t i = 0; i < constrlist.size(); i++) {
sws[i] = !(constrlist[i]->isInVirtualSpace
!= isshownvirtualspace); // XOR of constraint mode and VP mode
sws[i] = !(constrlist[i]->isInVirtualSpace != isshownvirtualspace)
&& constrlist[i]->isVisible; // XOR of constraint mode and VP mode
}
@@ -2414,8 +2414,9 @@ void EditModeConstraintCoinManager::drawConstraintIcons(const GeoListFacade& geo
thisIcon.position = absPos;
thisIcon.destination = coinIconPtr;
thisIcon.infoPtr = infoPtr;
thisIcon.visible = constraint->isInVirtualSpace
== ViewProviderSketchCoinAttorney::isShownVirtualSpace(viewProvider);
thisIcon.visible = (constraint->isInVirtualSpace
== ViewProviderSketchCoinAttorney::isShownVirtualSpace(viewProvider))
&& constraint->isVisible;
if (constraint->Type == Symmetric) {
Base::Vector3d startingpoint =

View File

@@ -1472,37 +1472,37 @@ void TaskSketcherConstraints::change3DViewVisibilityToTrackFilter(bool filterEna
const Sketcher::SketchObject* sketch = sketchView->getSketchObject();
const std::vector<Sketcher::Constraint*>& vals = sketch->Constraints.getValues();
std::vector<int> constrIdsToVirtualSpace;
std::vector<int> constrIdsToCurrentSpace;
std::vector<int> constrIdsToSetVisible;
std::vector<int> constrIdsToSetHidden;
for (std::size_t i = 0; i < vals.size(); ++i) {
ConstraintItem* it = static_cast<ConstraintItem*>(ui->listWidgetConstraints->item(i));
bool visible = !filterEnabled || !isConstraintFiltered(it);
// If the constraint is filteredout and it was previously shown in 3D view
if (!visible && it->isInVirtualSpace() == sketchView->getIsShownVirtualSpace()) {
constrIdsToVirtualSpace.push_back(it->ConstraintNbr);
if (!visible) {
constrIdsToSetHidden.push_back(it->ConstraintNbr);
}
else if (visible && it->isInVirtualSpace() != sketchView->getIsShownVirtualSpace()) {
constrIdsToCurrentSpace.push_back(it->ConstraintNbr);
else if (visible) {
constrIdsToSetVisible.push_back(it->ConstraintNbr);
}
}
if (!constrIdsToVirtualSpace.empty()) {
bool ret = doSetVirtualSpace(constrIdsToVirtualSpace, true);
if (!constrIdsToSetVisible.empty()) {
bool ret = doSetVisible(constrIdsToSetVisible, true);
if (!ret) {
return;
}
}
if (!constrIdsToCurrentSpace.empty()) {
bool ret = doSetVirtualSpace(constrIdsToCurrentSpace, false);
if (!constrIdsToSetHidden.empty()) {
bool ret = doSetVisible(constrIdsToSetHidden, false);
if (!ret) {
return;
}
}
if (constrIdsToVirtualSpace.empty() && constrIdsToCurrentSpace.empty()) {
if (constrIdsToSetVisible.empty() && constrIdsToSetHidden.empty()) {
slotConstraintsChanged();
}
}
@@ -1541,6 +1541,40 @@ bool TaskSketcherConstraints::doSetVirtualSpace(const std::vector<int>& constrId
return true;
}
bool TaskSketcherConstraints::doSetVisible(const std::vector<int>& constrIds, bool isVisible) {
assert(sketchView);
const Sketcher::SketchObject* sketch = sketchView->getSketchObject();
std::stringstream stream;
stream << '[';
for (size_t i = 0; i < constrIds.size() - 1; i++) {
stream << constrIds[i] << ",";
}
stream << constrIds[constrIds.size() - 1] << ']';
std::string constrIdList = stream.str();
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Update constraint's visibility"));
try {
Gui::cmdAppObjectArgs(sketch,
"setVisibility(%s, %s)",
constrIdList,
isVisible ? "True" : "False");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::Command::abortCommand();
Gui::TranslatedUserError(
sketch, tr("Error"), tr("Impossible to update visibility:") + QLatin1String(" ") + QLatin1String(e.what()));
return false;
}
return true;
}
bool TaskSketcherConstraints::isConstraintFiltered(QListWidgetItem* item)
{
assert(sketchView);

View File

@@ -169,6 +169,7 @@ private:
bool isConstraintFiltered(QListWidgetItem* item);
void change3DViewVisibilityToTrackFilter(bool filterEnabled);
bool doSetVirtualSpace(const std::vector<int>& constrIds, bool isvirtualspace);
bool doSetVisible(const std::vector<int>& constrIds, bool isVisible);
void changeFilteredVisibility(bool show, ActionTarget target = ActionTarget::All);
void updateSelectionFilter();
void updateAssociatedConstraintsFilter();