PartDesign: add Origin to the Body and unstrap the module from the Parts

This commit is contained in:
Alexander Golubev 2015-09-05 05:49:33 +03:00 committed by Stefan Tröger
parent 15e998e07c
commit 1a26f7551f
27 changed files with 378 additions and 264 deletions

View File

@ -22,39 +22,39 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <boost/bind.hpp>
#endif
#include <Base/Console.h>
#include <Base/Placement.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Origin.h>
#include <Mod/Part/App/DatumFeature.h>
#include <Mod/Part/App/PartFeature.h>
#include "Feature.h"
#include "Body.h"
#include "BodyPy.h"
#include "FeatureSketchBased.h"
#include "FeatureTransformed.h"
#include "DatumPoint.h"
#include "DatumLine.h"
#include "DatumPlane.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Base/Console.h>
#include <Mod/Part/App/DatumFeature.h>
#include <Mod/Part/App/PartFeature.h>
#include <boost/bind.hpp>
#include "Body.h"
#include "BodyPy.h"
using namespace PartDesign;
namespace PartDesign {
PROPERTY_SOURCE(PartDesign::Body, Part::BodyBase)
Body::Body()
{
Placement.StatusBits.set(3, true);
//ADD_PROPERTY(IsActive,(0));
Body::Body() {
ADD_PROPERTY_TYPE (Origin, (0), 0, App::Prop_Hidden, "Origin linked to the body" );
}
/*
@ -446,15 +446,6 @@ Base::BoundBox3d Body::getBoundBox()
return result;
}
PyObject *Body::getPyObject(void)
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new BodyPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
void Body::onSettingDocument() {
if(connection.connected())
@ -479,11 +470,58 @@ void Body::onChanged (const App::Property* prop) {
assert ( nextSolid->isDerivedFrom ( PartDesign::Feature::getClassTypeId () ) );
static_cast<PartDesign::Feature*>(nextSolid)->BaseFeature.setValue( baseFeature );
}
}
Part::BodyBase::onChanged ( prop );
}
App::Origin *Body::getOrigin () const {
App::DocumentObject *originObj = Origin.getValue ();
} /* PartDesign */
if ( !originObj ) {
std::stringstream err;
err << "Can't find Origin for \"" << getNameInDocument () << "\"";
throw Base::Exception ( err.str().c_str () );
} else if (! originObj->isDerivedFrom ( App::Origin::getClassTypeId() ) ) {
std::stringstream err;
err << "Bad object \"" << originObj->getNameInDocument () << "\"(" << originObj->getTypeId().getName()
<< ") linked to the Origin of \"" << getNameInDocument () << "\"";
throw Base::Exception ( err.str().c_str () );
} else {
return static_cast<App::Origin *> ( originObj );
}
}
void Body::setupObject () {
// NOTE: the code shared with App::OriginGroup
App::Document *doc = getDocument ();
std::string objName = std::string ( getNameInDocument() ).append ( "Origin" );
App::DocumentObject *originObj = doc->addObject ( "App::Origin", objName.c_str () );
assert ( originObj && originObj->isDerivedFrom ( App::Origin::getClassTypeId () ) );
Origin.setValue ( originObj );
Part::BodyBase::setupObject ();
}
void Body::unsetupObject () {
App::DocumentObject *origin = Origin.getValue ();
if (origin && !origin->isDeleting ()) {
origin->getDocument ()->remObject (origin->getNameInDocument());
}
Part::BodyBase::unsetupObject ();
}
PyObject *Body::getPyObject(void)
{
if (PythonObject.is(Py::_None())){
// ref counter is set to 1
PythonObject = Py::Object(new BodyPy(this),true);
}
return Py::new_reference_to(PythonObject);
}

View File

@ -29,6 +29,10 @@
#include <boost/signals.hpp>
namespace App {
class Origin;
}
namespace PartDesign
{
@ -50,6 +54,7 @@ public:
/// recalculate the feature
App::DocumentObjectExecReturn *execute(void);
short mustExecute() const;
/// returns the type name of the view provider
const char* getViewProviderName(void) const {
return "PartDesignGui::ViewProviderBody";
@ -59,9 +64,6 @@ public:
/// Return the previous feature
App::DocumentObject* getPrevFeature(App::DocumentObject *start = NULL) const;
// Return the shape of the feature preceding this feature
//const Part::TopoShape getPreviousSolid(const PartDesign::Feature* f);
/**
* Add the feature into the body at the current insert point.
* The insertion poin is the before next solid after the Tip feature
@ -84,6 +86,9 @@ public:
/// Remove the feature from the body
void removeFeature(App::DocumentObject* feature);
/// Delets all the objects linked to the model.
void removeModelFromDocument();
/**
* Checks if the given document object lays after the current insert point
* (place before next solid after the Tip)
@ -112,14 +117,17 @@ public:
*/
static Body *findBodyOf(const App::DocumentObject* feature);
/// Delets all the objects linked to the model.
void removeModelFromDocument();
/// Return the bounding box of the Tip Shape, taking into account datum features
Base::BoundBox3d getBoundBox();
/// Returns the origin link or throws an exception
App::Origin *getOrigin () const;
PyObject *getPyObject(void);
/// Origin linked to the property, please use getOrigin () to access it
App::PropertyLink Origin;
protected:
virtual void onSettingDocument();
@ -138,8 +146,12 @@ protected:
*/
App::DocumentObject *getNextSolidFeature(App::DocumentObject* start = NULL);
/// Creates the corresponding Origin object
virtual void setupObject ();
/// Removes all planes and axis if they are still linked to the document
virtual void unsetupObject ();
private:
App::DocumentObject* rememberTip;
boost::signals::scoped_connection connection;
};

View File

@ -24,12 +24,11 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
// TODO Cleanup headers (2015-09-04, Fat-Zer)
#include "DatumCS.h"
#include "DatumPoint.h"
#include "DatumPlane.h"
#include "DatumLine.h"
#include <App/Part.h>
#include <Base/Exception.h>
#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>

View File

@ -60,9 +60,8 @@
# include <Standard_Version.hxx>
#endif
// TODO Cleanup Headers (2015-09-04, Fat-Zer)
#include <QObject>
#include <App/OriginFeature.h>
#include <App/Part.h>
#include "DatumPoint.h"
#include "DatumLine.h"
#include "DatumPlane.h"

View File

@ -57,9 +57,8 @@
# include <BRepAdaptor_Surface.hxx>
# include <Standard_Version.hxx>
#endif
// TODO Cleanup headers (2015-09-04, Fat-Zer)
#include <QObject>
#include <App/Part.h>
#include "DatumPoint.h"
#include "DatumLine.h"
#include "DatumPlane.h"

View File

@ -57,9 +57,8 @@
# include <BRepAdaptor_Surface.hxx>
# include <Standard_Version.hxx>
#endif
// TODO Cleanup headers (2015-09-04, Fat-Zer)
#include <QObject>
#include <App/Part.h>
#include "DatumPoint.h"
#include "DatumLine.h"
#include "DatumPlane.h"

View File

@ -33,7 +33,7 @@
# include <BRepBuilderAPI_MakeFace.hxx>
#endif
// TODO Cleanup headers (2015-09-04, Fat-Zer)
#include <Base/Exception.h>
#include "App/Document.h"
#include "App/OriginFeature.h"

View File

@ -41,7 +41,6 @@
#include <Base/Console.h>
#include <Base/Exception.h>
#include <App/Document.h>
#include <App/Part.h>
using namespace PartDesign;
@ -90,19 +89,6 @@ App::DocumentObjectExecReturn *Boolean::execute(void)
if(!baseBody)
return new App::DocumentObjectExecReturn("Cannot do boolean on feature which is not in a body");
// TODO: share the code snippet with PartDesignGui::getPartFor()
//get the part every body should belong to
App::Part* part = NULL;
for(App::Part* p : this->getDocument()->getObjectsOfType<App::Part>()) {
if(p->hasObject(baseBody)) {
part = p;
break;
}
}
if(!part)
return new App::DocumentObjectExecReturn("Cannot do boolean on body which is not in a part");
// TODO: Why is Feature::getLocation() protected?
Base::Placement place = baseBody->Placement.getValue();
Base::Rotation rot(place.getRotation());
@ -125,8 +111,6 @@ App::DocumentObjectExecReturn *Boolean::execute(void)
// Extract the body shape. Its important to get the actual feature that provides the last solid in the body
// so that the placement will be right
PartDesign::Body* body = static_cast<PartDesign::Body*>(*b);
if(!part->hasObject(body))
return new App::DocumentObjectExecReturn("Cannot do boolean on bodies of different parts");
TopoDS_Shape shape = body->Shape.getValue();

View File

@ -71,7 +71,6 @@
#include <Base/Parameter.h>
#include <App/Application.h>
#include <App/OriginFeature.h>
#include <App/Part.h>
#include <Mod/Part/App/modelRefine.h>
#include "FeatureSketchBased.h"
#include "DatumPlane.h"

View File

@ -339,21 +339,21 @@ void CmdPartDesignNewSketch::activated(int iMsg)
// Get a valid plane from the user
unsigned validPlanes = 0;
App::Part* pcActivePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>(PARTKEY);
App::GeoFeatureGroup* geoGroup = App::GeoFeatureGroup::getGroupOfObject ( pcActiveBody );
std::vector<App::DocumentObject*> planes;
std::vector<PartDesignGui::TaskFeaturePick::featureStatus> status;
// Baseplanes are preaprooved
if ( pcActivePart ) {
if ( pcActiveBody ) {
try {
for ( auto plane: pcActivePart->getOrigin ()->planes() ) {
for ( auto plane: pcActiveBody->getOrigin ()->planes() ) {
planes.push_back (plane);
status.push_back(PartDesignGui::TaskFeaturePick::basePlane);
validPlanes++;
}
} catch (const Base::Exception &ex) {
Base::Console().Error ("%s\n", ex.what() );
Base::Console().Error ("%s\n", ex.what() );
}
}
@ -363,24 +363,34 @@ void CmdPartDesignNewSketch::activated(int iMsg)
for (auto plane: datumPlanes) {
planes.push_back ( plane );
// Check whether this plane belongs to the active body
if (!pcActiveBody->hasFeature(plane)) {
if ( pcActivePart && pcActivePart->hasObject ( plane, true ) ) {
status.push_back(PartDesignGui::TaskFeaturePick::otherBody);
if ( pcActiveBody && pcActiveBody->hasFeature(plane) ) {
if ( !pcActiveBody->isAfterInsertPoint ( plane ) ) {
validPlanes++;
status.push_back(PartDesignGui::TaskFeaturePick::validFeature);
} else {
status.push_back(PartDesignGui::TaskFeaturePick::otherPart);
}
continue;
} else {
if (pcActiveBody->isAfterInsertPoint ( plane ) ) {
status.push_back(PartDesignGui::TaskFeaturePick::afterTip);
continue;
}
} else {
PartDesign::Body *planeBody = PartDesign::Body::findBodyOf (plane);
if ( planeBody ) {
if ( ( geoGroup && geoGroup->hasObject ( planeBody, true ) ) ||
!App::GeoFeatureGroup::getGroupOfObject (planeBody) ) {
status.push_back ( PartDesignGui::TaskFeaturePick::otherBody );
} else {
status.push_back ( PartDesignGui::TaskFeaturePick::otherPart );
}
} else {
if ( ( geoGroup && geoGroup->hasObject ( plane, true ) ) ||
!App::GeoFeatureGroup::getGroupOfObject ( plane ) ) {
status.push_back ( PartDesignGui::TaskFeaturePick::otherPart );
} else if (pcActiveBody) {
status.push_back ( PartDesignGui::TaskFeaturePick::notInBody );
} else { // if we are outside a body count it as valid
validPlanes++;
status.push_back(PartDesignGui::TaskFeaturePick::validFeature);
}
}
}
// All checks passed - found a valid plane
validPlanes++;
status.push_back(PartDesignGui::TaskFeaturePick::validFeature);
}
if (validPlanes == 0) {
@ -510,6 +520,7 @@ const unsigned validateSketches(std::vector<App::DocumentObject*>& sketches,
std::vector<PartDesignGui::TaskFeaturePick::featureStatus>& status,
std::vector<App::DocumentObject*>::iterator& firstValidSketch)
{
// TODO Review the function for non-part bodies (2015-09-04, Fat-Zer)
PartDesign::Body* pcActiveBody = PartDesignGui::getBody(false);
App::Part* pcActivePart = PartDesignGui::getPartFor(pcActiveBody, false);
@ -1599,6 +1610,7 @@ void CmdPartDesignMultiTransform::activated(int iMsg)
Gui::Selection().clearSelection();
if (prevFeature != NULL)
Gui::Selection().addSelection(prevFeature->getDocument()->getName(), prevFeature->getNameInDocument());
// TODO Review this (2015-09-05, Fat-Zer)
openCommand("Convert to MultiTransform feature");
doCommand(Gui, "FreeCADGui.runCommand('PartDesign_MoveTip')");

View File

@ -157,30 +157,30 @@ void CmdPartDesignBody::activated(int iMsg)
}
// first check if Part is already created:
App::Part *actPart = PartDesignGui::assertActivePart ();
if (!actPart) {
return;
}
std::string PartName = actPart->getNameInDocument();
App::Part *actPart = PartDesignGui::getActivePart ();
openCommand("Add a Body");
std::string FeatName = getUniqueObjectName("Body");
std::string bodyName = getUniqueObjectName("Body");
// add the Body feature itself, and make it active
doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", FeatName.c_str());
doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", bodyName.c_str());
if (baseFeature) {
doCommand(Doc,"App.activeDocument().%s.BaseFeature = App.activeDocument().%s",
FeatName.c_str(), baseFeature->getNameInDocument());
bodyName.c_str(), baseFeature->getNameInDocument());
}
addModule(Gui,"PartDesignGui"); // import the Gui module only once a session
doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, FeatName.c_str());
doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)",
PDBODYKEY, bodyName.c_str());
// Make the "Create sketch" prompt appear in the task panel
doCommand(Gui,"Gui.Selection.clearSelection()");
doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)",PartName.c_str(),FeatName.c_str());
doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", bodyName.c_str());
if (actPart) {
doCommand(Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)",
actPart->getNameInDocument(), bodyName.c_str());
}
updateActive();
}
@ -307,6 +307,7 @@ void CmdPartDesignMigrate::activated(int iMsg)
// TODO Align visability (2015-08-17, Fat-Zer)
} /* for */
// TODO make it work without parts (2015-09-04, Fat-Zer)
// add a part if there is no active yet
App::Part *actPart = PartDesignGui::assertActivePart ();

