PartDesign/Gui: Move various utility stuff from Workbench to a separate file

Also do some header cleanup.
This commit is contained in:
Alexander Golubev 2015-08-09 16:35:23 +03:00 committed by Stefan Tröger
parent a5fcd5775e
commit c782a11aab
36 changed files with 548 additions and 474 deletions

View File

@ -38,7 +38,7 @@
#include <Mod/PartDesign/App/BodyPy.h>
#include "ViewProviderBody.h"
#include "Workbench.h"
#include "Utils.h"
//static PyObject * setActiveBody(PyObject *self, PyObject *args)
@ -92,7 +92,7 @@ static PyObject * setUpPart(PyObject *self, PyObject *args)
// Should be set!
assert(part);
PartDesignGui::Workbench::setUpPart(part);
PartDesignGui::setUpPart(part);
Py_Return;
}

View File

@ -229,6 +229,8 @@ SET(PartDesignGuiModule_SRCS
Resources/PartDesign.qrc
PreCompiled.cpp
PreCompiled.h
Utils.cpp
Utils.h
Workbench.cpp
Workbench.h
)

View File

@ -55,12 +55,11 @@
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include "Workbench.h"
using namespace std;
#include "TaskFeaturePick.h"
#include "ReferenceSelection.h"
#include "Utils.h"
using namespace std;
//===========================================================================

View File

@ -38,7 +38,8 @@
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/Feature.h>
#include "Workbench.h"
#include "Utils.h"
//===========================================================================
@ -67,7 +68,7 @@ void CmdPartDesignPart::activated(int iMsg)
PartName = getUniqueObjectName("Part");
doCommand(Doc,"App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')",PartName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr(PartName.c_str()).toStdString().c_str());
PartDesignGui::Workbench::setUpPart(dynamic_cast<App::Part *>(getDocument()->getObject(PartName.c_str())));
PartDesignGui::setUpPart(dynamic_cast<App::Part *>(getDocument()->getObject(PartName.c_str())));
doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PARTKEY, PartName.c_str());
updateActive();
@ -382,7 +383,7 @@ void CmdPartDesignMoveFeature::activated(int iMsg)
if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(feat);
try {
PartDesignGui::Workbench::fixSketchSupport(sketch);
PartDesignGui::fixSketchSupport(sketch);
} catch (Base::Exception &) {
QMessageBox::warning( Gui::getMainWindow(), QObject::tr("Sketch plane cannot be migrated"),
QObject::tr("Please edit '%1' and redefine it to use a Base or Datum plane as the sketch plane.").

View File

@ -22,7 +22,6 @@
#include "PreCompiled.h"
#include "Workbench.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeaturePrimitive.h>
#ifndef _PreComp_
@ -31,6 +30,7 @@
# include <QMessageBox>
#endif
#include <App/Document.h>
#include <Gui/Command.h>
#include <Gui/Action.h>
#include <Gui/MainWindow.h>
@ -38,6 +38,8 @@
#include <Gui/Application.h>
#include <Base/Console.h>
#include "Utils.h"
using namespace std;
DEF_STD_CMD_ACL(CmdPrimtiveCompAdditive);

View File

@ -43,7 +43,6 @@
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include "ReferenceSelection.h"
#include "Workbench.h"
using namespace PartDesignGui;
using namespace Gui;
@ -52,8 +51,8 @@ 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");
PartDesign::Body* ActivePartObject = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
App::Part* activePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>("Part");
// Don't allow selection in other document
if ((support != NULL) && (pDoc != support->getDocument()))

View File

@ -29,7 +29,6 @@
#include "ui_TaskBooleanParameters.h"
#include "TaskBooleanParameters.h"
#include "Workbench.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>

View File

@ -28,7 +28,6 @@
#include "ui_TaskChamferParameters.h"
#include "TaskChamferParameters.h"
#include "Workbench.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>

View File

@ -31,8 +31,7 @@
# include <Precision.hxx>
#endif
#include "ui_TaskDatumParameters.h"
#include "TaskDatumParameters.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Plane.h>
@ -43,15 +42,18 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/ViewProviderOrigin.h>
#include <Mod/Part/App/PrimitiveFeature.h>
#include <Mod/Part/App/DatumFeature.h>
#include <Mod/PartDesign/App/Body.h>
#include "ReferenceSelection.h"
#include "Workbench.h"
#include "Utils.h"
#include "ui_TaskDatumParameters.h"
#include "TaskDatumParameters.h"
using namespace PartDesignGui;
using namespace Gui;
@ -599,7 +601,7 @@ void TaskDatumParameters::onRefName(const QString& text, const int idx)
if (obj == NULL) return;
std::string subElement;
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree)
@ -916,7 +918,7 @@ bool TaskDlgDatumParameters::reject()
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
return true;
}

View File

@ -29,7 +29,6 @@
#include "ui_TaskDraftParameters.h"
#include "TaskDraftParameters.h"
#include "Workbench.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>

View File

@ -28,7 +28,6 @@
#endif
#include "TaskDressUpParameters.h"
#include "Workbench.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>

View File

