PartDesign workflow without part/body
PartDesign: make datum features work outside of body/part PartDesign old workflow: remove a few messageboxes about no part PartDesign: old workflow: multitransform without body Still has visibility issues, but generally works.
This commit is contained in:
parent
c3da141020
commit
16e4ce20f0
|
@ -110,29 +110,6 @@ App::DocumentObjectExecReturn *Pad::execute(void)
|
|||
base = TopoDS_Shape();
|
||||
}
|
||||
|
||||
/*
|
||||
// Find Body feature which owns this Pad and get the shape of the feature preceding this one for fusing
|
||||
// This method was rejected in favour of the BaseFeature property because that makes the feature atomic (independent of the
|
||||
// Body object). See
|
||||
// https://sourceforge.net/apps/phpbb/free-cad/viewtopic.php?f=19&t=3831
|
||||
// https://sourceforge.net/apps/phpbb/free-cad/viewtopic.php?f=19&t=3855
|
||||
PartDesign::Body* body = getBody();
|
||||
if (body == NULL) {
|
||||
return new App::DocumentObjectExecReturn(
|
||||
"In order to use PartDesign you need an active Body object in the document. "
|
||||
"Please make one active or create one. If you have a legacy document "
|
||||
"with PartDesign objects without Body, use the transfer function in "
|
||||
"PartDesign to put them into a Body."
|
||||
);
|
||||
}
|
||||
const Part::TopoShape& prevShape = body->getPreviousSolid(this);
|
||||
TopoDS_Shape support;
|
||||
if (prevShape.isNull())
|
||||
// ignore, because support isn't mandatory
|
||||
support = TopoDS_Shape();
|
||||
else
|
||||
support = prevShape._Shape;
|
||||
*/
|
||||
|
||||
// get the Sketch plane
|
||||
Base::Placement SketchPos = sketch->Placement.getValue();
|
||||
|
|
|
@ -522,9 +522,7 @@ void UnifiedDatumCommand(Gui::Command &cmd, Base::Type type, std::string name)
|
|||
cmd.openCommand(tmp.c_str());
|
||||
cmd.doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')",support.getValue()->getNameInDocument());
|
||||
} else {
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true);
|
||||
if (pcActiveBody == 0)
|
||||
return;
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false);
|
||||
|
||||
std::string FeatName = cmd.getUniqueObjectName(name.c_str());
|
||||
|
||||
|
@ -547,8 +545,10 @@ void UnifiedDatumCommand(Gui::Command &cmd, Base::Type type, std::string name)
|
|||
QMessageBox::information(Gui::getMainWindow(),QObject::tr("Invalid selection"), QObject::tr("There are no attachment modes that fit seleted objects. Select something else."));
|
||||
}
|
||||
}
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
if (pcActiveBody) {
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
}
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().recompute()"); // recompute the feature based on its references
|
||||
cmd.doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
|
||||
}
|
||||
|
@ -667,7 +667,11 @@ void CmdPartDesignNewSketch::activated(int iMsg)
|
|||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true);
|
||||
|
||||
// No PartDesign feature without Body past FreeCAD 0.13
|
||||
if(!pcActiveBody) return;
|
||||
if(!pcActiveBody) {
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
rcCmdMgr.runCommandByName("Sketcher_NewSketch");
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::SelectionFilter SketchFilter("SELECT Sketcher::SketchObject COUNT 1");
|
||||
Gui::SelectionFilter FaceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1");
|
||||
|
@ -893,10 +897,9 @@ bool CmdPartDesignNewSketch::isActive(void)
|
|||
void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const bool hidePrevSolid = true)
|
||||
{
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false);
|
||||
if (pcActiveBody == 0)
|
||||
throw Base::Exception("No active body!");
|
||||
|
||||
cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
if (pcActiveBody)
|
||||
cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
|
||||
if (pcActiveBody != NULL) {
|
||||
|
@ -939,8 +942,8 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b
|
|||
for (std::vector<App::DocumentObject*>::iterator s = sketches.begin(); s != sketches.end(); s++) {
|
||||
|
||||
// Check whether this plane belongs to the active body
|
||||
if (!pcActiveBody->hasFeature(*s)) {
|
||||
if(pcActivePart->hasObject(*s, true))
|
||||
if (pcActiveBody && !pcActiveBody->hasFeature(*s)) {
|
||||
if(pcActivePart && pcActivePart->hasObject(*s, true))
|
||||
status.push_back(PartDesignGui::TaskFeaturePick::otherBody);
|
||||
else
|
||||
status.push_back(PartDesignGui::TaskFeaturePick::otherPart);
|
||||
|
@ -968,7 +971,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b
|
|||
continue;
|
||||
}
|
||||
|
||||
if (pcActiveBody->isAfterTip(*s)){
|
||||
if (pcActiveBody && pcActiveBody->isAfterTip(*s)){
|
||||
status.push_back(PartDesignGui::TaskFeaturePick::afterTip);
|
||||
continue;
|
||||
}
|
||||
|
@ -1005,9 +1008,6 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b
|
|||
void prepareSketchBased(Gui::Command* cmd, const std::string& which,
|
||||
boost::function<void (Part::Part2DObject*, std::string)> func)
|
||||
{
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true);
|
||||
if (!pcActiveBody) return;
|
||||
|
||||
bool bNoSketchWasSelected = false;
|
||||
// Get a valid sketch from the user
|
||||
// First check selections
|
||||
|
@ -1050,8 +1050,6 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which,
|
|||
which.c_str(), FeatName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s",
|
||||
FeatName.c_str(), sketch->getNameInDocument());
|
||||
//Gui::Command::doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
|
||||
// pcActiveBody->getNameInDocument(), FeatName.c_str());
|
||||
|
||||
func(sketch, FeatName);
|
||||
};
|
||||
|
@ -2061,8 +2059,8 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform()
|
|||
|
||||
void CmdPartDesignMultiTransform::activated(int iMsg)
|
||||
{
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true);
|
||||
if (!pcActiveBody) return;
|
||||
PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false);
|
||||
//if (!pcActiveBody) return;
|
||||
|
||||
std::vector<App::DocumentObject*> features;
|
||||
|
||||
|
@ -2082,8 +2080,12 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
|
|||
PartDesign::Transformed* trFeat = static_cast<PartDesign::Transformed*>(features.front());
|
||||
|
||||
// Move the insert point back one feature
|
||||
App::DocumentObject* oldTip = pcActiveBody->Tip.getValue();
|
||||
App::DocumentObject* prevFeature = pcActiveBody->getPrevFeature(trFeat);
|
||||
App::DocumentObject* oldTip = 0;
|
||||
App::DocumentObject* prevFeature = 0;
|
||||
if (pcActiveBody){
|
||||
oldTip = pcActiveBody->Tip.getValue();
|
||||
prevFeature = pcActiveBody->getPrevFeature(trFeat);
|
||||
}
|
||||
Gui::Selection().clearSelection();
|
||||
if (prevFeature != NULL)
|
||||
Gui::Selection().addSelection(prevFeature->getDocument()->getName(), prevFeature->getNameInDocument());
|
||||
|
@ -2091,8 +2093,9 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
|
|||
doCommand(Gui, "FreeCADGui.runCommand('PartDesign_MoveTip')");
|
||||
|
||||
// Remove the Transformed feature from the Body
|
||||
doCommand(Doc, "App.activeDocument().%s.removeFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), trFeat->getNameInDocument());
|
||||
if(pcActiveBody)
|
||||
doCommand(Doc, "App.activeDocument().%s.removeFeature(App.activeDocument().%s)",
|
||||
pcActiveBody->getNameInDocument(), trFeat->getNameInDocument());
|
||||
|
||||
// Create a MultiTransform feature and move the Transformed feature inside it
|
||||
std::string FeatName = getUniqueObjectName("MultiTransform");
|
||||
|
@ -2105,7 +2108,7 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
|
|||
finishFeature(this, FeatName);
|
||||
|
||||
// Restore the insert point
|
||||
if (oldTip != trFeat) {
|
||||
if (pcActiveBody && oldTip != trFeat) {
|
||||
Gui::Selection().clearSelection();
|
||||
Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
|
||||
|
@ -2120,7 +2123,9 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
|
|||
return;
|
||||
|
||||
// Make sure the user isn't presented with an empty screen because no transformations are defined yet...
|
||||
App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true);
|
||||
App::DocumentObject* prevSolid = 0;
|
||||
if (pcActiveBody)
|
||||
pcActiveBody->getPrevSolidFeature(NULL, true);
|
||||
if (prevSolid != NULL) {
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(prevSolid);
|
||||
doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape",
|
||||
|
|
|
@ -94,15 +94,28 @@ const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChan
|
|||
|
||||
void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar) {
|
||||
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
|
||||
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
|
||||
App::DocumentObject* prevSolid = activeBody->getPrevSolidFeature(vp->getObject(), false);
|
||||
App::DocumentObject* curSolid = activeBody->getPrevSolidFeature();
|
||||
|
||||
PartDesign::SketchBased* pcSketchBased = static_cast<PartDesign::SketchBased*>(vp->getObject());
|
||||
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
|
||||
|
||||
App::DocumentObject* curSolid = 0;//the last solid of the body, the one that is likely visible, but can't be used for up-to-face
|
||||
if (activeBody)
|
||||
curSolid = activeBody->getPrevSolidFeature();
|
||||
else
|
||||
curSolid = pcSketchBased;
|
||||
|
||||
App::DocumentObject* prevSolid = 0;//the solid this feature will be fused to
|
||||
try {
|
||||
prevSolid = pcSketchBased->getBaseObject();
|
||||
} catch (Base::Exception) {
|
||||
//this feature is a starting feature
|
||||
}
|
||||
|
||||
if (pressed) {
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc) {
|
||||
if (curSolid)
|
||||
doc->setHide(curSolid->getNameInDocument());
|
||||
doc->setHide(curSolid->getNameInDocument());
|
||||
if (prevSolid)
|
||||
doc->setShow(prevSolid->getNameInDocument());
|
||||
}
|
||||
|
@ -114,7 +127,7 @@ void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool
|
|||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
if (doc) {
|
||||
if (curSolid)
|
||||
doc->setShow(curSolid->getNameInDocument());
|
||||
doc->setShow(curSolid->getNameInDocument());
|
||||
if (prevSolid)
|
||||
doc->setHide(prevSolid->getNameInDocument());
|
||||
}
|
||||
|
@ -200,7 +213,7 @@ App::DocumentObject* TaskSketchBasedParameters::getPartPlanes(const char* str) c
|
|||
|
||||
//TODO: Adjust to GRAPH handling when available
|
||||
App::DocumentObject* obj = vp->getObject();
|
||||
App::Part* part = getPartFor(obj, true);
|
||||
App::Part* part = getPartFor(obj, false);
|
||||
if(!part)
|
||||
return nullptr;
|
||||
|
||||
|
@ -224,11 +237,15 @@ App::DocumentObject* TaskSketchBasedParameters::getPartLines(const char* str) co
|
|||
|
||||
//TODO: Adjust to GRAPH handling when available
|
||||
App::DocumentObject* obj = vp->getObject();
|
||||
App::Part* part = getPartFor(obj, true);
|
||||
if(!part)
|
||||
return nullptr;
|
||||
App::Part* part = getPartFor(obj, false);
|
||||
|
||||
std::vector<App::DocumentObject*> origs = part->getObjectsOfType(App::Origin::getClassTypeId());
|
||||
|
||||
std::vector<App::DocumentObject*> origs;
|
||||
if(part)
|
||||
origs = part->getObjectsOfType(App::Origin::getClassTypeId());
|
||||
else
|
||||
origs = vp->getObject()->getDocument()->getObjectsOfType(App::Origin::getClassTypeId());
|
||||
|
||||
if(origs.size()<1)
|
||||
return nullptr;
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ App::DocumentObject* TaskTransformedParameters::getPartPlanes(const char* str) c
|
|||
|
||||
//TODO: Adjust to GRAPH handling when available
|
||||
App::DocumentObject* obj = getObject();
|
||||
App::Part* part = getPartFor(obj, true);
|
||||
App::Part* part = getPartFor(obj, false);
|
||||
|
||||
if (part) {
|
||||
std::vector<App::DocumentObject*> origs = part->getObjectsOfType(App::Origin::getClassTypeId());
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "ViewProviderDatum.h"
|
||||
#include "TaskDatumParameters.h"
|
||||
#include "Workbench.h"
|
||||
#include <App/Part.h>
|
||||
#include <Mod/PartDesign/App/DatumPoint.h>
|
||||
#include <Mod/PartDesign/App/DatumLine.h>
|
||||
#include <Mod/PartDesign/App/DatumPlane.h>
|
||||
|
@ -314,3 +315,39 @@ void ViewProviderDatum::unsetEdit(int ModNum)
|
|||
}
|
||||
}
|
||||
|
||||
Base::BoundBox3d ViewProviderDatum::getRelevantExtents()
|
||||
{
|
||||
Base::BoundBox3d bbox;
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
|
||||
if (body != NULL)
|
||||
bbox = body->getBoundBox();
|
||||
else {
|
||||
App::Part* part = getPartFor(this->getObject(),false);
|
||||
std::vector<App::DocumentObject*> objs;
|
||||
|
||||
if(part)
|
||||
objs = part->getObjectsOfType(Part::Feature::getClassTypeId());
|
||||
else
|
||||
objs = this->getObject()->getDocument()->getObjectsOfType(Part::Feature::getClassTypeId());
|
||||
|
||||
for(App::DocumentObject* obj: objs){
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(feat);
|
||||
if (vp->isVisible()){
|
||||
Base::BoundBox3d bbf = feat->Shape.getBoundingBox();
|
||||
if (bbf.CalcDiagonalLength() < Precision::Infinite())
|
||||
bbox.Add(bbf);
|
||||
}
|
||||
|
||||
}
|
||||
if (bbox.CalcDiagonalLength() < Precision::Confusion()){
|
||||
bbox.Add(Base::Vector3d(-10.0,-10.0,-10.0));
|
||||
bbox.Add(Base::Vector3d(10.0,10.0,10.0));
|
||||
}
|
||||
|
||||
}
|
||||
bbox.Enlarge(0.1 * bbox.CalcDiagonalLength());
|
||||
return bbox;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define PARTGUI_ViewProviderDatum_H
|
||||
|
||||
#include "Gui/ViewProviderGeometryObject.h"
|
||||
#include <Base/BoundBox.h>
|
||||
|
||||
namespace PartDesignGui {
|
||||
|
||||
|
@ -64,6 +65,19 @@ protected:
|
|||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
|
||||
|
||||
//
|
||||
/**
|
||||
* @brief getRelevantExtents computes the bounding box of the objects
|
||||
* relevant to the datum feature, which is intended to be used for
|
||||
* determinimg the size of the rendered piece of the datum.
|
||||
* @return Bounding box of body, if the datum is in a body. Bounding box of
|
||||
* all visible shapes of a part, if in a part but not in a body. Bounding
|
||||
* box of all visible Part::Feature-derived objects if just in a document.
|
||||
* This behavior is subject to change.
|
||||
*/
|
||||
virtual Base::BoundBox3d getRelevantExtents();
|
||||
|
||||
protected:
|
||||
SoSeparator* pShapeSep;
|
||||
std::string oldWb;
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include <Gui/Control.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Mod/PartDesign/App/Body.h>
|
||||
|
||||
using namespace PartDesignGui;
|
||||
|
||||
|
@ -80,12 +79,9 @@ void ViewProviderDatumLine::updateData(const App::Property* prop)
|
|||
Base::Vector3d dir(0,0,1);
|
||||
|
||||
// Get limits of the line from bounding box of the body
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
|
||||
if (body == NULL)
|
||||
return;
|
||||
Base::BoundBox3d bbox = body->getBoundBox();
|
||||
Base::BoundBox3d bbox = this->getRelevantExtents();
|
||||
|
||||
bbox = bbox.Transformed(plm.toMatrix());
|
||||
bbox.Enlarge(0.1 * bbox.CalcDiagonalLength());
|
||||
Base::Vector3d p1, p2;
|
||||
if (bbox.IsInBox(base)) {
|
||||
bbox.IntersectionPoint(base, dir, p1, Precision::Confusion());
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include <Gui/Control.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Mod/PartDesign/App/Body.h>
|
||||
|
||||
using namespace PartDesignGui;
|
||||
|
||||
|
@ -81,10 +80,7 @@ void ViewProviderDatumPlane::updateData(const App::Property* prop)
|
|||
Base::Vector3d normal(0,0,1);
|
||||
|
||||
// Get limits of the plane from bounding box of the body
|
||||
PartDesign::Body* body = static_cast<PartDesign::Body*>(Part::BodyBase::findBodyOf(this->getObject()));
|
||||
if (body == NULL)
|
||||
return;
|
||||
Base::BoundBox3d bbox = body->getBoundBox();
|
||||
Base::BoundBox3d bbox = this->getRelevantExtents();
|
||||
bbox = bbox.Transformed(plm.toMatrix());
|
||||
double dlength = bbox.CalcDiagonalLength();
|
||||
if (dlength < Precision::Confusion())
|
||||
|
|
Loading…
Reference in New Issue
Block a user