View File

@ -31,6 +31,8 @@
#endif
#include <App/OriginFeature.h>
#include <App/GeoFeatureGroup.h>
#include <App/Origin.h>
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
@ -41,6 +43,9 @@
#include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include "Utils.h"
#include "ReferenceSelection.h"
using namespace PartDesignGui;
@ -50,26 +55,62 @@ using namespace Gui;
bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName)
{
PartDesign::Body* ActivePartObject = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
App::Part* activePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>("Part");
// TODO review this function (2015-09-04, Fat-Zer)
PartDesign::Body *body;
App::GeoFeatureGroup *geoGroup;
if ( support ) {
body = PartDesign::Body::findBodyOf (support);
} else {
body = PartDesignGui::getBody (false);
}
if ( body ) { // Search for Part of the body
geoGroup = App::GeoFeatureGroup::getGroupOfObject ( body ) ;
} else if ( support ) { // if no body search part for support
geoGroup = App::GeoFeatureGroup::getGroupOfObject ( support ) ;
} else { // fallback to active part
geoGroup = PartDesignGui::getActivePart ( );
}
// Don't allow selection in other document
if ((support != NULL) && (pDoc != support->getDocument()))
if ( support && pDoc != support->getDocument() ) {
return false;
}
if (plane && (pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())))
// Note: It is assumed that a Part has exactly 3 App::Plane objects at the root of the feature tree
return true;
// Enable selection from origin of current part/
if ( pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()) ) {
bool fits = false;
if ( plane && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) {
fits = true;
} else if ( edge && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) {
fits = true;
}
if (edge && (pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId())))
return true;
if (fits) { // check that it is actually belongs to the choosen body or part
try { // here are some throwers
if (body) {
if (body->getOrigin ()->hasObject (pObj) ) {
return true;
}
} else if (geoGroup && geoGroup->isDerivedFrom ( App::OriginGroup::getClassTypeId () ) ) {
if ( static_cast<App::OriginGroup *>(geoGroup)->getOrigin ()->hasObject (pObj) ) {
return true;
}
}
} catch (const Base::Exception)
{ }
}
return false; // The Plane/Axis doesn't fits our needs
}
if (pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
// Allow selecting Part::Datum features from the active Body
if (ActivePartObject == NULL)
if (!body) { // Allow selecting Part::Datum features from the active Body
return false;
if (!allowOtherBody && !ActivePartObject->hasFeature(pObj))
} else if (!allowOtherBody && !body->hasFeature(pObj)) {
return false;
}
if (plane && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())))
return true;

