Changed tree ordering of booleans and bodies

This commit is contained in:
jrheinlaender 2013-05-24 08:23:04 +04:30 committed by Stefan Tröger
parent 106efeec02
commit 026242231e
8 changed files with 104 additions and 45 deletions

View File

@ -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()) ||

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);