[Part] extend SectionCutting feature for intersecting objects
- it is a well-known and often feed-backed missing feature that SectionCuttings fails for intersecting objects. To resolve this, the objects must be put int a BooleanFragments object. - this PR adds this functionality as option. - since a BooleanFragments objects has a specific color, the different colors of the objects cannot be preserved. Because of this disadvantage, the BooleanFragments option will not be the default. - this PR also modernize all for loops
This commit is contained in:
@@ -110,9 +110,9 @@ SectionCut::SectionCut(QWidget* parent)
|
||||
return;
|
||||
}
|
||||
// now store those that are currently visible
|
||||
for (auto it = ObjectsList.begin(); it != ObjectsList.end(); ++it) {
|
||||
if ((*it)->Visibility.getValue())
|
||||
ObjectsListVisible.emplace_back(*it);
|
||||
for (auto anObject : ObjectsList) {
|
||||
if (anObject->Visibility.getValue())
|
||||
ObjectsListVisible.emplace_back(anObject);
|
||||
}
|
||||
|
||||
// lambda function to set color and transparency
|
||||
@@ -125,8 +125,8 @@ SectionCut::SectionCut(QWidget* parent)
|
||||
cutColor = vpBox->ShapeColor.getValue();
|
||||
cutTransparency = vpBox->Transparency.getValue();
|
||||
ui->CutColor->setColor(cutColor.asValue<QColor>());
|
||||
ui->CutTransparency->setValue(cutTransparency);
|
||||
ui->CutTransparency->setToolTip(QString::number(cutTransparency)
|
||||
ui->CutTransparencyHS->setValue(cutTransparency);
|
||||
ui->CutTransparencyHS->setToolTip(QString::number(cutTransparency)
|
||||
+ QString::fromLatin1(" %"));
|
||||
}
|
||||
};
|
||||
@@ -137,21 +137,56 @@ SectionCut::SectionCut(QWidget* parent)
|
||||
Base::BoundBox3d BoundCutBox;
|
||||
if (doc->getObject(BoxXName) || doc->getObject(BoxYName) || doc->getObject(BoxZName)) {
|
||||
// automatic coloring must be disabled
|
||||
ui->AutoCutfaceColor->setChecked(false);
|
||||
ui->autoCutfaceColorCB->setChecked(false);
|
||||
ui->autoBFColorCB->setChecked(false);
|
||||
if (doc->getObject(CompoundName)) {
|
||||
// get the object with the right name
|
||||
auto compoundObject = doc->getObject(CompoundName);
|
||||
Part::Compound* pcCompound = dynamic_cast<Part::Compound*>(compoundObject);
|
||||
if (!pcCompound) {
|
||||
Base::Console().Error(
|
||||
"SectionCut error: compound is incorrectly named, cannot proceed\n");
|
||||
return;
|
||||
// to later store the childs
|
||||
std::vector<App::DocumentObject*> compoundChilds;
|
||||
|
||||
// check if this is a BooleanFragments or a Part::Compound
|
||||
// Part::Compound is the case when there was only one object
|
||||
Part::Compound* pcCompoundPart = dynamic_cast<Part::Compound*>(compoundObject);
|
||||
if (!pcCompoundPart) {
|
||||
// for more security check for validity accessing its ViewProvider
|
||||
auto pcCompoundBF = Gui::Application::Instance->getViewProvider(compoundObject);
|
||||
if (!pcCompoundBF) {
|
||||
Base::Console().Error(
|
||||
"SectionCut error: compound is incorrectly named, cannot proceed\n");
|
||||
return;
|
||||
}
|
||||
auto property = compoundObject->getPropertyByName("Shape");
|
||||
Part::PropertyPartShape* objectShape =
|
||||
static_cast<Part::PropertyPartShape*>(property);
|
||||
BoundCompound = objectShape->getBoundingBox();
|
||||
// for BooleanFragments we also need to set the checkbox, transparency and color
|
||||
ui->groupBoxIntersecting->setChecked(true);
|
||||
auto pcCompoundBFGO = dynamic_cast<Gui::ViewProviderGeometryObject*>(pcCompoundBF);
|
||||
if (pcCompoundBFGO) {
|
||||
App::Color compoundColor = pcCompoundBFGO->ShapeColor.getValue();
|
||||
ui->BFragColor->setColor(compoundColor.asValue<QColor>());
|
||||
int compoundTransparency = pcCompoundBFGO->Transparency.getValue();
|
||||
ui->BFragTransparencyHS->setValue(compoundTransparency);
|
||||
ui->BFragTransparencyHS->setToolTip(QString::number(compoundTransparency)
|
||||
+ QString::fromLatin1(" %"));
|
||||
// Part::Cut ignores the cutbox transparency when it is set
|
||||
// to zero and the BooleanFragments transparency is not zero
|
||||
// therefore limit the cutbox transparency to 1 in this case
|
||||
if (compoundTransparency > 0)
|
||||
ui->CutTransparencyHS->setMinimum(1);
|
||||
else
|
||||
ui->CutTransparencyHS->setMinimum(0);
|
||||
}
|
||||
compoundChilds = pcCompoundBF->claimChildren();
|
||||
}
|
||||
else {
|
||||
BoundCompound = pcCompoundPart->Shape.getBoundingBox();
|
||||
pcCompoundPart->Links.getLinks(compoundChilds);
|
||||
}
|
||||
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 aCompoundObj : compoundObjects) {
|
||||
for (auto aCompoundObj : compoundChilds) {
|
||||
App::Link* pcLink = dynamic_cast<App::Link*>(aCompoundObj);
|
||||
auto LinkedObject = pcLink ? pcLink->getLink() : nullptr;
|
||||
if (LinkedObject) {
|
||||
@@ -273,9 +308,17 @@ SectionCut::SectionCut(QWidget* parent)
|
||||
connect(ui->flipZ, &QPushButton::clicked, this, &SectionCut::onFlipZclicked);
|
||||
connect(ui->RefreshCutPB, &QPushButton::clicked, this, &SectionCut::onRefreshCutPBclicked);
|
||||
connect(ui->CutColor, &QPushButton::clicked, this, &SectionCut::onCutColorclicked);
|
||||
connect(ui->CutTransparency, &QSlider::sliderMoved, this,
|
||||
&SectionCut::onTransparencySliderMoved);
|
||||
connect(ui->CutTransparency, &QSlider::valueChanged, this, &SectionCut::onTransparencyChanged);
|
||||
connect(ui->CutTransparencyHS, &QSlider::sliderMoved,
|
||||
this, &SectionCut::onTransparencyHSMoved);
|
||||
connect(ui->CutTransparencyHS, &QSlider::valueChanged,
|
||||
this, &SectionCut::onTransparencyHSChanged);
|
||||
connect(ui->groupBoxIntersecting, &QGroupBox::toggled,
|
||||
this, &SectionCut::onGroupBoxIntersectingToggled);
|
||||
connect(ui->BFragColor, &QPushButton::clicked, this, &SectionCut::onBFragColorclicked);
|
||||
connect(ui->BFragTransparencyHS, &QSlider::sliderMoved,
|
||||
this, &SectionCut::onBFragTransparencyHSMoved);
|
||||
connect(ui->BFragTransparencyHS,&QSlider::valueChanged,
|
||||
this, &SectionCut::onBFragTransparencyHSChanged);
|
||||
|
||||
// if there is a cut, perform it
|
||||
if (hasBoxX || hasBoxY || hasBoxZ) {
|
||||
@@ -314,7 +357,6 @@ void SectionCut::startCutting(bool isInitial)
|
||||
onRefreshCutPBclicked();
|
||||
|
||||
App::DocumentObject* anObject = nullptr;
|
||||
std::vector<App::DocumentObjectT>::iterator it;
|
||||
|
||||
// lambda function to delete objects
|
||||
auto deleteObject = [&](const char* objectName) {
|
||||
@@ -338,7 +380,7 @@ void SectionCut::startCutting(bool isInitial)
|
||||
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
|
||||
@@ -364,16 +406,28 @@ void SectionCut::startCutting(bool isInitial)
|
||||
if (doc->getObject(BoxXName))
|
||||
deleteObject(BoxXName);
|
||||
if (doc->getObject(CompoundName)) {
|
||||
// get the object with the right name
|
||||
auto compoundObject = doc->getObject(CompoundName);
|
||||
Part::Compound* pcCompoundDel = dynamic_cast<Part::Compound*>(compoundObject);
|
||||
if (!pcCompoundDel) {
|
||||
Base::Console().Error(
|
||||
"SectionCut error: compound is incorrectly named, cannot proceed\n");
|
||||
return;
|
||||
// to later store the childs
|
||||
std::vector<App::DocumentObject*> compoundChilds;
|
||||
|
||||
// check if this is a BooleanFragments or a Part::Compound
|
||||
Part::Compound* pcCompoundDelPart = dynamic_cast<Part::Compound*>(compoundObject);
|
||||
Gui::ViewProvider* pcCompoundDelBF;
|
||||
if (!pcCompoundDelPart) {
|
||||
// check for BooleanFragments
|
||||
pcCompoundDelBF = Gui::Application::Instance->getViewProvider(compoundObject);
|
||||
if (!pcCompoundDelBF) {
|
||||
Base::Console().Error(
|
||||
"SectionCut error: compound is incorrectly named, cannot proceed\n");
|
||||
return;
|
||||
}
|
||||
compoundChilds = pcCompoundDelBF->claimChildren();
|
||||
}
|
||||
// get the compound content
|
||||
std::vector<App::DocumentObject*> compoundObjects;
|
||||
pcCompoundDel->Links.getLinks(compoundObjects);
|
||||
else {
|
||||
pcCompoundDelPart->Links.getLinks(compoundChilds);
|
||||
}
|
||||
|
||||
// first delete the compound
|
||||
auto foundObj = std::find_if(
|
||||
ObjectsListVisible.begin(), ObjectsListVisible.end(),
|
||||
@@ -383,24 +437,23 @@ void SectionCut::startCutting(bool isInitial)
|
||||
ObjectsListVisible.erase(foundObj);
|
||||
doc->removeObject(CompoundName);
|
||||
// now delete the objects that have been part of the compound
|
||||
for (auto itCompound = compoundObjects.begin(); itCompound != compoundObjects.end();
|
||||
itCompound++) {
|
||||
anObject = doc->getObject((*itCompound)->getNameInDocument());
|
||||
for (auto aChild : compoundChilds) {
|
||||
anObject = doc->getObject(aChild->getNameInDocument());
|
||||
auto foundObjInner = std::find_if(ObjectsListVisible.begin(), ObjectsListVisible.end(),
|
||||
[anObject](const App::DocumentObjectT &objInner) {
|
||||
return (objInner.getObject() == anObject);
|
||||
});
|
||||
if (foundObjInner != ObjectsListVisible.end())
|
||||
ObjectsListVisible.erase((foundObjInner));
|
||||
doc->removeObject((*itCompound)->getNameInDocument());
|
||||
doc->removeObject(aChild->getNameInDocument());
|
||||
}
|
||||
}
|
||||
|
||||
// make all objects visible that have been visible when the dialog was called
|
||||
// because we made them invisible when we created cuts
|
||||
for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) {
|
||||
if (it->getObject()) // a formerly visible object might have been deleted
|
||||
it->getObject()->Visibility.setValue(true);
|
||||
for (auto& aVisObject : ObjectsListVisible) {
|
||||
if (aVisObject.getObject()) // a formerly visible object might have been deleted
|
||||
aVisObject.getObject()->Visibility.setValue(true);
|
||||
else {
|
||||
// we must refresh the ObjectsListVisible list
|
||||
onRefreshCutPBclicked();
|
||||
@@ -416,21 +469,20 @@ void SectionCut::startCutting(bool isInitial)
|
||||
// those that have a solid shape
|
||||
std::vector<App::DocumentObject*> ObjectsListCut;
|
||||
bool isLinkAssembly = false;
|
||||
for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) {
|
||||
App::DocumentObject* object = it->getObject();
|
||||
for (auto& aVisObject : ObjectsListVisible) {
|
||||
App::DocumentObject* object = aVisObject.getObject();
|
||||
if (!object) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// we need all Link objects in App::Part for example for Assembly 4
|
||||
if (object->getTypeId() == Base::Type::fromName("App::Part")) {
|
||||
App::Part* pcPart = static_cast<App::Part*>(object);
|
||||
|
||||
// collect all its link objects
|
||||
auto groupObjects = pcPart->Group.getValue();
|
||||
for (auto itGO = groupObjects.begin(); itGO != groupObjects.end(); ++itGO) {
|
||||
if ((*itGO)->getTypeId() == Base::Type::fromName("App::Link")) {
|
||||
ObjectsListCut.push_back((*itGO));
|
||||
for (auto aGroupObject : groupObjects) {
|
||||
if (aGroupObject->getTypeId() == Base::Type::fromName("App::Link")) {
|
||||
ObjectsListCut.push_back(aGroupObject);
|
||||
// we assume that App::Links inside a App::Part are an assembly
|
||||
isLinkAssembly = true;
|
||||
}
|
||||
@@ -438,12 +490,14 @@ void SectionCut::startCutting(bool isInitial)
|
||||
}
|
||||
// get all shapes that are also Part::Features
|
||||
if (object->getPropertyByName("Shape")
|
||||
&& object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature"))) {
|
||||
&& object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::Feature"))) {
|
||||
// sort out 2D objects, datums, App:Parts, compounds and objects that are
|
||||
// part of a PartDesign body
|
||||
if (!object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::Part2DObject"))
|
||||
&& !object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Datum"))
|
||||
&& !object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::Datum"))
|
||||
&& !object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("PartDesign::Feature"))
|
||||
&& !object->getTypeId().isDerivedFrom(
|
||||
@@ -474,29 +528,30 @@ void SectionCut::startCutting(bool isInitial)
|
||||
|
||||
// sort out objects that are part of Part::Boolean, Part::MultiCommon, Part::MultiFuse,
|
||||
// Part::Thickness and Part::FilletBase
|
||||
std::vector<App::DocumentObject*>::iterator it2;
|
||||
std::vector<App::DocumentObject*>::iterator it3;
|
||||
// check list of visible objects and not cut list because we want to repove from the cut list
|
||||
for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) {
|
||||
App::DocumentObject* object = it->getObject();
|
||||
// check list of visible objects and not cut list because we want to remove from the cut list
|
||||
for (auto &aVisObject : ObjectsListVisible) {
|
||||
App::DocumentObject* object = aVisObject.getObject();
|
||||
if (!object) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Boolean"))
|
||||
|| object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiCommon"))
|
||||
|| object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiFuse"))
|
||||
|| object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Thickness"))
|
||||
|| object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::MultiCommon"))
|
||||
|| object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::MultiFuse"))
|
||||
|| object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::Thickness"))
|
||||
|| object->getTypeId().isDerivedFrom(
|
||||
Base::Type::fromName("Part::FilletBase"))) {
|
||||
// get possible links
|
||||
auto subObjectList = object->getOutList();
|
||||
// if there are links, delete them
|
||||
if (!subObjectList.empty()) {
|
||||
for (it2 = subObjectList.begin(); it2 != subObjectList.end(); ++it2) {
|
||||
for (it3 = ObjectsListCut.begin(); it3 != ObjectsListCut.end(); ++it3) {
|
||||
if ((*it2) == (*it3)) {
|
||||
ObjectsListCut.erase(it3);
|
||||
for (auto aSubObj : subObjectList) {
|
||||
for (auto itCutObj = ObjectsListCut.begin(); itCutObj != ObjectsListCut.end();
|
||||
++itCutObj) {
|
||||
if (aSubObj == *itCutObj) {
|
||||
ObjectsListCut.erase(itCutObj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -526,8 +581,11 @@ void SectionCut::startCutting(bool isInitial)
|
||||
return;
|
||||
}
|
||||
|
||||
// disable intersection option because BooleanFragments requires at least 2 objects
|
||||
ui->groupBoxIntersecting->setEnabled(ObjectsListCut.size() > 1);
|
||||
|
||||
// we cut this way:
|
||||
// 1. put all existing objects into a part compound
|
||||
// 1. put all existing objects into a either a Part::Compound or a BooleanFragments object
|
||||
// 2. create a box with the size of the bounding box
|
||||
// 3. cut the box from the compound
|
||||
|
||||
@@ -543,14 +601,6 @@ void SectionCut::startCutting(bool isInitial)
|
||||
// disable refresh button
|
||||
ui->RefreshCutPB->setEnabled(false);
|
||||
|
||||
// create an empty compound
|
||||
auto CutCompound = doc->addObject("Part::Compound", CompoundName);
|
||||
if (!CutCompound) {
|
||||
Base::Console().Error( (std::string("SectionCut error: ")
|
||||
+ std::string(CompoundName) + std::string(" could not be added\n")).c_str() );
|
||||
return;
|
||||
}
|
||||
Part::Compound* pcCompound = static_cast<Part::Compound*>(CutCompound);
|
||||
// store color and transparency of first object
|
||||
App::Color cutColor;
|
||||
int cutTransparency;
|
||||
@@ -562,17 +612,17 @@ void SectionCut::startCutting(bool isInitial)
|
||||
cutColor = vpFirstObject->ShapeColor.getValue();
|
||||
cutTransparency = vpFirstObject->Transparency.getValue();
|
||||
}
|
||||
// fill it with all found elements with the copies of the elements
|
||||
int count = 0;
|
||||
for (auto itCuts = ObjectsListCut.begin(); itCuts != ObjectsListCut.end(); ++itCuts, count++) {
|
||||
// create link objects for all found elements
|
||||
std::vector<App::DocumentObject*> ObjectsListLinks;
|
||||
for (auto itCuts : ObjectsListCut) {
|
||||
// first create a link with a unique name
|
||||
std::string newName;
|
||||
// since links to normal Part objects all have the document name "Link",
|
||||
// use their label text instead
|
||||
if ((*itCuts)->getTypeId() == Base::Type::fromName("App::Link"))
|
||||
newName = (*itCuts)->Label.getValue();
|
||||
if (itCuts->getTypeId() == Base::Type::fromName("App::Link"))
|
||||
newName = itCuts->Label.getValue();
|
||||
else
|
||||
newName = (*itCuts)->getNameInDocument();
|
||||
newName = itCuts->getNameInDocument();
|
||||
newName = newName + "_CutLink";
|
||||
|
||||
auto newObject = doc->addObject("App::Link", newName.c_str());
|
||||
@@ -582,17 +632,20 @@ void SectionCut::startCutting(bool isInitial)
|
||||
}
|
||||
App::Link* pcLink = static_cast<App::Link*>(newObject);
|
||||
// set the object to the created empty link object
|
||||
pcLink->LinkedObject.setValue((*itCuts));
|
||||
pcLink->LinkedObject.setValue(itCuts);
|
||||
// we want to get the link at the same position as the original
|
||||
pcLink->LinkTransform.setValue(true);
|
||||
|
||||
// add link to list to later add this to the compound object
|
||||
ObjectsListLinks.push_back(newObject);
|
||||
|
||||
// if the object is part of an App::Part container,
|
||||
// the link needs to get the container placement
|
||||
auto parents = (*itCuts)->getInList();
|
||||
auto parents = itCuts->getInList();
|
||||
if (!parents.empty()) {
|
||||
for (auto itParents = parents.begin(); itParents != parents.end(); ++itParents) {
|
||||
if ((*itParents)->getTypeId() == Base::Type::fromName("App::Part")) {
|
||||
App::Part* pcPartParent = static_cast<App::Part*>((*itParents));
|
||||
for (auto parent : parents) {
|
||||
if (parent->getTypeId() == Base::Type::fromName("App::Part")) {
|
||||
App::Part* pcPartParent = static_cast<App::Part*>(parent);
|
||||
auto placement = Base::freecad_dynamic_cast<App::PropertyPlacement>(
|
||||
pcPartParent->getPropertyByName("Placement"));
|
||||
if (placement)
|
||||
@@ -601,16 +654,13 @@ void SectionCut::startCutting(bool isInitial)
|
||||
}
|
||||
}
|
||||
|
||||
// add the link to the compound
|
||||
pcCompound->Links.set1Value(count, newObject);
|
||||
|
||||
// hide the objects since only the cut should later be visible
|
||||
(*itCuts)->Visibility.setValue(false);
|
||||
itCuts->Visibility.setValue(false);
|
||||
|
||||
// check if all objects have same color and transparency
|
||||
if (ui->AutoCutfaceColor->isChecked()) {
|
||||
if (ui->autoCutfaceColorCB->isChecked() || ui->autoBFColorCB->isChecked()) {
|
||||
auto vpObject = dynamic_cast<Gui::ViewProviderGeometryObject*>(
|
||||
Gui::Application::Instance->getViewProvider(*itCuts));
|
||||
Gui::Application::Instance->getViewProvider(itCuts));
|
||||
if (vpObject) {
|
||||
if (cutColor != vpObject->ShapeColor.getValue())
|
||||
autoColor = false;
|
||||
@@ -620,24 +670,67 @@ 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);
|
||||
App::DocumentObject* CutCompoundBF = nullptr;
|
||||
Part::Compound* CutCompoundPart = nullptr;
|
||||
App::DocumentObject* CutCompoundPartObj = nullptr;
|
||||
|
||||
// compute the filled compound
|
||||
pcCompound->recomputeFeature();
|
||||
// specify transparency for the compound
|
||||
// if there was no compound, take the setting for the cut face
|
||||
if (ui->groupBoxIntersecting->isChecked())
|
||||
compoundTransparency = ui->BFragTransparencyHS->value();
|
||||
if (compoundTransparency == -1)
|
||||
compoundTransparency = ui->CutTransparencyHS->value();
|
||||
|
||||
// create BooleanFragments and fill it
|
||||
if (ui->groupBoxIntersecting->isChecked() && ObjectsListCut.size() > 1) {
|
||||
CutCompoundBF = CreateBooleanFragments(doc);
|
||||
// the BooleanFragment implementation requires to first add at least 2 objects
|
||||
// before any other setting to the BooleanFragment object can be made
|
||||
App::PropertyLinkList* CutLinkList =
|
||||
dynamic_cast<App::PropertyLinkList*>(CutCompoundBF->getPropertyByName("Objects"));
|
||||
if (!CutCompoundBF) {
|
||||
Base::Console().Error((std::string("SectionCut error: ") + std::string(CompoundName)
|
||||
+ std::string(" could not be added\n")).c_str());
|
||||
return;
|
||||
}
|
||||
CutLinkList->setValue(ObjectsListLinks);
|
||||
// make all objects in the BooleanFragments object invisible to later only show the cut
|
||||
for (auto aLinkObj : ObjectsListLinks) {
|
||||
aLinkObj->Visibility.setValue(false);
|
||||
}
|
||||
// set the transparency
|
||||
auto vpCompound = dynamic_cast<Gui::ViewProviderGeometryObject*>(
|
||||
Gui::Application::Instance->getViewProvider(CutCompoundBF));
|
||||
vpCompound->Transparency.setValue(compoundTransparency);
|
||||
// set the color
|
||||
// setBooleanFragmentsColor also does a non-recursive recompute
|
||||
setBooleanFragmentsColor();
|
||||
}
|
||||
else { // create Part::Compound and fill it
|
||||
// if there is only one object to be cut, we cannot create a BooleanFragments object
|
||||
CutCompoundPartObj = doc->addObject("Part::Compound", CompoundName);
|
||||
if (!CutCompoundPartObj) {
|
||||
Base::Console().Error((std::string("SectionCut error: ") + std::string(CompoundName)
|
||||
+ std::string(" could not be added\n")).c_str());
|
||||
return;
|
||||
}
|
||||
CutCompoundPart = static_cast<Part::Compound*>(CutCompoundPartObj);
|
||||
// add the link to the compound
|
||||
CutCompoundPart->Links.setValue(ObjectsListLinks);
|
||||
// set the transparency
|
||||
auto vpCompound = dynamic_cast<Gui::ViewProviderGeometryObject*>(
|
||||
Gui::Application::Instance->getViewProvider(CutCompoundPartObj));
|
||||
vpCompound->Transparency.setValue(compoundTransparency);
|
||||
CutCompoundPart->recomputeFeature();
|
||||
}
|
||||
|
||||
// make all objects invisible so that only the compound remains
|
||||
for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) {
|
||||
App::DocumentObject* object = it->getObject();
|
||||
for (auto &aVisObject : ObjectsListVisible) {
|
||||
App::DocumentObject* object = aVisObject.getObject();
|
||||
if (object) {
|
||||
object->Visibility.setValue(false);
|
||||
}
|
||||
object->Visibility.setValue(false);
|
||||
}
|
||||
|
||||
// the area in which we can cut is the size of the compound
|
||||
@@ -673,25 +766,39 @@ void SectionCut::startCutting(bool isInitial)
|
||||
hasBoxCustom = false;
|
||||
|
||||
// if automatic, we take this color for the cut
|
||||
if (ui->AutoCutfaceColor->isChecked()) {
|
||||
if (autoColor) {
|
||||
if (autoColor) {
|
||||
if (ui->autoCutfaceColorCB->isChecked()) {
|
||||
ui->CutColor->blockSignals(true);
|
||||
ui->CutColor->setColor(cutColor.asValue<QColor>());
|
||||
ui->CutColor->blockSignals(false);
|
||||
}
|
||||
if (autoTransparency) {
|
||||
ui->CutTransparency->blockSignals(true);
|
||||
ui->CutTransparency->setValue(cutTransparency);
|
||||
ui->CutTransparency->setToolTip(QString::number(cutTransparency)
|
||||
+ QString::fromLatin1(" %"));
|
||||
ui->CutTransparency->blockSignals(false);
|
||||
if (ui->autoBFColorCB->isChecked()) {
|
||||
ui->BFragColor->blockSignals(true);
|
||||
ui->BFragColor->setColor(cutColor.asValue<QColor>());
|
||||
ui->BFragColor->blockSignals(false);
|
||||
}
|
||||
}
|
||||
if (autoTransparency) {
|
||||
if (ui->autoCutfaceColorCB->isChecked()) {
|
||||
ui->CutTransparencyHS->blockSignals(true);
|
||||
ui->CutTransparencyHS->setValue(cutTransparency);
|
||||
ui->CutTransparencyHS->setToolTip(QString::number(cutTransparency)
|
||||
+ QString::fromLatin1(" %"));
|
||||
ui->CutTransparencyHS->blockSignals(false);
|
||||
}
|
||||
if (ui->autoBFColorCB->isChecked()) {
|
||||
ui->BFragTransparencyHS->blockSignals(true);
|
||||
ui->BFragTransparencyHS->setValue(cutTransparency);
|
||||
ui->BFragTransparencyHS->setToolTip(QString::number(cutTransparency)
|
||||
+ QString::fromLatin1(" %"));
|
||||
ui->BFragTransparencyHS->blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
// read cutface color for the cut box
|
||||
App::Color boxColor;
|
||||
boxColor.setValue<QColor>(ui->CutColor->color());
|
||||
int boxTransparency = ui->CutTransparency->value();
|
||||
int boxTransparency = ui->CutTransparencyHS->value();
|
||||
|
||||
// lambda function to set placement, shape color and transparency
|
||||
auto setPlaceColorTransparency = [&](Part::Box* pcBox) {
|
||||
@@ -737,16 +844,16 @@ void SectionCut::startCutting(bool isInitial)
|
||||
}
|
||||
// we don't set the value to ui->cutX because this would refresh the cut
|
||||
// which we don't have yet, thus do this later
|
||||
//set the box position
|
||||
// set the box position
|
||||
if (!ui->flipX->isChecked())
|
||||
BoxOriginSet.x = CutPosX - (BoundingBoxSize[0] + 1.0);
|
||||
else //flipped
|
||||
else // flipped
|
||||
BoxOriginSet.x = CutPosX;
|
||||
// we made the box 1.0 larger that we can place it 0.5 below the bounding box
|
||||
BoxOriginSet.y = BoundingBoxOrigin[1] - 0.5;
|
||||
BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5;
|
||||
placement.setPosition(BoxOriginSet);
|
||||
// set box color
|
||||
// set box placement, color and transparency
|
||||
setPlaceColorTransparency(pcBox);
|
||||
|
||||
// create a cut feature
|
||||
@@ -757,7 +864,10 @@ void SectionCut::startCutting(bool isInitial)
|
||||
return;
|
||||
}
|
||||
Part::Cut* pcCut = static_cast<Part::Cut*>(CutFeature);
|
||||
pcCut->Base.setValue(CutCompound);
|
||||
if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
|
||||
pcCut->Base.setValue(CutCompoundPart);
|
||||
else
|
||||
pcCut->Base.setValue(CutCompoundBF);
|
||||
pcCut->Tool.setValue(CutBox);
|
||||
// we must set the compoundTransparency also for the cut
|
||||
setTransparency(pcCut);
|
||||
@@ -800,11 +910,11 @@ void SectionCut::startCutting(bool isInitial)
|
||||
else if (CutPosY <= ui->cutY->minimum()) {
|
||||
CutPosY = ui->cutY->minimum() + 0.1; // short above the minimum
|
||||
}
|
||||
//set the box position
|
||||
// set the box position
|
||||
BoxOriginSet.x = BoundingBoxOrigin[0] - 0.5;
|
||||
if (!ui->flipY->isChecked())
|
||||
BoxOriginSet.y = CutPosY - (BoundingBoxSize[1] + 1.0);
|
||||
else //flipped
|
||||
else // flipped
|
||||
BoxOriginSet.y = CutPosY;
|
||||
BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5;
|
||||
placement.setPosition(BoxOriginSet);
|
||||
@@ -818,10 +928,15 @@ void SectionCut::startCutting(bool isInitial)
|
||||
}
|
||||
Part::Cut* pcCut = static_cast<Part::Cut*>(CutFeature);
|
||||
// if there is already a cut, we must take it as feature to be cut
|
||||
if (hasBoxX)
|
||||
if (hasBoxX) {
|
||||
pcCut->Base.setValue(doc->getObject(CutXName));
|
||||
else
|
||||
pcCut->Base.setValue(CutCompound);
|
||||
}
|
||||
else {
|
||||
if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
|
||||
pcCut->Base.setValue(CutCompoundPart);
|
||||
else
|
||||
pcCut->Base.setValue(CutCompoundBF);
|
||||
}
|
||||
pcCut->Tool.setValue(CutBox);
|
||||
setTransparency(pcCut);
|
||||
|
||||
@@ -857,12 +972,12 @@ void SectionCut::startCutting(bool isInitial)
|
||||
else if (CutPosZ <= ui->cutZ->minimum()) {
|
||||
CutPosZ = ui->cutZ->minimum() + 0.1; // short above the minimum
|
||||
}
|
||||
//set the box position
|
||||
// set the box position
|
||||
BoxOriginSet.x = BoundingBoxOrigin[0] - 0.5;
|
||||
BoxOriginSet.y = BoundingBoxOrigin[1] - 0.5;
|
||||
if (!ui->flipY->isChecked())
|
||||
BoxOriginSet.z = CutPosZ - (BoundingBoxSize[2] + 1.0);
|
||||
else //flipped
|
||||
else // flipped
|
||||
BoxOriginSet.z = CutPosZ;
|
||||
placement.setPosition(BoxOriginSet);
|
||||
setPlaceColorTransparency(pcBox);
|
||||
@@ -882,7 +997,10 @@ void SectionCut::startCutting(bool isInitial)
|
||||
pcCut->Base.setValue(doc->getObject(CutXName));
|
||||
}
|
||||
else {
|
||||
pcCut->Base.setValue(CutCompound);
|
||||
if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
|
||||
pcCut->Base.setValue(CutCompoundPart);
|
||||
else
|
||||
pcCut->Base.setValue(CutCompoundBF);
|
||||
}
|
||||
pcCut->Tool.setValue(CutBox);
|
||||
setTransparency(pcCut);
|
||||
@@ -920,9 +1038,9 @@ SectionCut::~SectionCut()
|
||||
if (!ui->keepOnlyCutCB->isChecked()) {
|
||||
// make all objects visible that have been visible when the dialog was called
|
||||
// because we made them invisible when we created cuts
|
||||
for (auto it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) {
|
||||
if (it->getObject()) // a formerly visible object might have been deleted
|
||||
it->getObject()->Visibility.setValue(true);
|
||||
for (auto& aVisObj : ObjectsListVisible) {
|
||||
if (aVisObj.getObject())// a formerly visible object might have been deleted
|
||||
aVisObj.getObject()->Visibility.setValue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1590,8 +1708,9 @@ void SectionCut::onFlipZclicked()
|
||||
// changes the cutface color
|
||||
void SectionCut::onCutColorclicked()
|
||||
{
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked())
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked()) {
|
||||
changeCutBoxColors();
|
||||
}
|
||||
}
|
||||
|
||||
// changes cutbox colors
|
||||
@@ -1605,38 +1724,173 @@ void SectionCut::changeCutBoxColors()
|
||||
App::Color boxColor;
|
||||
boxColor.setValue<QColor>(ui->CutColor->color());
|
||||
boxVPGO->ShapeColor.setValue(boxColor);
|
||||
int boxTransparency = ui->CutTransparency->value();
|
||||
int boxTransparency = ui->CutTransparencyHS->value();
|
||||
boxVPGO->Transparency.setValue(boxTransparency);
|
||||
}
|
||||
};
|
||||
if (doc->getObject(BoxXName))
|
||||
if (doc->getObject(BoxXName)) {
|
||||
setColorTransparency(doc->getObject(BoxXName));
|
||||
if (doc->getObject(BoxYName))
|
||||
}
|
||||
if (doc->getObject(BoxYName)) {
|
||||
setColorTransparency(doc->getObject(BoxYName));
|
||||
if (doc->getObject(BoxZName))
|
||||
}
|
||||
if (doc->getObject(BoxZName)) {
|
||||
setColorTransparency(doc->getObject(BoxZName));
|
||||
}
|
||||
|
||||
// we must recompute the topmost cut to make the color visible
|
||||
if (doc->getObject(CutZName))
|
||||
doc->getObject(CutZName)->recomputeFeature(false);
|
||||
else if (doc->getObject(CutYName))
|
||||
doc->getObject(CutYName)->recomputeFeature(false);
|
||||
else if (doc->getObject(CutXName))
|
||||
// we must hereby first recompute ewvery cut non-recursively in the order X -> Y -> Z
|
||||
// eventually recompute the topmost cut recursively
|
||||
if (doc->getObject(CutXName)) {
|
||||
doc->getObject(CutXName)->recomputeFeature(false);
|
||||
}
|
||||
if (doc->getObject(CutYName)) {
|
||||
doc->getObject(CutYName)->recomputeFeature(false);
|
||||
}
|
||||
if (doc->getObject(CutZName)) {
|
||||
doc->getObject(CutZName)->recomputeFeature(false);
|
||||
}
|
||||
if (doc->getObject(CutZName)) {
|
||||
doc->getObject(CutZName)->recomputeFeature(true);
|
||||
}
|
||||
else if (doc->getObject(CutYName)) {
|
||||
doc->getObject(CutYName)->recomputeFeature(true);
|
||||
}
|
||||
else if (doc->getObject(CutXName)) {
|
||||
doc->getObject(CutXName)->recomputeFeature(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SectionCut::onTransparencySliderMoved(int val)
|
||||
void SectionCut::onTransparencyHSMoved(int val)
|
||||
{
|
||||
ui->CutTransparency->setToolTip(QString::number(val) + QString::fromLatin1(" %"));
|
||||
ui->CutTransparencyHS->setToolTip(QString::number(val) + QString::fromLatin1(" %"));
|
||||
// highlight the tooltip
|
||||
QToolTip::showText(QCursor::pos(), QString::number(val) + QString::fromLatin1(" %"), nullptr);
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked())
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked()) {
|
||||
changeCutBoxColors();
|
||||
}
|
||||
}
|
||||
|
||||
void SectionCut::onTransparencyChanged(int val)
|
||||
void SectionCut::onTransparencyHSChanged(int val)
|
||||
{
|
||||
onTransparencySliderMoved(val);
|
||||
onTransparencyHSMoved(val);
|
||||
}
|
||||
|
||||
// change from/to BooleanFragments compound
|
||||
void SectionCut::onGroupBoxIntersectingToggled()
|
||||
{
|
||||
// re-cut
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked()) {
|
||||
startCutting();
|
||||
}
|
||||
}
|
||||
|
||||
// changes the BooleanFragments color
|
||||
void SectionCut::onBFragColorclicked()
|
||||
{
|
||||
// when there is no cut yet, there is nothing to do
|
||||
if (!(ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked())) {
|
||||
return;
|
||||
}
|
||||
|
||||
setBooleanFragmentsColor();
|
||||
// we must recompute the topmost cut to make the color visible
|
||||
if (doc->getObject(CutZName)) {
|
||||
doc->getObject(CutZName)->recomputeFeature(true);
|
||||
}
|
||||
else if (doc->getObject(CutYName)) {
|
||||
doc->getObject(CutYName)->recomputeFeature(true);
|
||||
}
|
||||
else if (doc->getObject(CutXName)) {
|
||||
doc->getObject(CutXName)->recomputeFeature(true);
|
||||
}
|
||||
}
|
||||
|
||||
// sets BooleanFragments color
|
||||
void SectionCut::setBooleanFragmentsColor()
|
||||
{
|
||||
App::DocumentObject* compoundObject;
|
||||
if (doc->getObject(CompoundName)) {
|
||||
// get the object with the right name
|
||||
compoundObject = doc->getObject(CompoundName);
|
||||
}
|
||||
else {
|
||||
Base::Console().Error("SectionCut error: compound is incorrectly named, cannot proceed\n");
|
||||
return;
|
||||
}
|
||||
// assure it is not a Part::Compound
|
||||
Part::Compound* pcCompound = dynamic_cast<Part::Compound*>(compoundObject);
|
||||
Gui::ViewProvider* CompoundBFVP;
|
||||
if (!pcCompound) {
|
||||
// check for valid BooleanFragments by accessing its ViewProvider
|
||||
CompoundBFVP = Gui::Application::Instance->getViewProvider(compoundObject);
|
||||
if (!CompoundBFVP) {
|
||||
Base::Console().Error("SectionCut error: cannot access ViewProvider of cut compound\n");
|
||||
return;
|
||||
}
|
||||
auto CutCompoundBFGeom = dynamic_cast<Gui::ViewProviderGeometryObject*>(CompoundBFVP);
|
||||
if (CutCompoundBFGeom) {
|
||||
App::Color BFColor;
|
||||
BFColor.setValue<QColor>(ui->BFragColor->color());
|
||||
CutCompoundBFGeom->ShapeColor.setValue(BFColor);
|
||||
int BFTransparency = ui->BFragTransparencyHS->value();
|
||||
CutCompoundBFGeom->Transparency.setValue(BFTransparency);
|
||||
compoundObject->recomputeFeature(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SectionCut::onBFragTransparencyHSMoved(int val)
|
||||
{
|
||||
// lambda to set transparency
|
||||
auto setTransparency = [&](App::DocumentObject* cutObject) {
|
||||
Gui::ViewProvider* CutVP = Gui::Application::Instance->getViewProvider(cutObject);
|
||||
if (!CutVP) {
|
||||
Base::Console().Error(
|
||||
"SectionCut error: cannot access ViewProvider of cut object\n");
|
||||
return;
|
||||
}
|
||||
auto CutVPGeom = dynamic_cast<Gui::ViewProviderGeometryObject*>(CutVP);
|
||||
if (CutVPGeom) {
|
||||
int BFTransparency = ui->BFragTransparencyHS->value();
|
||||
CutVPGeom->Transparency.setValue(BFTransparency);
|
||||
cutObject->recomputeFeature(true);
|
||||
}
|
||||
};
|
||||
|
||||
// Part::Cut ignores the cutbox transparency when it is set
|
||||
// to zero and the BooleanFragments transparency is not zero
|
||||
// therefore limit the cutbox transparency to 1 in this case
|
||||
if (val > 0) {
|
||||
ui->CutTransparencyHS->setMinimum(1);
|
||||
}
|
||||
else {
|
||||
ui->CutTransparencyHS->setMinimum(0);
|
||||
}
|
||||
|
||||
ui->BFragTransparencyHS->setToolTip(QString::number(val) + QString::fromLatin1(" %"));
|
||||
// highlight the tooltip
|
||||
QToolTip::showText(QCursor::pos(), QString::number(val) + QString::fromLatin1(" %"), nullptr);
|
||||
|
||||
// when there is no cut yet, there is nothing else to do
|
||||
if (ui->groupBoxX->isChecked() || ui->groupBoxY->isChecked() || ui->groupBoxZ->isChecked()) {
|
||||
setBooleanFragmentsColor();
|
||||
// we must set the transparency to every cut and recompute in the order X -> Y -> Z
|
||||
if (doc->getObject(CutXName)) {
|
||||
setTransparency(doc->getObject(CutXName));
|
||||
}
|
||||
if (doc->getObject(CutYName)) {
|
||||
setTransparency(doc->getObject(CutYName));
|
||||
}
|
||||
if (doc->getObject(CutZName)) {
|
||||
setTransparency(doc->getObject(CutZName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SectionCut::onBFragTransparencyHSChanged(int val)
|
||||
{
|
||||
onBFragTransparencyHSMoved(val);
|
||||
}
|
||||
|
||||
// refreshes the list of document objects and the visible objects
|
||||
@@ -1658,11 +1912,13 @@ void SectionCut::onRefreshCutPBclicked()
|
||||
// empty the ObjectsListVisible
|
||||
ObjectsListVisible.clear();
|
||||
// now store those that are currently visible
|
||||
for (auto it = ObjectsList.begin(); it != ObjectsList.end(); ++it) {
|
||||
if ((*it)->Visibility.getValue()) {
|
||||
ObjectsListVisible.emplace_back(*it);
|
||||
for (auto anObject : ObjectsList) {
|
||||
if (anObject->Visibility.getValue()) {
|
||||
ObjectsListVisible.emplace_back(anObject);
|
||||
}
|
||||
}
|
||||
// disable intersection option because BooleanFragments requires at least 2 objects
|
||||
ui->groupBoxIntersecting->setEnabled(ObjectsListVisible.size() > 1);
|
||||
// reset defaults
|
||||
hasBoxX = false;
|
||||
hasBoxY = false;
|
||||
@@ -1776,4 +2032,22 @@ void SectionCut::refreshCutRanges(SbBox3f BoundingBox,
|
||||
}
|
||||
}
|
||||
|
||||
App::DocumentObject* SectionCut::CreateBooleanFragments(App::Document* doc)
|
||||
{
|
||||
// create the object
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "import FreeCAD");
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "from BOPTools import SplitFeatures");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"SplitFeatures.makeBooleanFragments(name=\"%s\")",
|
||||
CompoundName);
|
||||
// check for success
|
||||
App::DocumentObject* object = doc->getObject(CompoundName);
|
||||
if (!object) {
|
||||
Base::Console().Error((std::string("SectionCut error: ") + std::string(CompoundName)
|
||||
+ std::string(" could not be added\n")).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
#include "moc_SectionCutting.cpp"
|
||||
|
||||
@@ -61,14 +61,18 @@ protected Q_SLOTS:
|
||||
void onFlipZclicked();
|
||||
void onRefreshCutPBclicked();
|
||||
void onCutColorclicked();
|
||||
void onTransparencySliderMoved(int);
|
||||
void onTransparencyChanged(int);
|
||||
void onTransparencyHSMoved(int);
|
||||
void onTransparencyHSChanged(int);
|
||||
void onGroupBoxIntersectingToggled();
|
||||
void onBFragColorclicked();
|
||||
void onBFragTransparencyHSMoved(int);
|
||||
void onBFragTransparencyHSChanged(int);
|
||||
|
||||
public:
|
||||
void reject() override;
|
||||
|
||||
private:
|
||||
Ui_SectionCut* ui;
|
||||
std::unique_ptr<Ui_SectionCut> ui;
|
||||
std::vector<App::DocumentObjectT> ObjectsListVisible;
|
||||
App::Document* doc = nullptr; // pointer to active document
|
||||
bool hasBoxX = false;
|
||||
@@ -90,6 +94,8 @@ private:
|
||||
const char* CutYName = "SectionCutY";
|
||||
const char* CutZName = "SectionCutZ";
|
||||
void changeCutBoxColors();
|
||||
App::DocumentObject* CreateBooleanFragments(App::Document* doc);
|
||||
void setBooleanFragmentsColor();
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>230</width>
|
||||
<height>427</height>
|
||||
<height>514</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
@@ -19,7 +19,7 @@
|
||||
<property name="windowTitle">
|
||||
<string>Permanent Section Cutting</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBoxX">
|
||||
<property name="maximumSize">
|
||||
@@ -275,7 +275,7 @@
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="color" stdset="0">
|
||||
<property name="color">
|
||||
<color>
|
||||
<red>203</red>
|
||||
<green>203</green>
|
||||
@@ -291,7 +291,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::PrefCheckBox" name="AutoCutfaceColor">
|
||||
<widget class="Gui::PrefCheckBox" name="autoCutfaceColorCB">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@@ -301,7 +301,8 @@
|
||||
<property name="toolTip">
|
||||
<string>If checked, the color and transparency
|
||||
will be taken from the cut objects.
|
||||
Works only if all objects have the same values.</string>
|
||||
Works only properly if all objects
|
||||
have the same values.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
@@ -334,7 +335,7 @@ Works only if all objects have the same values.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="Gui::PrefSlider" name="CutTransparency">
|
||||
<widget class="Gui::PrefSlider" name="CutTransparencyHS">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -358,7 +359,150 @@ Works only if all objects have the same values.</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBoxIntersecting">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Allows to cut objects intersecting each other
|
||||
for the price that all cut objects
|
||||
will get the same color</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Cut intersecting objects</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Color of cut face</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::PrefColorButton" name="BFragColor">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Color for all objects</string>
|
||||
</property>
|
||||
<property name="color">
|
||||
<color>
|
||||
<red>203</red>
|
||||
<green>203</green>
|
||||
<blue>203</blue>
|
||||
</color>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultShapeColor</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>View</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::PrefCheckBox" name="autoBFColorCB">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>If checked, the color and transparency
|
||||
will be taken from the cut objects.
|
||||
Works only properly if all objects
|
||||
have the same values.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>TwoSideRendering</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Part</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Transparency of cut face</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Transparency</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="Gui::PrefSlider" name="BFragTransparencyHS">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true">0 %</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultShapeTransparency</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>View</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="RefreshCutPB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@@ -371,7 +515,7 @@ Works only if all objects have the same values.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -384,7 +528,7 @@ Works only if all objects have the same values.</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<item row="5" column="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -394,7 +538,7 @@ Works only if all objects have the same values.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="keepOnlyCutCB">
|
||||
<property name="toolTip">
|
||||
<string>When the dialog is closed,
|
||||
@@ -405,7 +549,7 @@ only created cuts will be visible</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<item row="7" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -472,9 +616,9 @@ only created cuts will be visible</string>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>AutoCutfaceColor</sender>
|
||||
<sender>autoCutfaceColorCB</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>CutTransparency</receiver>
|
||||
<receiver>CutTransparencyHS</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
@@ -488,7 +632,7 @@ only created cuts will be visible</string>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>AutoCutfaceColor</sender>
|
||||
<sender>autoCutfaceColorCB</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>CutColor</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
@@ -503,5 +647,37 @@ only created cuts will be visible</string>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>autoBFColorCB</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>BFragColor</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>182</x>
|
||||
<y>427</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>119</x>
|
||||
<y>427</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>autoBFColorCB</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>BFragTransparencyHS</receiver>
|
||||
<slot>setDisabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>182</x>
|
||||
<y>427</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>150</x>
|
||||
<y>454</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
||||
Reference in New Issue
Block a user