[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
This commit is contained in:
Uwe
2023-01-24 02:16:56 +01:00
committed by Chris Hennes
parent f727945f1e
commit 1f6c1fcd0f
2 changed files with 75 additions and 30 deletions

View File

@@ -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<App::DocumentObject*> compoundObjects;
pcCompound->Links.getLinks(compoundObjects);
for (auto itCompound = compoundObjects.begin(); itCompound != compoundObjects.end();
itCompound++) {
App::Link* pcLink = dynamic_cast<App::Link*>(*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::ViewProviderGeometryObject*>(
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<App::DocumentObject*> 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::ViewProviderGeometryObject*>(
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<QColor>(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::ViewProviderGeometryObject*>(
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::ViewProviderGeometryObject*>(
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::ViewProviderGeometryObject*>(
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<Part::Cut*>(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::ViewProviderGeometryObject*>(
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::ViewProviderGeometryObject*>(
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);

View File

@@ -277,9 +277,9 @@
</property>
<property name="color" stdset="0">
<color>
<red>204</red>
<green>204</green>
<blue>204</blue>
<red>203</red>
<green>203</green>
<blue>203</blue>
</color>
</property>
<property name="prefEntry" stdset="0">
@@ -347,10 +347,10 @@ Works only if all objects have the same values.</string>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="prefEntry">
<property name="prefEntry" stdset="0">
<cstring>DefaultShapeTransparency</cstring>
</property>
<property name="prefPath">
<property name="prefPath" stdset="0">
<cstring>View</cstring>
</property>
</widget>