@ -23,8 +23,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QPixmap>
# include <QDialog>
# include <QListIterator>
#endif
@ -38,12 +36,14 @@
#include <Base/Tools.h>
#include <Base/Reader.h>
#include "ui_TaskFeaturePick.h"
#include "TaskFeaturePick.h"
#include "Workbench.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "Utils.h"
#include "ui_TaskFeaturePick.h"
#include "TaskFeaturePick.h"
using namespace PartDesignGui;
const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st)
@ -226,7 +226,7 @@ std::vector<App::DocumentObject*> TaskFeaturePick::buildFeatures() {
// doesn't supposed to get here anything but sketch but to be on the safe side better to check
if (copy->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(copy);
Workbench::fixSketchSupport(sketch);
PartDesignGui::fixSketchSupport(sketch);
}
result.push_back(copy);
}

View File

@ -28,7 +28,6 @@
#include "ui_TaskFilletParameters.h"
#include "TaskFilletParameters.h"
#include "Workbench.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>

View File

@ -28,11 +28,7 @@
# include <QTimer>
#endif
#include "ui_TaskLinearPatternParameters.h"
#include "TaskLinearPatternParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <Base/Console.h>
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
@ -44,15 +40,22 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/ViewProviderOrigin.h>
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ReferenceSelection.h"
#include "TaskMultiTransformParameters.h"
#include "Utils.h"
#include "ui_TaskLinearPatternParameters.h"
#include "TaskLinearPatternParameters.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -48,7 +48,6 @@
#include <Mod/PartDesign/App/Body.h>
#include "TaskSketchBasedParameters.h"
#include "ReferenceSelection.h"
#include "Workbench.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -27,11 +27,7 @@
# include <QMessageBox>
#endif
#include "ui_TaskMirroredParameters.h"
#include "TaskMirroredParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
@ -41,7 +37,6 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/ViewProviderOrigin.h>
@ -49,6 +44,14 @@
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ReferenceSelection.h"
#include "TaskMultiTransformParameters.h"
#include "Utils.h"
#include "ui_TaskMirroredParameters.h"
#include "TaskMirroredParameters.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -46,7 +46,6 @@
#include <Mod/Sketcher/App/SketchObject.h>
#include "TaskSketchBasedParameters.h"
#include "ReferenceSelection.h"
#include "Workbench.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -50,7 +50,6 @@
#include <Mod/PartDesign/App/Body.h>
#include "TaskSketchBasedParameters.h"
#include "ReferenceSelection.h"
#include "Workbench.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -46,7 +46,6 @@
#include <Mod/Sketcher/App/SketchObject.h>
#include "TaskSketchBasedParameters.h"
#include "ReferenceSelection.h"
#include "Workbench.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -28,11 +28,6 @@
# include <QTimer>
#endif
#include "ui_TaskPolarPatternParameters.h"
#include "TaskPolarPatternParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
@ -51,6 +46,13 @@
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include "ReferenceSelection.h"
#include "TaskMultiTransformParameters.h"
#include "Utils.h"
#include "ui_TaskPolarPatternParameters.h"
#include "TaskPolarPatternParameters.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -26,9 +26,8 @@
#ifndef _PreComp_
#endif
#include "ui_TaskRevolutionParameters.h"
#include "TaskRevolutionParameters.h"
#include <Base/UnitsApi.h>
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
@ -39,7 +38,6 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/ViewProviderOrigin.h>
@ -48,10 +46,12 @@
#include <Mod/PartDesign/App/FeatureGroove.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/Body.h>
#include "ReferenceSelection.h"
#include "TaskSketchBasedParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include "Utils.h"
#include "ui_TaskRevolutionParameters.h"
#include "TaskRevolutionParameters.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -30,7 +30,7 @@
# include <Precision.hxx>
#endif
#include "TaskSketchBasedParameters.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Plane.h>
@ -42,15 +42,18 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Part/App/DatumFeature.h>
#include <Mod/PartDesign/App/FeatureSketchBased.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/Body.h>
#include "Utils.h"
#include "ReferenceSelection.h"
#include "Workbench.h"
#include "TaskSketchBasedParameters.h"
using namespace PartDesignGui;
using namespace Gui;
@ -141,12 +144,12 @@ const QByteArray TaskSketchBasedParameters::onFaceName(const QString& text)
if (obj == NULL)
return QByteArray();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree)
return QByteArray();
} else if (obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
if (!activeBody->hasFeature(obj))
if (!activeBody->hasFeature(obj))
return QByteArray();
return QByteArray();
} else {

View File

@ -28,7 +28,6 @@
#include "ui_TaskThicknessParameters.h"
#include "TaskThicknessParameters.h"
#include "Workbench.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>

View File

@ -31,9 +31,7 @@
# include <BRepAdaptor_Surface.hxx>
#endif
#include "TaskTransformedParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include <Base/Console.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Part.h>
@ -45,13 +43,19 @@
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeatureAddSub.h>
#include "ReferenceSelection.h"
#include "TaskMultiTransformParameters.h"
#include "Utils.h"
#include "TaskTransformedParameters.h"
using namespace PartDesignGui;
using namespace Gui;

View File

@ -0,0 +1,228 @@
/***************************************************************************
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QMessageBox>
# include <Precision.hxx>
# include <gp_Pln.hxx>
#endif
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Gui/MainWindow.h>
#include <Gui/MDIView.h>
#include <Gui/ViewProviderPart.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/Body.h>
#include "Utils.h"
//===========================================================================
// Helper for Body
//===========================================================================
namespace PartDesignGui {
PartDesign::Body *getBody(bool messageIfNot)
{
PartDesign::Body * activeBody = nullptr;
Gui::MDIView *activeView = Gui::Application::Instance->activeView();
if (activeView) {
activeBody = activeView->getActiveObject<PartDesign::Body*>(PDBODYKEY);
}
if (!activeBody && messageIfNot) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"),
QObject::tr("In order to use PartDesign you need an active Body object in the document. "
"Please make one active (double click) 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."
));
}
return activeBody;
}
PartDesign::Body *getBodyFor(const App::DocumentObject* obj, bool messageIfNot)
{
if(!obj)
return nullptr;
PartDesign::Body * rv = getBody( /*messageIfNot =*/ false);
if(rv && rv->hasFeature(obj))
return rv;
rv = PartDesign::Body::findBodyOf(obj);
if (rv) {
return rv;
}
if (messageIfNot){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Feature is not in a body"),
QObject::tr("In order to use this feature it needs to belong to a body object in the document."));
}
return nullptr;
}
App::Part* getPartFor(const App::DocumentObject* obj, bool messageIfNot) {
if(!obj)
return nullptr;
PartDesign::Body* body = getBodyFor(obj, false);
if(body)
obj = body;
//get the part every body should belong to
for(App::Part* p : obj->getDocument()->getObjectsOfType<App::Part>()) {
if(p->hasObject(obj)) {
return p;
}
}
if (messageIfNot){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Feature is not in a part"),
QObject::tr("In order to use this feature it needs to belong to a part object in the document."));
}
return nullptr;
}
static void buildDefaultPartAndBody(const App::Document* doc)
{
// This adds both the base planes and the body
std::string PartName = doc->getUniqueObjectName("Part");
//// create a PartDesign Part for now, can be later any kind of Part or an empty one
Gui::Command::addModule(Gui::Command::Doc, "PartDesignGui");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "PartDesignGui.setUpPart(App.activeDocument().%s)", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Part',App.activeDocument().%s)", PartName.c_str());
}
PartDesign::Body *setUpPart(const App::Part *part)
{
// first do the general Part setup
Gui::ViewProviderPart::setUpPart(part);
// check for Bodies
// std::vector<App::DocumentObject*> bodies = part->getObjectsOfType(PartDesign::Body::getClassTypeId());
// assert(bodies.size() == 0);
// std::string PartName = part->getNameInDocument();
// std::string BodyName = part->getDocument()->getUniqueObjectName("MainBody");
Gui::Command::addModule(Gui::Command::Doc, "PartDesign");
// Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('PartDesign::Body','%s')", BodyName.c_str());
// Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addObject(App.activeDocument().ActiveObject)", part->getNameInDocument());
// Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, BodyName.c_str());
Gui::Command::updateActive();
return NULL;
}
void fixSketchSupport (Sketcher::SketchObject* sketch)
{
App::DocumentObject* support = sketch->Support.getValue();
if (support)
return; // Sketch is on a face of a solid, do nothing
const App::Document* doc = sketch->getDocument();
PartDesign::Body *body = getBodyFor(sketch, /*messageIfNot*/ 0);
if (!body) {
throw Base::Exception ("Coudn't find body for the sketch");
}
Base::Placement plm = sketch->Placement.getValue();
Base::Vector3d pnt = plm.getPosition();
// Currently we only handle positions that are parallel to the base planes
Base::Rotation rot = plm.getRotation();
Base::Vector3d sketchVector(0,0,1);
rot.multVec(sketchVector, sketchVector);
bool reverseSketch = (sketchVector.x + sketchVector.y + sketchVector.z) < 0.0 ;
if (reverseSketch) sketchVector *= -1.0;
int index;
if (sketchVector == Base::Vector3d(0,0,1))
index = 0;
else if (sketchVector == Base::Vector3d(0,1,0))
index = 1;
else if (sketchVector == Base::Vector3d(1,0,0))
index = 2;
else {
throw Base::Exception("Sketch plane cannot be migrated");
}
// Find the normal distance from origin to the sketch plane
gp_Pln pln(gp_Pnt (pnt.x, pnt.y, pnt.z), gp_Dir(sketchVector.x, sketchVector.y, sketchVector.z));
double offset = pln.Distance(gp_Pnt(0,0,0));
if (fabs(offset) < Precision::Confusion()) {
// One of the base planes
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = (App.activeDocument().%s,[''])",
sketch->getNameInDocument(), App::Part::BaseplaneTypes[index]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapReversed = %s",
sketch->getNameInDocument(), reverseSketch ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",
sketch->getNameInDocument(), Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
} else {
// Offset to base plane
// Find out which direction we need to offset
double a = sketchVector.GetAngle(pnt);
if ((a < -M_PI_2) || (a > M_PI_2))
offset *= -1.0;
std::string Datum = doc->getUniqueObjectName("DatumPlane");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('PartDesign::Plane','%s')",Datum.c_str());
QString refStr = QString::fromAscii("[(App.activeDocument().") + QString::fromAscii(App::Part::BaseplaneTypes[index]) +
QString::fromAscii(",'')]");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = %s",Datum.c_str(), refStr.toStdString().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",Datum.c_str(), AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.superPlacement.Base.z = %f",Datum.c_str(), offset);
Gui::Command::doCommand(Gui::Command::Doc,
"App.activeDocument().%s.insertFeature(App.activeDocument().%s, App.activeDocument().%s)",
body->getNameInDocument(), Datum.c_str(), sketch->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = (App.activeDocument().%s,[''])",
sketch->getNameInDocument(), Datum.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapReversed = %s",
sketch->getNameInDocument(), reverseSketch ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",
sketch->getNameInDocument(),Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()"); // recompute the feature based on its references
}
}
} /* PartDesignGui */

