From 1f6c1fcd0fa3ae5eddfd5b77b1f163e3b52ffd13 Mon Sep 17 00:00:00 2001 From: Uwe Date: Tue, 24 Jan 2023 02:16:56 +0100 Subject: [PATCH] [Part] fixes for the section cutting feature - a typical use-case is to open a document with an existing cut and only this cut is visible. When now opening the section cutting tool, the user got the fault message that there were no visible objects to be cut. - the transparency for the cut was not explicitly set. Therefore the default transparency for new objects was used instead of the transparency of the objects to be cut. - workaround for a graphics issue: when cutting objects intersection each other (only then), the transparency setting might be ignored. The fix is simply to change the default color slightly (By the way, this issue is independent on the color that is set in the Part preferences as color for new objects, seems to be a graphics driver or OCC issue.) - besides this, avoid code duplication by using a lambda function --- src/Mod/Part/Gui/SectionCutting.cpp | 95 +++++++++++++++++++++-------- src/Mod/Part/Gui/SectionCutting.ui | 10 +-- 2 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/Mod/Part/Gui/SectionCutting.cpp b/src/Mod/Part/Gui/SectionCutting.cpp index 983702c683..b64f2215b4 100644 --- a/src/Mod/Part/Gui/SectionCutting.cpp +++ b/src/Mod/Part/Gui/SectionCutting.cpp @@ -147,6 +147,20 @@ SectionCut::SectionCut(QWidget* parent) return; } BoundCompound = pcCompound->Shape.getBoundingBox(); + // make parent objects of links visible to handle the case that + // the cutting is started when only an existing cut was visible + std::vector compoundObjects; + pcCompound->Links.getLinks(compoundObjects); + for (auto itCompound = compoundObjects.begin(); itCompound != compoundObjects.end(); + itCompound++) { + App::Link* pcLink = dynamic_cast(*itCompound); + auto LinkedObject = pcLink->getLink(); + // only if not already visible + if (!(LinkedObject->Visibility.getValue())) { + LinkedObject->Visibility.setValue(true); + ObjectsListVisible.emplace_back(LinkedObject); + } + } } } if (doc->getObject(BoxZName)) { @@ -314,22 +328,38 @@ void SectionCut::startCutting(bool isInitial) doc->removeObject(objectName); }; + int compoundTransparency = -1; + // lambda to store the compoundTransparency + auto storeTransparency = [&](App::DocumentObject* cutObject) { + auto CompoundVP = dynamic_cast( + Gui::Application::Instance->getViewProvider(cutObject)); + if (CompoundVP && compoundTransparency == -1) { + compoundTransparency = CompoundVP->Transparency.getValue(); + } + }; + // delete the objects we might have already created to cut // we must do this because we support several cuts at once and // it is dangerous to deal with the fact that the user is free // to uncheck cutting planes and to add/remove objects while this dialog is open // We must remove in this order because the tree hierary of the features is Z->Y->X and Cut->Box - - if (doc->getObject(CutZName)) + if (doc->getObject(CutZName)) { + // the topmost cut transparency determines the overall transparency + storeTransparency(doc->getObject(CutZName)); deleteObject(CutZName); + } if (doc->getObject(BoxZName)) deleteObject(BoxZName); - if (doc->getObject(CutYName)) + if (doc->getObject(CutYName)) { + storeTransparency(doc->getObject(CutYName)); deleteObject(CutYName); + } if (doc->getObject(BoxYName)) deleteObject(BoxYName); - if (doc->getObject(CutXName)) + if (doc->getObject(CutXName)) { + storeTransparency(doc->getObject(CutXName)); deleteObject(CutXName); + } if (doc->getObject(BoxXName)) deleteObject(BoxXName); if (doc->getObject(CompoundName)) { @@ -340,6 +370,7 @@ void SectionCut::startCutting(bool isInitial) "SectionCut error: compound is incorrectly named, cannot proceed\n"); return; } + // get the compound content std::vector compoundObjects; pcCompoundDel->Links.getLinks(compoundObjects); // first delete the compound @@ -578,6 +609,15 @@ void SectionCut::startCutting(bool isInitial) } } + // set transparency for the compound + // if there was no compound, take the setting for the cut face + if (compoundTransparency == -1) + compoundTransparency = ui->CutTransparency->value(); + auto vpCompound = dynamic_cast( + Gui::Application::Instance->getViewProvider(pcCompound)); + if (vpCompound) + vpCompound->Transparency.setValue(compoundTransparency); + // compute the filled compound pcCompound->recomputeFeature(); @@ -639,6 +679,25 @@ void SectionCut::startCutting(bool isInitial) boxColor.setValue(ui->CutColor->color()); int boxTransparency = ui->CutTransparency->value(); + // lambda function to set placement, shape color and transparency + auto setPlaceColorTransparency = [&](Part::Box* pcBox) { + pcBox->Placement.setValue(placement); + auto vpBox = dynamic_cast( + Gui::Application::Instance->getViewProvider(pcBox)); + if (vpBox) { + vpBox->ShapeColor.setValue(boxColor); + vpBox->Transparency.setValue(boxTransparency); + } + }; + + // lambda function to set transparency + auto setTransparency = [&](Part::Cut* pcCut) { + auto vpCut = dynamic_cast( + Gui::Application::Instance->getViewProvider(pcCut)); + if (vpCut) + vpCut->Transparency.setValue(compoundTransparency); + }; + if (ui->groupBoxX->isChecked()) { // create a box auto CutBox = doc->addObject("Part::Box", BoxXName); @@ -674,13 +733,7 @@ void SectionCut::startCutting(bool isInitial) BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5; placement.setPosition(BoxOriginSet); // set box color - pcBox->Placement.setValue(placement); - auto vpBox = dynamic_cast( - Gui::Application::Instance->getViewProvider(pcBox)); - if (vpBox) { - vpBox->ShapeColor.setValue(boxColor); - vpBox->Transparency.setValue(boxTransparency); - } + setPlaceColorTransparency(pcBox); // create a cut feature auto CutFeature = doc->addObject("Part::Cut", CutXName); @@ -692,6 +745,8 @@ void SectionCut::startCutting(bool isInitial) Part::Cut* pcCut = static_cast(CutFeature); pcCut->Base.setValue(CutCompound); pcCut->Tool.setValue(CutBox); + // we must set the compoundTransparency also for the cut + setTransparency(pcCut); // set the cut value ui->cutX->setValue(CutPosX); @@ -739,13 +794,7 @@ void SectionCut::startCutting(bool isInitial) BoxOriginSet.y = CutPosY; BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5; placement.setPosition(BoxOriginSet); - pcBox->Placement.setValue(placement); - auto vpBox = dynamic_cast( - Gui::Application::Instance->getViewProvider(pcBox)); - if (vpBox) { - vpBox->ShapeColor.setValue(boxColor); - vpBox->Transparency.setValue(boxTransparency); - } + setPlaceColorTransparency(pcBox); auto CutFeature = doc->addObject("Part::Cut", CutYName); if (!CutFeature) { @@ -760,6 +809,7 @@ void SectionCut::startCutting(bool isInitial) else pcCut->Base.setValue(CutCompound); pcCut->Tool.setValue(CutBox); + setTransparency(pcCut); // set the cut value ui->cutY->setValue(CutPosY); @@ -801,13 +851,7 @@ void SectionCut::startCutting(bool isInitial) else //flipped BoxOriginSet.z = CutPosZ; placement.setPosition(BoxOriginSet); - pcBox->Placement.setValue(placement); - auto vpBox = dynamic_cast( - Gui::Application::Instance->getViewProvider(pcBox)); - if (vpBox) { - vpBox->ShapeColor.setValue(boxColor); - vpBox->Transparency.setValue(boxTransparency); - } + setPlaceColorTransparency(pcBox); auto CutFeature = doc->addObject("Part::Cut", CutZName); if (!CutFeature) { @@ -827,6 +871,7 @@ void SectionCut::startCutting(bool isInitial) pcCut->Base.setValue(CutCompound); } pcCut->Tool.setValue(CutBox); + setTransparency(pcCut); // set the cut value ui->cutZ->setValue(CutPosZ); diff --git a/src/Mod/Part/Gui/SectionCutting.ui b/src/Mod/Part/Gui/SectionCutting.ui index 0d285a72c1..47067d8e0b 100644 --- a/src/Mod/Part/Gui/SectionCutting.ui +++ b/src/Mod/Part/Gui/SectionCutting.ui @@ -277,9 +277,9 @@ - 204 - 204 - 204 + 203 + 203 + 203 @@ -347,10 +347,10 @@ Works only if all objects have the same values. Qt::Horizontal - + DefaultShapeTransparency - + View