Changed tree ordering of booleans and bodies
This commit is contained in:
parent
106efeec02
commit
026242231e
|
@ -90,7 +90,7 @@ const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f)
|
|||
throw Base::Exception("getPointFromFace(): Not implemented yet for this case");
|
||||
}
|
||||
|
||||
const TopoDS_Shape& Feature::getBaseShape() const {
|
||||
const Part::Feature* Feature::getBaseObject() const {
|
||||
App::DocumentObject* BaseLink = BaseFeature.getValue();
|
||||
if (BaseLink == NULL) throw Base::Exception("Base property not set");
|
||||
Part::Feature* BaseObject = NULL;
|
||||
|
@ -100,6 +100,12 @@ const TopoDS_Shape& Feature::getBaseShape() const {
|
|||
if (BaseObject == NULL)
|
||||
throw Base::Exception("No base feature linked");
|
||||
|
||||
return BaseObject;
|
||||
}
|
||||
|
||||
const TopoDS_Shape& Feature::getBaseShape() const {
|
||||
const Part::Feature* BaseObject = getBaseObject();
|
||||
|
||||
const TopoDS_Shape& result = BaseObject->Shape.getValue();
|
||||
if (result.IsNull())
|
||||
throw Base::Exception("Base feature's shape is invalid");
|
||||
|
@ -110,6 +116,16 @@ const TopoDS_Shape& Feature::getBaseShape() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
const Part::TopoShape Feature::getBaseTopoShape() const {
|
||||
const Part::Feature* BaseObject = getBaseObject();
|
||||
|
||||
const Part::TopoShape& result = BaseObject->Shape.getShape();
|
||||
if (result._Shape.IsNull())
|
||||
throw Base::Exception("Base feature's TopoShape is invalid");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Feature::isDatum(const App::DocumentObject* feature)
|
||||
{
|
||||
return feature->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ||
|
||||
|
|
|
@ -57,8 +57,12 @@ public:
|
|||
static bool isDatum(const App::DocumentObject* feature);
|
||||
|
||||
protected:
|
||||
/// Returns the BaseFeature property's object (if any)
|
||||
const Part::Feature* getBaseObject() const;
|
||||
/// Returns the BaseFeature property's shape (if any)
|
||||
const TopoDS_Shape& getBaseShape() const;
|
||||
/// Returns the BaseFeature property's TopoShape (if any)
|
||||
const Part::TopoShape getBaseTopoShape() const;
|
||||
|
||||
/**
|
||||
* Get a solid of the given shape. If no solid is found an exception is raised.
|
||||
|
|
|
@ -60,33 +60,36 @@ short Boolean::mustExecute() const
|
|||
|
||||
App::DocumentObjectExecReturn *Boolean::execute(void)
|
||||
{
|
||||
// Get the base shape to operate on
|
||||
Part::TopoShape baseTopShape;
|
||||
try {
|
||||
baseTopShape = getBaseTopoShape();
|
||||
} catch (const Base::Exception&) {
|
||||
return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid base shape");
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> bodies = Bodies.getValues();
|
||||
if (bodies.empty())
|
||||
return App::DocumentObject::StdReturn;
|
||||
|
||||
// Get the first body
|
||||
if (bodies.front() == NULL)
|
||||
return new App::DocumentObjectExecReturn("No body for boolean");
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(bodies.front());
|
||||
const Part::TopoShape& bodyTopShape = body->Shape.getShape();
|
||||
if (bodyTopShape._Shape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Cannot do boolean operation on invalid body shape");
|
||||
|
||||
// create an untransformed copy of the body shape
|
||||
Part::TopoShape bodyShape(bodyTopShape);
|
||||
bodyShape.setTransform(Base::Matrix4D());
|
||||
TopoDS_Shape result = bodyShape._Shape;
|
||||
// create an untransformed copy of the base shape
|
||||
Part::TopoShape baseShape(baseTopShape);
|
||||
baseShape.setTransform(Base::Matrix4D());
|
||||
TopoDS_Shape result = baseShape._Shape;
|
||||
|
||||
// Position this feature by the first body
|
||||
this->Placement.setValue(body->Placement.getValue());
|
||||
const Part::Feature* baseFeature;
|
||||
try {
|
||||
baseFeature = getBaseObject();
|
||||
} catch (const Base::Exception&) {
|
||||
return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid BaseFeature");
|
||||
}
|
||||
this->Placement.setValue(baseFeature->Placement.getValue());
|
||||
|
||||
// Get the operation type
|
||||
std::string type = Type.getValueAsString();
|
||||
|
||||
std::vector<App::DocumentObject*>::const_iterator b = bodies.begin();
|
||||
b++;
|
||||
|
||||
for (; b != bodies.end(); b++)
|
||||
for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++)
|
||||
{
|
||||
// Extract the body shape
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(*b);
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
#include "ReferenceSelection.h"
|
||||
|
||||
//===========================================================================
|
||||
// PartDesign_Body
|
||||
|
@ -737,7 +738,7 @@ bool CmdPartDesignNewSketch::isActive(void)
|
|||
// Common utility functions for all features creating solids
|
||||
//===========================================================================
|
||||
|
||||
void finishFeature(const Gui::Command* cmd, const std::string& FeatName)
|
||||
void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const bool hidePrevSolid = true)
|
||||
{
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody();
|
||||
|
||||
|
@ -746,7 +747,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName)
|
|||
|
||||
if (cmd->isActiveObjectValid() && (pcActiveBody != NULL)) {
|
||||
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature(NULL, false);
|
||||
if (prevSolidFeature != NULL)
|
||||
if (hidePrevSolid && (prevSolidFeature != NULL))
|
||||
cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument());
|
||||
}
|
||||
cmd->updateActive();
|
||||
|
@ -1626,33 +1627,41 @@ CmdPartDesignBoolean::CmdPartDesignBoolean()
|
|||
void CmdPartDesignBoolean::activated(int iMsg)
|
||||
{
|
||||
Gui::SelectionFilter BodyFilter("SELECT PartDesign::Body COUNT 1..");
|
||||
std::string bodyString("[");
|
||||
PartDesign::Body* body;
|
||||
std::string bodyString("");
|
||||
|
||||
if (BodyFilter.match()) {
|
||||
body = static_cast<PartDesign::Body*>(BodyFilter.Result[0][0].getObject());
|
||||
std::vector<App::DocumentObject*> bodies;
|
||||
for (std::vector<std::vector<Gui::SelectionObject> >::iterator i = BodyFilter.Result.begin();
|
||||
i != BodyFilter.Result.end(); i++) {
|
||||
std::vector<std::vector<Gui::SelectionObject> >::iterator i = BodyFilter.Result.begin();
|
||||
i++;
|
||||
for (; i != BodyFilter.Result.end(); i++) {
|
||||
for (std::vector<Gui::SelectionObject>::iterator j = i->begin(); j != i->end(); j++) {
|
||||
bodies.push_back(j->getObject());
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++)
|
||||
bodyString += std::string("App.activeDocument().") + (*b)->getNameInDocument() + ",";
|
||||
bodyString += "]";
|
||||
bodyString = PartDesignGui::getPythonStr(bodies);
|
||||
} else {
|
||||
bodyString = "";
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No body selected"),
|
||||
QObject::tr("Please select a body for the boolean operation"));
|
||||
return;
|
||||
}
|
||||
|
||||
openCommand("Create Boolean");
|
||||
|
||||
// Make sure we are working on the selected body
|
||||
if (body != PartDesignGui::ActivePartObject) {
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelection(body->getDocument()->getName(), body->Tip.getValue()->getNameInDocument());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
|
||||
}
|
||||
|
||||
std::string FeatName = getUniqueObjectName("Boolean");
|
||||
|
||||
openCommand("Create Boolean");
|
||||
doCommand(Doc,"App.activeDocument().addObject('PartDesign::Boolean','%s')",FeatName.c_str());
|
||||
if (!bodyString.empty())
|
||||
doCommand(Doc,"App.activeDocument().%s.Bodies = %s",FeatName.c_str(),bodyString.c_str());
|
||||
//doCommand(Gui,"App.activeDocument().recompute()");
|
||||
//doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str());
|
||||
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
|
||||
finishFeature(this, FeatName, false);
|
||||
}
|
||||
|
||||
bool CmdPartDesignBoolean::isActive(void)
|
||||
|
|
|
@ -155,4 +155,15 @@ const std::string getPythonStr(const App::DocumentObject* obj, const std::vector
|
|||
return std::string("(App.ActiveDocument.") + obj->getNameInDocument() + ", [\"" + sub.front() + "\"])";
|
||||
}
|
||||
|
||||
const std::string getPythonStr(const std::vector<App::DocumentObject*> objs)
|
||||
{
|
||||
std::string result("[");
|
||||
|
||||
for (std::vector<App::DocumentObject*>::const_iterator o = objs.begin(); o != objs.end(); o++)
|
||||
result += std::string("App.activeDocument().") + (*o)->getNameInDocument() + ",";
|
||||
result += "]";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,8 +53,10 @@ void getReferencedSelection(const App::DocumentObject* thisObj, const Gui::Selec
|
|||
App::DocumentObject*& selObj, std::vector<std::string>& selSub);
|
||||
/// Return reference as string for UI elements (format <obj>:<subelement>
|
||||
const QString getRefStr(const App::DocumentObject* obj, const std::vector<std::string>& sub);
|
||||
/// Return reference as string for python (format (<obj>, ["<subelement>"]) )
|
||||
/// Return reference as string for python in the format (<obj>, ["<subelement>",])
|
||||
const std::string getPythonStr(const App::DocumentObject* obj, const std::vector<std::string>& sub);
|
||||
/// Return reference as string for python in the format [obj1, obj2, ...,]
|
||||
const std::string getPythonStr(const std::vector<App::DocumentObject*> objs);
|
||||
|
||||
} //namespace PartDesignGui
|
||||
|
||||
|
|
|
@ -122,15 +122,15 @@ void TaskBooleanParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
|||
ui->buttonBodyAdd->setChecked(false);
|
||||
exitSelectionMode();
|
||||
|
||||
// Hide the bodies if there are more than two
|
||||
if (bodies.size() == 2) {
|
||||
// Hide both bodies
|
||||
// Hide the bodies
|
||||
if (bodies.size() == 1) {
|
||||
// Hide base body and added body
|
||||
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(
|
||||
Gui::Application::Instance->getViewProvider(bodies.front()));
|
||||
Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue()));
|
||||
if (vp != NULL)
|
||||
vp->hide();
|
||||
vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(
|
||||
Gui::Application::Instance->getViewProvider(bodies.back()));
|
||||
Gui::Application::Instance->getViewProvider(bodies.front()));
|
||||
if (vp != NULL)
|
||||
vp->hide();
|
||||
BooleanView->show();
|
||||
|
@ -163,9 +163,9 @@ void TaskBooleanParameters::onSelectionChanged(const Gui::SelectionChanges& msg)
|
|||
Gui::Application::Instance->getViewProvider(*b));
|
||||
if (vp != NULL)
|
||||
vp->show();
|
||||
if (bodies.size() == 1) {
|
||||
if (bodies.size() == 0) {
|
||||
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(
|
||||
Gui::Application::Instance->getViewProvider(bodies.front()));
|
||||
Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue()));
|
||||
if (vp != NULL)
|
||||
vp->show();
|
||||
BooleanView->hide();
|
||||
|
@ -180,7 +180,10 @@ void TaskBooleanParameters::onButtonBodyAdd(bool checked)
|
|||
if (checked) {
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc != NULL)
|
||||
doc->setHide(BooleanView->getObject()->getNameInDocument());
|
||||
BooleanView->hide();
|
||||
PartDesign::Boolean* pcBoolean = static_cast<PartDesign::Boolean*>(BooleanView->getObject());
|
||||
if (pcBoolean->Bodies.getValues().empty())
|
||||
doc->setHide(pcBoolean->BaseFeature.getValue()->getNameInDocument());
|
||||
selectionMode = bodyAdd;
|
||||
Gui::Selection().clearSelection();
|
||||
} else {
|
||||
|
@ -193,7 +196,7 @@ void TaskBooleanParameters::onButtonBodyRemove(bool checked)
|
|||
if (checked) {
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc != NULL)
|
||||
doc->setHide(BooleanView->getObject()->getNameInDocument());
|
||||
BooleanView->show();
|
||||
selectionMode = bodyRemove;
|
||||
Gui::Selection().clearSelection();
|
||||
} else {
|
||||
|
@ -247,9 +250,9 @@ void TaskBooleanParameters::onBodyDeleted(void)
|
|||
Gui::Application::Instance->getViewProvider(body));
|
||||
if (vp != NULL)
|
||||
vp->show();
|
||||
if (bodies.size() == 1) {
|
||||
if (bodies.empty()) {
|
||||
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(
|
||||
Gui::Application::Instance->getViewProvider(bodies.front()));
|
||||
Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue()));
|
||||
if (vp != NULL)
|
||||
vp->show();
|
||||
BooleanView->hide();
|
||||
|
@ -343,10 +346,21 @@ bool TaskDlgBooleanParameters::accept()
|
|||
|
||||
bool TaskDlgBooleanParameters::reject()
|
||||
{
|
||||
// Show the bodies again
|
||||
PartDesign::Boolean* obj = static_cast<PartDesign::Boolean*>(BooleanView->getObject());
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc != NULL) {
|
||||
doc->setShow(obj->BaseFeature.getValue()->getNameInDocument());
|
||||
std::vector<App::DocumentObject*> bodies = obj->Bodies.getValues();
|
||||
for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++)
|
||||
doc->setShow((*b)->getNameInDocument());
|
||||
}
|
||||
|
||||
// roll back the done things
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *Revol
|
|||
ui->checkBoxReversed->setChecked(reversed);
|
||||
ui->revolveAngle->bind(pcRevolution->Angle);
|
||||
|
||||
ui->doubleSpinBox->blockSignals(false);
|
||||
ui->revolveAngle->blockSignals(false);
|
||||
ui->axis->blockSignals(false);
|
||||
ui->checkBoxMidplane->blockSignals(false);
|
||||
ui->checkBoxReversed->blockSignals(false);
|
||||
|
|
Loading…
Reference in New Issue
Block a user