View File

@ -0,0 +1,69 @@
/***************************************************************************
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef UTILS_H_CS5LK2ZQ
#define UTILS_H_CS5LK2ZQ
/** \file Utils.h
* This fiel contains some utility function used over PartDesignGui module
*/
namespace PartDesign {
class Body;
}
namespace App {
class DocumentObject;
class Part;
}
namespace Sketcher {
class SketchObject;
}
namespace PartDesignGui {
/// Return active body or show a warning message
PartDesign::Body *getBody(bool messageIfNot);
/**
* Finds a body for the given feature. And shows a message if not found
* Also unlike Body::findBodyFor it checks if the active body has the feature first.
*/
PartDesign::Body *getBodyFor(const App::DocumentObject*, bool messageIfNot);
App::Part *getPartFor(const App::DocumentObject*, bool messageIfNot);
/** Setup a Part for PartDesign
* This methode is use to populate a Part object with all
* necesarry PartDesign and base objects to allow the use
* in PartDesign. Its called from within PartDesign as well
* as from other modules which wish to set up a Part for PartDesin
* (e.g. Assembly):
* TODO any reasons why this should return a value? (2015-08-08, Fat-Zer)
*/
PartDesign::Body *setUpPart(const App::Part *);
/// Fix sketch support after moving a free sketch into a body
void fixSketchSupport(Sketcher::SketchObject* sketch);
} /* PartDesignGui */
#endif /* end of include guard: UTILS_H_CS5LK2ZQ */

