[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:
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user