View File

@ -29,6 +29,7 @@ namespace PartDesignGui {
class ReferenceSelection : public Gui::SelectionFilterGate
{
// TODO Replace this set of bools with bitwice enum (2015-09-04, Fat-Zer)
const App::DocumentObject* support;
// If set to true, allow picking edges or planes or both
bool edge, plane;

View File

@ -36,7 +36,6 @@
#include <App/Document.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
@ -211,10 +210,10 @@ TaskDatumParameters::TaskDatumParameters(ViewProviderDatum *DatumView,QWidget *p
updateListOfModes(eMapMode(pcDatum->MapMode.getValue()));
//temporary show coordinate systems for selection
App::Part* part = getPartFor(DatumView->getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( DatumView->getObject() );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->setTemporaryVisibility(true, true);
@ -771,10 +770,10 @@ bool TaskDatumParameters::getFlip() const
TaskDatumParameters::~TaskDatumParameters()
{
//end temporary view mode of coordinate system
App::Part* part = getPartFor(DatumView->getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( DatumView->getObject() );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();

View File

@ -48,6 +48,7 @@
using namespace PartDesignGui;
// TODO Do ve should snap here to App:Part or GeoFeatureGroup/DocumentObjectGroup ? (2015-09-04, Fat-Zer)
const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st)
{
switch (st) {

View File

@ -32,7 +32,6 @@
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>
@ -47,6 +46,7 @@
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ReferenceSelection.h"
@ -165,10 +165,10 @@ void TaskLinearPatternParameters::setupUI()
updateUI();
//show the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf(getObject());
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->setTemporaryVisibility(true, false);
@ -357,10 +357,10 @@ const unsigned TaskLinearPatternParameters::getOccurrences(void) const
TaskLinearPatternParameters::~TaskLinearPatternParameters()
{
//hide the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( getObject() );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();

View File

@ -30,7 +30,6 @@
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>
@ -43,6 +42,7 @@
#include <Gui/ViewProviderOrigin.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ReferenceSelection.h"
@ -140,10 +140,10 @@ void TaskMirroredParameters::setupUI()
updateUI();
//show the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( getObject() );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->setTemporaryVisibility(true, false);
@ -267,10 +267,10 @@ void TaskMirroredParameters::apply()
TaskMirroredParameters::~TaskMirroredParameters()
{
//hide the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( getObject() );
if ( body ) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();

View File

@ -31,7 +31,6 @@
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>
@ -46,6 +45,7 @@
#include <Mod/PartDesign/App/FeaturePolarPattern.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/Body.h>
#include "ReferenceSelection.h"
#include "TaskMultiTransformParameters.h"
@ -150,19 +150,20 @@ void TaskPolarPatternParameters::setupUI()
ui->checkReverse->setEnabled(true);
ui->polarAngle->setEnabled(true);
ui->spinOccurrences->setEnabled(true);
App::DocumentObject* sketch = getSketchObject();
if (!(sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId())))
sketch = 0;
this->axesLinks.setCombo(*(ui->comboAxis));
this->fillAxisCombo(axesLinks, static_cast<Part::Part2DObject*>(sketch));
updateUI();
//show the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( getObject() );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->setTemporaryVisibility(true, false);
@ -327,7 +328,7 @@ void TaskPolarPatternParameters::onFeatureDeleted(void)
}
void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector<std::string>& sub) const
{
{
const App::PropertyLinkSub &lnk = axesLinks.getCurrentLink();
obj = lnk.getValue();
sub = lnk.getSubValues();
@ -352,10 +353,10 @@ const unsigned TaskPolarPatternParameters::getOccurrences(void) const
TaskPolarPatternParameters::~TaskPolarPatternParameters()
{
//hide the parts coordinate system axis for selection
App::Part* part = getPartFor(getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( getObject() );
if ( body ) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility ();
@ -363,7 +364,7 @@ TaskPolarPatternParameters::~TaskPolarPatternParameters()
Base::Console().Error ("%s\n", ex.what () );
}
}
delete ui;
if (proxy)
delete proxy;

View File

@ -30,7 +30,6 @@
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>
@ -129,19 +128,19 @@ TaskRevolutionParameters::TaskRevolutionParameters(PartDesignGui::ViewProvider*
ui->checkBoxReversed->blockSignals(false);
setFocus ();
//show the parts coordinate system axis for selection
App::Part* part = getPartFor(vp->getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( vp->getObject () );
if(body) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->setTemporaryVisibility(true, false);
} catch (const Base::Exception &ex) {
Base::Console().Error ("%s\n", ex.what () );
}
}
}
}
void TaskRevolutionParameters::fillAxisCombo(bool forceRefill)
@ -177,11 +176,11 @@ void TaskRevolutionParameters::fillAxisCombo(bool forceRefill)
//add part axes
App::DocumentObject* obj = vp->getObject();
App::Part* part = getPartFor(obj, false);
if (part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( obj );
if (body) {
try {
App::Origin* orig = part->getOrigin();
App::Origin* orig = body->getOrigin();
addAxisToCombo(orig->getX(),"",tr("Base X axis"));
addAxisToCombo(orig->getY(),"",tr("Base Y axis"));
addAxisToCombo(orig->getZ(),"",tr("Base Z axis"));
@ -360,10 +359,10 @@ bool TaskRevolutionParameters::getReversed(void) const
TaskRevolutionParameters::~TaskRevolutionParameters()
{
//hide the parts coordinate system axis for selection
App::Part* part = getPartFor(vp->getObject(), false);
if(part) {
PartDesign::Body * body = PartDesign::Body::findBodyOf ( vp->getObject() );
if ( body ) {
try {
App::Origin *origin = part->getOrigin();
App::Origin *origin = body->getOrigin();
ViewProviderOrigin* vpOrigin;
vpOrigin = static_cast<ViewProviderOrigin*>(Gui::Application::Instance->getViewProvider(origin));
vpOrigin->resetTemporaryVisibility();

View File

@ -33,7 +33,6 @@
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>

View File

@ -34,7 +34,6 @@
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
#include <App/Origin.h>
#include <App/OriginFeature.h>
#include <Gui/Application.h>
@ -192,11 +191,11 @@ void TaskTransformedParameters::fillAxisCombo(ComboLinks &combolinks,
//add part axes
App::DocumentObject* obj = getObject();
App::Part* part = getPartFor(obj, false);
PartDesign::Body * body = PartDesign::Body::findBodyOf ( obj );
if (part) {
if (body) {
try {
App::Origin* orig = part->getOrigin();
App::Origin* orig = body->getOrigin();
combolinks.addLink(orig->getX(),"",tr("Base X axis"));
combolinks.addLink(orig->getY(),"",tr("Base Y axis"));
combolinks.addLink(orig->getZ(),"",tr("Base Z axis"));
@ -228,11 +227,11 @@ void TaskTransformedParameters::fillPlanesCombo(ComboLinks &combolinks,
//add part baseplanes
App::DocumentObject* obj = getObject();
App::Part* part = getPartFor(obj, false);
PartDesign::Body * body = PartDesign::Body::findBodyOf ( obj );
if (part) {
if (body) {
try {
App::Origin* orig = part->getOrigin();
App::Origin* orig = body->getOrigin();
combolinks.addLink(orig->getXY(),"",tr("Base XY plane"));
combolinks.addLink(orig->getYZ(),"",tr("Base YZ plane"));
combolinks.addLink(orig->getXZ(),"",tr("Base XZ plane"));

View File

@ -99,6 +99,15 @@ PartDesign::Body *getBodyFor(const App::DocumentObject* obj, bool messageIfNot)
return nullptr;
}
App::Part* getActivePart() {
Gui::MDIView *activeView = Gui::Application::Instance->activeView();
if ( activeView ) {
return activeView->getActiveObject<App::Part*> (PARTKEY);
} else {
return 0;
}
}
App::Part* getPartFor(const App::DocumentObject* obj, bool messageIfNot) {
if(!obj)
@ -108,7 +117,7 @@ App::Part* getPartFor(const App::DocumentObject* obj, bool messageIfNot) {
if(body)
obj = body;
//get the part every body should belong to
//get the part
for(App::Part* p : obj->getDocument()->getObjectsOfType<App::Part>()) {
if(p->hasObject(obj)) {
return p;
@ -149,11 +158,7 @@ void fixSketchSupport (Sketcher::SketchObject* sketch)
}
// Get the Origin for the body
App::OriginGroup *grp = App::OriginGroup::getGroupOfObject (body);
if (!grp) {
throw Base::Exception ("Coudn't find group for body");
}
App::Origin *origin = grp->getOrigin (); // May throw by itself
App::Origin *origin = body->getOrigin (); // May throw by itself
Base::Placement plm = sketch->Placement.getValue();
Base::Vector3d pnt = plm.getPosition();

View File

@ -50,6 +50,7 @@ PartDesign::Body *getBody(bool messageIfNot);
*/
PartDesign::Body *getBodyFor(const App::DocumentObject*, bool messageIfNot);
App::Part *getPartFor(const App::DocumentObject*, bool messageIfNot);
App::Part *getActivePart();
/// Fix sketch support after moving a free sketch into a body
void fixSketchSupport(Sketcher::SketchObject* sketch);

View File

@ -26,6 +26,7 @@
#ifndef _PreComp_
# include <algorithm>
# include <Inventor/nodes/SoGroup.h>
# include <Inventor/nodes/SoSeparator.h>
#endif
#include <Base/Console.h>
@ -51,19 +52,18 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderBody,PartGui::ViewProviderPart)
ViewProviderBody::ViewProviderBody()
{
pcBodyChildren = new SoGroup();
pcBodyChildren = new SoSeparator();
pcBodyChildren->ref();
pcBodyTip = new SoGroup();
pcBodyTip = new SoSeparator();
pcBodyTip->ref();
sPixmap = "PartDesign_Body_Tree.svg";
}
ViewProviderBody::~ViewProviderBody()
{
pcBodyChildren->unref();
pcBodyChildren = 0;
pcBodyTip->unref();
pcBodyTip = 0;
pcBodyChildren->unref ();
pcBodyTip->unref ();
}
@ -71,39 +71,40 @@ void ViewProviderBody::attach(App::DocumentObject *pcFeat)
{
// call parent attach method
ViewProviderPart::attach(pcFeat);
PartDesign::Body *body = static_cast <PartDesign::Body *> (pcFeat);
App::DocumentObject *tip = body->Tip.getValue ();
if (tip) {
Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider (tip);
if (vp) {
pcBodyTip->addChild ( vp->getRoot () );
}
}
// TODO fixup the "Body" display mode (2015-08-07, Fat-Zer)
// putting all together with the switch
addDisplayMaskMode(pcBodyTip, "Body");
addDisplayMaskMode(pcBodyChildren, "Through");
addDisplayMaskMode(pcBodyTip, "Tip");
}
// TODO on activating the body switch to the "Through" mode (2015-09-05, Fat-Zer)
// TODO differnt icon in tree if mode is Through (2015-09-05, Fat-Zer)
// TODO drag&drop (2015-09-05, Fat-Zer)
void ViewProviderBody::setDisplayMode(const char* ModeName)
{
if ( strcmp("Body",ModeName)==0 )
setDisplayMaskMode("Body");
if ( strcmp("Main",ModeName)==0 )
setDisplayMaskMode("Main");
if ( strcmp("Through",ModeName)==0 )
setDisplayMaskMode("Through");
if ( strcmp("Tip",ModeName)==0 )
setDisplayMaskMode("Tip");
// TODO When switching into Tip mode switch it's visability to true (2015-09-05, Fat-Zer)
ViewProviderGeometryObject::setDisplayMode( ModeName );
}
std::vector<std::string> ViewProviderBody::getDisplayModes(void) const
{
// get the modes of the father
std::vector<std::string> StrList = ViewProviderGeometryObject::getDisplayModes();
// add your own modes
StrList.push_back("Through");
StrList.push_back("Body");
return StrList;
std::vector<std::string> ViewProviderBody::getDisplayModes(void) const {
return {"Through" , "Tip"};
}
bool ViewProviderBody::doubleClicked(void)
{
// assure the PartDesign workbench
@ -121,35 +122,35 @@ bool ViewProviderBody::doubleClicked(void)
std::vector<App::DocumentObject*> ViewProviderBody::claimChildren(void)const
{
PartDesign::Body* bodyObj = static_cast<PartDesign::Body*>(getObject());
const std::vector<App::DocumentObject*> &Model = bodyObj->Model.getValues();
std::set<App::DocumentObject*> OutSet;
PartDesign::Body* body= static_cast<PartDesign::Body*> ( getObject () );
const std::vector<App::DocumentObject*> &model = body->Model.getValues ();
std::set<App::DocumentObject*> outSet; //< set of objects not to claim (childrens of childrens)
// search for objects handled (claimed) by the features
for(std::vector<App::DocumentObject*>::const_iterator it = Model.begin();it!=Model.end();++it){
if (*it == NULL) continue;
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(*it);
if (vp == NULL) continue;
std::vector<App::DocumentObject*> children = vp->claimChildren();
for (std::vector<App::DocumentObject*>::const_iterator ch = children.begin(); ch != children.end(); ch++) {
if ((*ch) != NULL)
OutSet.insert(*ch);
}
for( auto obj: model){
if (!obj) { continue; }
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider ( obj );
if (!vp) { continue; }
auto children = vp->claimChildren();
std::remove_copy ( children.begin (), children.end (), std::inserter (outSet, outSet.begin () ), nullptr);
}
// remove the otherwise handled objects, preserving their order so the order in the TreeWidget is correct
std::vector<App::DocumentObject*> Result;
// Clame for the base feature first
if (bodyObj->BaseFeature.getValue()) {
Result.push_back (bodyObj->BaseFeature.getValue());
if (body->Origin.getValue()) { // Clame for the Origin
Result.push_back (body->Origin.getValue());
}
if (body->BaseFeature.getValue()) { // Clame for the base feature
Result.push_back (body->BaseFeature.getValue());
}
// return the rest as claim set of the Body
for (std::vector<App::DocumentObject*>::const_iterator it = Model.begin();it!=Model.end();++it) {
if (OutSet.find(*it) == OutSet.end())
Result.push_back(*it);
}
// claim for rest content not claimed by any other features
std::remove_copy_if (model.begin(), model.end(), std::back_inserter (Result),
[outSet] (App::DocumentObject* obj) {
return outSet.find (obj) != outSet.end();
} );
return Result;
}
@ -160,14 +161,21 @@ std::vector<App::DocumentObject*> ViewProviderBody::claimChildren3D(void)const
PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());
const std::vector<App::DocumentObject*> & features = body->Model.getValues();
App::DocumentObject *originObj = body->Origin.getValue();
App::DocumentObject *baseFeature = body->BaseFeature.getValue();
std::vector<App::DocumentObject*> rv;
rv.push_back( body->BaseFeature.getValue() );
rv.insert( rv.end(), features.begin(), features.end());
if (body->Origin.getValue()) { // Add origin
rv.push_back (body->Origin.getValue());
}
if ( body->BaseFeature.getValue() ) { // Add Base Feature
rv.push_back (body->BaseFeature.getValue());
}
std::copy (features.begin(), features.end(), std::back_inserter (rv) );
// TODO Check what will happen if BaseFature will be shared by severral bodies (2015-08-04, Fat-Zer)
return rv;
}
//void ViewProviderBody::updateTree()
@ -194,6 +202,7 @@ std::vector<App::DocumentObject*> ViewProviderBody::claimChildren3D(void)const
//}
bool ViewProviderBody::onDelete ( const std::vector<std::string> &) {
// TODO May be do it conditionally? (2015-09-05, Fat-Zer)
Gui::Command::doCommand(Gui::Command::Doc,
"App.getDocument(\"%s\").getObject(\"%s\").removeModelFromDocument()"
,getObject()->getDocument()->getName(), getObject()->getNameInDocument());
@ -202,18 +211,34 @@ bool ViewProviderBody::onDelete ( const std::vector<std::string> &) {
void ViewProviderBody::updateData(const App::Property* prop)
{
//Base::Console().Error("ViewProviderBody::updateData for %s\n", getObject()->getNameInDocument());
//if (ActiveGuiDoc == NULL)
// // PartDesign workbench not active
// return PartGui::ViewProviderPart::updateData(prop);
//if ((/*prop->getTypeId() == App::PropertyBool::getClassTypeId() && strcmp(prop->getName(),"IsActive") == 0) ||*/
// (prop->getTypeId() == App::PropertyLink::getClassTypeId() && strcmp(prop->getName(),"Tip") == 0) ||
// (prop->getTypeId() == App::PropertyLinkList::getClassTypeId() && strcmp(prop->getName(),"Model") == 0))
// // updateTree();
// Update the visual size of datums
PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());
if (prop == &body->Model || prop == &body->BaseFeature) {
// update sizes of origins and datums
// TODO Write this (2015-09-05, Fat-Zer)
} else if (prop == &body->Tip) {
// Adjust the internals to display
App::DocumentObject *tip = body->Tip.getValue ();
if (tip) {
Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider (tip);
if (vp) {
SoNode *tipRoot = vp->getRoot ();
if ( pcBodyTip->findChild (tipRoot) == -1 ) {
pcBodyTip->removeAllChildren ();
pcBodyTip->addChild ( tipRoot );
}
// Else our tip is already shown
} else {
pcBodyTip->removeAllChildren ();
}
} else {
pcBodyTip->removeAllChildren ();
}
}
// TODO rewrite this, it's quite a hacky way of notifying (2015-09-05, Fat-Zer)
std::vector<App::DocumentObject*> features = body->Model.getValues();
for (std::vector<App::DocumentObject*>::const_iterator f = features.begin(); f != features.end(); f++) {
App::PropertyPlacement* plm = NULL;

View File

@ -26,13 +26,15 @@
#include <Mod/Part/Gui/ViewProvider.h>
class SoGroup;
class SoSeparator;
namespace PartDesignGui {
/** ViewProvider of the Body feature
* This class manage the visual apperance of the features in the
* Body feature. That mean while editing only the tip feature is
* visible. If the Body is not active it shows only the result shape (tip).
* Body feature. That mean while editing all visible features are shown.
* If the Body is not active it shows only the result shape (tip).
* \author jriegel
*/
class PartDesignGuiExport ViewProviderBody : public PartGui::ViewProviderPart
@ -63,9 +65,9 @@ public:
void updateData(const App::Property* prop);
private:
/// group used to store children collected by claimChildren3D()
/// group used to store children collected by claimChildren3D() in the through (edit) mode.
SoGroup *pcBodyChildren;
/// group used to show the tip element in "edit" mode
/// The tip node used to display the Body when it doesn't edited.
SoGroup *pcBodyTip;
/// Update the children's highlighting

View File

@ -51,7 +51,7 @@
# include <GeomAPI_IntCS.hxx>
#endif
#include <App/Part.h>
#include <App/DocumentObjectGroup.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
@ -311,11 +311,11 @@ Base::BoundBox3d ViewProviderDatum::getRelevantExtents()
if (body != NULL)
bbox = body->getBoundBox();
else {
App::Part* part = getPartFor(this->getObject(),false);
App::DocumentObjectGroup* group = App::DocumentObjectGroup::getGroupOfObject(this->getObject());
std::vector<App::DocumentObject*> objs;
if(part)
objs = part->getObjectsOfType(Part::Feature::getClassTypeId());
if(group)
objs = group->getObjectsOfType(Part::Feature::getClassTypeId());
else
objs = this->getObject()->getDocument()->getObjectsOfType(Part::Feature::getClassTypeId());

View File

@ -28,7 +28,6 @@
# include <QMessageBox>
#endif
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
@ -67,36 +66,36 @@ Workbench::~Workbench() {
void Workbench::_switchToDocument(const App::Document* doc)
{
if (doc == NULL) return;
PartDesign::Body* activeBody = NULL;
std::vector<App::DocumentObject*> bodies = doc->getObjectsOfType(PartDesign::Body::getClassTypeId());
// No tip, so build up structure or migrate
if (!doc->Tip.getValue())
{
;/*if (doc->countObjects() == 0){
buildDefaultPartAndBody(doc);
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
assert(activeBody);
} else {
// empty document with no tip, so do migration
_doMigration(doc);
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
assert(activeBody);
}
*/
}
else
{
App::Part *docPart = dynamic_cast<App::Part *>(doc->Tip.getValue());
if (docPart) {
App::Part *viewPart = Gui::Application::Instance->activeView()->getActiveObject<App::Part *>("Part");
if (viewPart != docPart)
Gui::Application::Instance->activeView()->setActiveObject(docPart, "Part");
//if (docPart->countObjectsOfType(PartDesign::Body::getClassTypeId()) < 1)
// setUpPart(docPart);
// TODO Commented out for thurther remove or rewrite (2015-08-27, Fat-Zer)
// TODO Commented out for thurther remove or rewrite (2015-09-04, Fat-Zer)
// if (doc == NULL) return;
//
// PartDesign::Body* activeBody = NULL;
// std::vector<App::DocumentObject*> bodies = doc->getObjectsOfType(PartDesign::Body::getClassTypeId());
//
// // No tip, so build up structure or migrate
// if (!doc->Tip.getValue())
// {
// ;/*if (doc->countObjects() == 0){
// buildDefaultPartAndBody(doc);
// activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// assert(activeBody);
// } else {
// // empty document with no tip, so do migration
// _doMigration(doc);
// activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// assert(activeBody);
// }
// */
// }
// else
// {
// App::Part *docPart = dynamic_cast<App::Part *>(doc->Tip.getValue());
// if (docPart) {
// App::Part *viewPart = Gui::Application::Instance->activeView()->getActiveObject<App::Part *>("Part");
// if (viewPart != docPart)
// Gui::Application::Instance->activeView()->setActiveObject(docPart, "Part");
// //if (docPart->countObjectsOfType(PartDesign::Body::getClassTypeId()) < 1)
// // setUpPart(docPart);
// PartDesign::Body *tempBody = dynamic_cast<PartDesign::Body *> (docPart->getObjectsOfType(PartDesign::Body::getClassTypeId()).front());
// if (tempBody) {
// PartDesign::Body *viewBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
@ -109,15 +108,15 @@ void Workbench::_switchToDocument(const App::Document* doc)
// if (activeBody != viewBody)
// Gui::Application::Instance->activeView()->setActiveObject(activeBody, PDBODYKEY);
// }
}
}
/*if (activeBody == NULL) {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Could not create body"),
QObject::tr("No body was found in this document, and none could be created. Please report this bug."
"We recommend you do not use this document with the PartDesign workbench until the bug has been fixed."
));
}*/
// }
// }
//
// /*if (activeBody == NULL) {
// QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Could not create body"),
// QObject::tr("No body was found in this document, and none could be created. Please report this bug."
// "We recommend you do not use this document with the PartDesign workbench until the bug has been fixed."
// ));
// }*/
}
void Workbench::slotActiveDocument(const Gui::Document& Doc)