View File

@ -24,24 +24,26 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <Inventor/nodes/SoGroup.h>
#endif
#include "ViewProviderBody.h"
#include "Workbench.h"
#include <Base/Console.h>
#include <App/Part.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/Application.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeatureSketchBased.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/DatumCS.h>
#include <algorithm>
#include "Base/Console.h"
#include <App/Part.h>
#include "Utils.h"
#include "ViewProviderBody.h"
using namespace PartDesignGui;

View File

@ -51,20 +51,23 @@
# include <GeomAPI_IntCS.hxx>
#endif
#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>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/MDIView.h>
#include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/DatumCS.h>
#include "TaskDatumParameters.h"
#include "Utils.h"
#include "ViewProviderDatum.h"
using namespace PartDesignGui;
PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject)
@ -260,11 +263,11 @@ bool ViewProviderDatum::doubleClicked(void)
std::string Msg("Edit ");
Msg += this->pcObject->Label.getValue();
Gui::Command::openCommand(Msg.c_str());
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
if (activeBody != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
if (activeBody != NULL) {
// Drop into insert mode so that the user doesn't see all the geometry that comes later in the tree
// Also, this way the user won't be tempted to use future geometry as external references for the sketch
oldTip = activeBody->Tip.getValue();
oldTip = activeBody->Tip.getValue();
if (oldTip != this->pcObject)
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
else
@ -285,9 +288,9 @@ void ViewProviderDatum::unsetEdit(int ModNum)
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
if ((activeBody != NULL) && (oldTip != NULL)) {
if ((activeBody != NULL) && (oldTip != NULL)) {
Gui::Selection().clearSelection();
Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");

View File

@ -44,7 +44,6 @@
#include "ViewProviderDatumCS.h"
#include "TaskDatumParameters.h"
#include "Workbench.h"
#include <Mod/PartDesign/App/DatumCS.h>
#include <Mod/Part/Gui/SoBrepFaceSet.h>
#include <Mod/Part/Gui/SoBrepEdgeSet.h>

View File

@ -39,7 +39,6 @@
#include "ViewProviderDatumLine.h"
#include "TaskDatumParameters.h"
#include "Workbench.h"
#include <Mod/Part/Gui/SoBrepFaceSet.h>
#include <Mod/Part/Gui/SoBrepEdgeSet.h>
#include <Mod/Part/Gui/SoBrepPointSet.h>

View File

@ -40,7 +40,6 @@
#include "ViewProviderDatumPlane.h"
#include "TaskDatumParameters.h"
#include "Workbench.h"
#include <Mod/PartDesign/App/DatumPlane.h>
#include <Mod/Part/Gui/SoBrepFaceSet.h>
#include <Mod/Part/Gui/SoBrepEdgeSet.h>

View File

@ -29,7 +29,6 @@
#include "ViewProviderLoft.h"
//#include "TaskLoftParameters.h"
#include "Workbench.h"
#include "TaskLoftParameters.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeatureLoft.h>

View File

@ -29,7 +29,6 @@
#include "ViewProviderPipe.h"
//#include "TaskPipeParameters.h"
#include "Workbench.h"
#include "TaskPipeParameters.h"
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/FeaturePipe.h>

View File

@ -47,7 +47,6 @@
# include <QMessageBox>
#endif
#include "Workbench.h"
#include "ViewProviderTransformed.h"
#include "TaskTransformedParameters.h"
#include <Base/Console.h>

View File

@ -24,40 +24,25 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <qobject.h>
# include <boost/bind.hpp>
# include <Precision.hxx>
# include <QMessageBox>
# include <gp_Pnt.hxx>
# include <gp_Dir.hxx>
# include <gp_Pln.hxx>
#endif
#include "Workbench.h"
#include <App/Plane.h>
#include <App/Part.h>
#include <App/Placement.h>
#include <App/Application.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Gui/Document.h>
#include <Gui/MainWindow.h>
#include <Gui/MenuManager.h>
#include <Gui/ToolBarManager.h>
#include <Gui/Control.h>
#include <Gui/DlgCheckableMessageBox.h>
#include <Gui/ViewProviderPart.h>
#include <Gui/ActiveObjectList.h>
#include <Gui/MDIView.h>
#include <Gui/MenuManager.h>
#include <Mod/Sketcher/Gui/Workbench.h>
#include <Mod/Part/App/Part2DObject.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/Feature.h>
#include <Mod/PartDesign/App/FeatureSketchBased.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/Part/App/DatumFeature.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "Utils.h"
#include "Workbench.h"
using namespace PartDesignGui;
@ -68,82 +53,6 @@ using namespace PartDesignGui;
qApp->translate("Gui::TaskView::TaskWatcherCommands", "Create Geometry");
#endif
namespace PartDesignGui {
//===========================================================================
// Helper for Body
//===========================================================================
PartDesign::Body *getBody(bool messageIfNot)
{
PartDesign::Body * activeBody = nullptr;
Gui::MDIView *activeView = Gui::Application::Instance->activeView();
if (activeView) {
activeBody = activeView->getActiveObject<PartDesign::Body*>(PDBODYKEY);
}
if (!activeBody && messageIfNot) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"),
QObject::tr("In order to use PartDesign you need an active Body object in the document. "
"Please make one active (double click) 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."
));
}
return activeBody;
}
PartDesign::Body *getBodyFor(const App::DocumentObject* obj, bool messageIfNot)
{
if(!obj)
return nullptr;
PartDesign::Body * rv = getBody( /*messageIfNot =*/ false);
if(rv && rv->hasFeature(obj))
return rv;
rv = PartDesign::Body::findBodyOf(obj);
if (rv) {
return rv;
}
if (messageIfNot){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Feature is not in a body"),
QObject::tr("In order to use this feature it needs to belong to a body object in the document."));
}
return nullptr;
}
App::Part* getPartFor(const App::DocumentObject* obj, bool messageIfNot) {
if(!obj)
return nullptr;
PartDesign::Body* body = getBodyFor(obj, false);
if(body)
obj = body;
//get the part every body should belong to
for(App::Part* p : obj->getDocument()->getObjectsOfType<App::Part>()) {
if(p->hasObject(obj)) {
return p;
}
}
if (messageIfNot){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Feature is not in a part"),
QObject::tr("In order to use this feature it needs to belong to a part object in the document."));
}
return nullptr;
}
}
/// @namespace PartDesignGui @class Workbench
TYPESYSTEM_SOURCE(PartDesignGui::Workbench, Gui::StdWorkbench)
@ -155,260 +64,152 @@ Workbench::~Workbench()
{
}
static void buildDefaultPartAndBody(const App::Document* doc)
{
// This adds both the base planes and the body
std::string PartName = doc->getUniqueObjectName("Part");
//// create a PartDesign Part for now, can be later any kind of Part or an empty one
Gui::Command::addModule(Gui::Command::Doc, "PartDesignGui");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "PartDesignGui.setUpPart(App.activeDocument().%s)", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Part',App.activeDocument().%s)", PartName.c_str());
}
PartDesign::Body *Workbench::setUpPart(const App::Part *part)
{
// first do the general Part setup
Gui::ViewProviderPart::setUpPart(part);
// check for Bodies
// std::vector<App::DocumentObject*> bodies = part->getObjectsOfType(PartDesign::Body::getClassTypeId());
// assert(bodies.size() == 0);
// std::string PartName = part->getNameInDocument();
// std::string BodyName = part->getDocument()->getUniqueObjectName("MainBody");
Gui::Command::addModule(Gui::Command::Doc, "PartDesign");
// Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('PartDesign::Body','%s')", BodyName.c_str());
// Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addObject(App.activeDocument().ActiveObject)", part->getNameInDocument());
// Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, BodyName.c_str());
Gui::Command::updateActive();
return NULL;
}
void Workbench::_doMigration(const App::Document* doc)
{
bool groupCreated = false;
if(doc->countObjects() != 0) {
// show a warning about the convertion
Gui::Dialog::DlgCheckableMessageBox::showMessage(
QString::fromLatin1("PartDesign conversion warning"),
QString::fromLatin1(
"<h2>Converting PartDesign features to new Body centric schema</h2>"
"If you are unsure what that mean save the document under a new name.<br>"
"You will not be able to load your work in an older Version of FreeCAD,<br>"
"After the translation took place...<br><br>"
"More information you will find here:<br>"
" <a href=\"http://www.freecadweb.org/wiki/index.php?title=Assembly_project\">http://www.freecadweb.org/wiki/index.php?title=Assembly_project</a> <br>"
"Or the Assembly dedicated portion of our forum:<br>"
" <a href=\"http://forum.freecadweb.org/viewforum.php?f=20&sid=2a1a326251c44576f450739e4a74c37d\">http://forum.freecadweb.org/</a> <br>"
),
false,
QString::fromLatin1("Don't tell me again, I know!")
);
}
Gui::Command::openCommand("Migrate part to Body feature");
// Get the objects now, before adding the Body and the base planes
std::vector<App::DocumentObject*> features = doc->getObjects();
// Assign all non-PartDesign features to a new group
for (std::vector<App::DocumentObject*>::iterator f = features.begin(); f != features.end(); ) {
if ((*f)->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) ||
(*f)->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
++f;
} else {
if (!groupCreated) {
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','NonBodyFeatures')");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'",
QObject::tr("NonBodyFeatures").toStdString().c_str());
groupCreated = true;
}
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().NonBodyFeatures.addObject(App.activeDocument().getObject('%s'))",
(*f)->getNameInDocument());
f = features.erase(f);
}
}
// TODO: Fold the group (is that possible through the Python interface?)
// Try to find the root(s) of the model tree (the features that depend on no other feature)
// Note: We assume a linear graph, except for MultiTransform features
std::vector<App::DocumentObject*> roots;
for (std::vector<App::DocumentObject*>::iterator f = features.begin(); f != features.end(); f++) {
// Note: The dependency list always contains at least the object itself
std::vector<App::DocumentObject*> ftemp;
ftemp.push_back(*f);
if (doc->getDependencyList(ftemp).size() == 1)
roots.push_back(*f);
}
// Always create at least the first body, even if the document is empty
buildDefaultPartAndBody(doc);
PartDesign::Body *activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
assert(activeBody);
// Create one Body for every root and put the appropriate features into it
for (std::vector<App::DocumentObject*>::iterator r = roots.begin(); r != roots.end(); r++) {
if (r != roots.begin()) {
Gui::Command::runCommand(Gui::Command::Doc, "FreeCADGui.runCommand('PartDesign_Body')");
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
}
std::set<App::DocumentObject*> inList;
inList.insert(*r); // start with the root feature
std::vector<App::DocumentObject*> bodyFeatures;
std::string modelString = "";
do {
for (std::set<App::DocumentObject*>::const_iterator o = inList.begin(); o != inList.end(); o++) {
std::vector<App::DocumentObject*>::iterator feat = std::find(features.begin(), features.end(), *o);
if (feat != features.end()) {
bodyFeatures.push_back(*o);
modelString += std::string(modelString.empty() ? "" : ",") + "App.ActiveDocument." + (*o)->getNameInDocument();
features.erase(feat);
} else {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Non-linear tree"),
QObject::tr("Please look at '%1' and make sure that the migration result is what you"
" would expect.").arg(QString::fromAscii((*o)->getNameInDocument())));
}
}
std::set<App::DocumentObject*> newInList;
for (std::set<App::DocumentObject*>::const_iterator o = inList.begin(); o != inList.end(); o++) {
// Omit members of a MultiTransform from the inList, to avoid migration errors
if (PartDesign::Body::isMemberOfMultiTransform(*o))
continue;
std::vector<App::DocumentObject*> iL = doc->getInList(*o);
newInList.insert(iL.begin(), iL.end());
}
inList = newInList; // TODO: Memory leak? Unnecessary copying?
} while (!inList.empty());
if (!modelString.empty()) {
modelString = std::string("[") + modelString + "]";
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Model = %s", activeBody->getNameInDocument(), modelString.c_str());
// Set the Tip, but not to a member of a MultiTransform!
for (std::vector<App::DocumentObject*>::const_reverse_iterator f = bodyFeatures.rbegin(); f != bodyFeatures.rend(); f++) {
if (PartDesign::Body::isMemberOfMultiTransform(*f))
continue;
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",
activeBody->getNameInDocument(), (*f)->getNameInDocument());
break;
}
}
// Initialize the BaseFeature property of all PartDesign solid features
App::DocumentObject* baseFeature = NULL;
for (std::vector<App::DocumentObject*>::const_iterator f = bodyFeatures.begin(); f != bodyFeatures.end(); f++) {
if (PartDesign::Body::isSolidFeature(*f)) {
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.BaseFeature = %s",
(*f)->getNameInDocument(),
baseFeature == NULL ?
"None" :
(std::string("App.activeDocument().") + baseFeature->getNameInDocument()).c_str());
baseFeature = *f;
}
}
// Re-route all sketches without support to the base planes
std::vector<App::DocumentObject*>::const_iterator prevf;
for (std::vector<App::DocumentObject*>::const_iterator f = bodyFeatures.begin(); f != bodyFeatures.end(); f++) {
if ((*f)->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(*f);
try {
fixSketchSupport(sketch);
} catch (Base::Exception &) {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Sketch plane cannot be migrated"),
QObject::tr("Please edit '%1' and redefine it to use a Base or Datum plane as the sketch plane.").
arg(QString::fromAscii(sketch->getNameInDocument()) ) );
}
}
prevf = f;
}
}
}
void Workbench::fixSketchSupport (Sketcher::SketchObject* sketch)
{
App::DocumentObject* support = sketch->Support.getValue();
if (support)
return; // Sketch is on a face of a solid, do nothing
const App::Document* doc = sketch->getDocument();
PartDesign::Body *body = getBodyFor(sketch, /*messageIfNot*/ 0);
if (!body) {
throw Base::Exception ("Coudn't find body for the sketch");
}
Base::Placement plm = sketch->Placement.getValue();
Base::Vector3d pnt = plm.getPosition();
// Currently we only handle positions that are parallel to the base planes
Base::Rotation rot = plm.getRotation();
Base::Vector3d sketchVector(0,0,1);
rot.multVec(sketchVector, sketchVector);
bool reverseSketch = (sketchVector.x + sketchVector.y + sketchVector.z) < 0.0 ;
if (reverseSketch) sketchVector *= -1.0;
int index;
if (sketchVector == Base::Vector3d(0,0,1))
index = 0;
else if (sketchVector == Base::Vector3d(0,1,0))
index = 1;
else if (sketchVector == Base::Vector3d(1,0,0))
index = 2;
else {
throw Base::Exception("Sketch plane cannot be migrated");
}
// Find the normal distance from origin to the sketch plane
gp_Pln pln(gp_Pnt (pnt.x, pnt.y, pnt.z), gp_Dir(sketchVector.x, sketchVector.y, sketchVector.z));
double offset = pln.Distance(gp_Pnt(0,0,0));
if (fabs(offset) < Precision::Confusion()) {
// One of the base planes
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = (App.activeDocument().%s,[''])",
sketch->getNameInDocument(), App::Part::BaseplaneTypes[index]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapReversed = %s",
sketch->getNameInDocument(), reverseSketch ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",
sketch->getNameInDocument(), Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
} else {
// Offset to base plane
// Find out which direction we need to offset
double a = sketchVector.GetAngle(pnt);
if ((a < -M_PI_2) || (a > M_PI_2))
offset *= -1.0;
std::string Datum = doc->getUniqueObjectName("DatumPlane");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('PartDesign::Plane','%s')",Datum.c_str());
QString refStr = QString::fromAscii("[(App.activeDocument().") + QString::fromAscii(App::Part::BaseplaneTypes[index]) +
QString::fromAscii(",'')]");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = %s",Datum.c_str(), refStr.toStdString().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",Datum.c_str(), AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.superPlacement.Base.z = %f",Datum.c_str(), offset);
Gui::Command::doCommand(Gui::Command::Doc,
"App.activeDocument().%s.insertFeature(App.activeDocument().%s, App.activeDocument().%s)",
body->getNameInDocument(), Datum.c_str(), sketch->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = (App.activeDocument().%s,[''])",
sketch->getNameInDocument(), Datum.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapReversed = %s",
sketch->getNameInDocument(), reverseSketch ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",
sketch->getNameInDocument(),Attacher::AttachEngine::eMapModeStrings[Attacher::mmFlatFace]);
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()"); // recompute the feature based on its references
}
}
// Commented out due to later to be moves and/or generall rewrighted from scratch (Fat-Zer 2015-08-08)
// void Workbench::_doMigration(const App::Document* doc)
// {
// bool groupCreated = false;
//
// if(doc->countObjects() != 0) {
// // show a warning about the convertion
// Gui::Dialog::DlgCheckableMessageBox::showMessage(
// QString::fromLatin1("PartDesign conversion warning"),
// QString::fromLatin1(
// "<h2>Converting PartDesign features to new Body centric schema</h2>"
// "If you are unsure what that mean save the document under a new name.<br>"
// "You will not be able to load your work in an older Version of FreeCAD,<br>"
// "After the translation took place...<br><br>"
// "More information you will find here:<br>"
// " <a href=\"http://www.freecadweb.org/wiki/index.php?title=Assembly_project\">http://www.freecadweb.org/wiki/index.php?title=Assembly_project</a> <br>"
// "Or the Assembly dedicated portion of our forum:<br>"
// " <a href=\"http://forum.freecadweb.org/viewforum.php?f=20&sid=2a1a326251c44576f450739e4a74c37d\">http://forum.freecadweb.org/</a> <br>"
// ),
// false,
// QString::fromLatin1("Don't tell me again, I know!")
// );
// }
//
// Gui::Command::openCommand("Migrate part to Body feature");
//
// // Get the objects now, before adding the Body and the base planes
// std::vector<App::DocumentObject*> features = doc->getObjects();
//
// // Assign all non-PartDesign features to a new group
// for (std::vector<App::DocumentObject*>::iterator f = features.begin(); f != features.end(); ) {
// if ((*f)->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId()) ||
// (*f)->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
// ++f;
// } else {
// if (!groupCreated) {
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','NonBodyFeatures')");
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'",
// QObject::tr("NonBodyFeatures").toStdString().c_str());
// groupCreated = true;
// }
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().NonBodyFeatures.addObject(App.activeDocument().getObject('%s'))",
// (*f)->getNameInDocument());
// f = features.erase(f);
// }
// }
// // TODO: Fold the group (is that possible through the Python interface?)
//
// // Try to find the root(s) of the model tree (the features that depend on no other feature)
// // Note: We assume a linear graph, except for MultiTransform features
// std::vector<App::DocumentObject*> roots;
// for (std::vector<App::DocumentObject*>::iterator f = features.begin(); f != features.end(); f++) {
// // Note: The dependency list always contains at least the object itself
// std::vector<App::DocumentObject*> ftemp;
// ftemp.push_back(*f);
// if (doc->getDependencyList(ftemp).size() == 1)
// roots.push_back(*f);
// }
//
// // Always create at least the first body, even if the document is empty
// buildDefaultPartAndBody(doc);
// PartDesign::Body *activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// assert(activeBody);
//
// // Create one Body for every root and put the appropriate features into it
// for (std::vector<App::DocumentObject*>::iterator r = roots.begin(); r != roots.end(); r++) {
// if (r != roots.begin()) {
// Gui::Command::runCommand(Gui::Command::Doc, "FreeCADGui.runCommand('PartDesign_Body')");
// activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>(PDBODYKEY);
// }
//
// std::set<App::DocumentObject*> inList;
// inList.insert(*r); // start with the root feature
// std::vector<App::DocumentObject*> bodyFeatures;
// std::string modelString = "";
// do {
// for (std::set<App::DocumentObject*>::const_iterator o = inList.begin(); o != inList.end(); o++) {
// std::vector<App::DocumentObject*>::iterator feat = std::find(features.begin(), features.end(), *o);
// if (feat != features.end()) {
// bodyFeatures.push_back(*o);
// modelString += std::string(modelString.empty() ? "" : ",") + "App.ActiveDocument." + (*o)->getNameInDocument();
// features.erase(feat);
// } else {
// QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Non-linear tree"),
// QObject::tr("Please look at '%1' and make sure that the migration result is what you"
// " would expect.").arg(QString::fromAscii((*o)->getNameInDocument())));
// }
// }
// std::set<App::DocumentObject*> newInList;
// for (std::set<App::DocumentObject*>::const_iterator o = inList.begin(); o != inList.end(); o++) {
// // Omit members of a MultiTransform from the inList, to avoid migration errors
// if (PartDesign::Body::isMemberOfMultiTransform(*o))
// continue;
// std::vector<App::DocumentObject*> iL = doc->getInList(*o);
// newInList.insert(iL.begin(), iL.end());
// }
// inList = newInList; // TODO: Memory leak? Unnecessary copying?
// } while (!inList.empty());
//
// if (!modelString.empty()) {
// modelString = std::string("[") + modelString + "]";
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Model = %s", activeBody->getNameInDocument(), modelString.c_str());
// // Set the Tip, but not to a member of a MultiTransform!
// for (std::vector<App::DocumentObject*>::const_reverse_iterator f = bodyFeatures.rbegin(); f != bodyFeatures.rend(); f++) {
// if (PartDesign::Body::isMemberOfMultiTransform(*f))
// continue;
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Tip = App.activeDocument().%s",
// activeBody->getNameInDocument(), (*f)->getNameInDocument());
// break;
// }
// }
//
// // Initialize the BaseFeature property of all PartDesign solid features
// App::DocumentObject* baseFeature = NULL;
// for (std::vector<App::DocumentObject*>::const_iterator f = bodyFeatures.begin(); f != bodyFeatures.end(); f++) {
// if (PartDesign::Body::isSolidFeature(*f)) {
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.BaseFeature = %s",
// (*f)->getNameInDocument(),
// baseFeature == NULL ?
// "None" :
// (std::string("App.activeDocument().") + baseFeature->getNameInDocument()).c_str());
//
// baseFeature = *f;
// }
// }
//
// // Re-route all sketches without support to the base planes
// std::vector<App::DocumentObject*>::const_iterator prevf;
//
// for (std::vector<App::DocumentObject*>::const_iterator f = bodyFeatures.begin(); f != bodyFeatures.end(); f++) {
// if ((*f)->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
// Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(*f);
// try {
// fixSketchSupport(sketch);
// } catch (Base::Exception &) {
// QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Sketch plane cannot be migrated"),
// QObject::tr("Please edit '%1' and redefine it to use a Base or Datum plane as the sketch plane.").
// arg(QString::fromAscii(sketch->getNameInDocument()) ) );
// }
// }
//
// prevf = f;
// }
// }
//
// }
void Workbench::_switchToDocument(const App::Document* doc)
{

View File

@ -34,18 +34,6 @@ class ViewProviderDocumentObject;
}
namespace PartDesign {
class Body;
}
namespace App {
class Part;
}
namespace Sketcher {
class SketchObject;
}
namespace PartDesignGui {
// pointer to the active assembly object
@ -54,15 +42,6 @@ namespace PartDesignGui {
//extern App::Document *ActiveAppDoc;
//extern Gui::ViewProviderDocumentObject *ActiveVp;
/// Return active body or show a warning message
PartDesign::Body *getBody(bool messageIfNot);
/**
* Finds a body for the given feature. And shows a message if not found
* Also unlike Body::findBodyFor it checks if the active body has the feature first.
*/
PartDesign::Body *getBodyFor(const App::DocumentObject*, bool messageIfNot);
App::Part *getPartFor(const App::DocumentObject*, bool messageIfNot);
/**
* @author Werner Mayer
*/
@ -82,18 +61,6 @@ public:
/// Add custom entries to the context menu
virtual void setupContextMenu(const char* recipient, Gui::MenuItem*) const;
/** Setup a Part for PartDesign
* This methode is use to populate a Part object with all
* necesarry PartDesign and base objects to allow the use
* in PartDesign. Its called from within PartDesign as well
* as from other modules which wish to set up a Part for PartDesin
* (e.g. Assembly):
*/
static PartDesign::Body *setUpPart(const App::Part *);
/// Fix sketch support after moving a free sketch into a body
static void fixSketchSupport(Sketcher::SketchObject* sketch);
protected:
Gui::MenuItem* setupMenuBar() const;
Gui::ToolBarItem* setupToolBars() const;
@ -111,7 +78,7 @@ private:
// Add new objects to the body, if appropriate
//void slotNewObject(const App::DocumentObject& obj);
void _doMigration(const App::Document* doc);
//void _doMigration(const App::Document* doc);
void _switchToDocument(const App::Document* doc);
};