PartDesign/Gui: initial migration command implementation

This commit is contained in:
Alexander Golubev 2015-08-17 12:54:39 +03:00 committed by Stefan Tröger
parent c4f094bba4
commit 492f1d24a4
7 changed files with 361 additions and 181 deletions

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com *
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@ -28,20 +28,47 @@
# include <QInputDialog>
#endif
#include <Base/Console.h>
#include <App/Part.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/ActiveObjectList.h>
#include <Gui/MainWindow.h>
#include <Gui/MDIView.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/Feature.h>
#include <Mod/PartDesign/App/FeatureSketchBased.h>
#include "Utils.h"
#include "WorkflowManager.h"
//===========================================================================
// Shared functions
//===========================================================================
namespace PartDesignGui {
/// Returns active part, if there is no such, creates a new part, if it fails, shows a message
App::Part* assertActivePart () {
App::Part* rv= Gui::Application::Instance->activeView()->getActiveObject<App::Part *> ( PARTKEY );
if ( !rv ) {
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.runCommandByName("PartDesign_Part");
rv = Gui::Application::Instance->activeView()->getActiveObject<App::Part *> ( PARTKEY );
if ( !rv ) {
QMessageBox::critical ( 0, QObject::tr( "Part creation failed" ),
QObject::tr( "Failed to create a part object." ) );
}
}
return rv;
}
} /* PartDesignGui */
//===========================================================================
// PartDesign_Part
@ -62,7 +89,7 @@ CmdPartDesignPart::CmdPartDesignPart()
void CmdPartDesignPart::activated(int iMsg)
{
if ( PartDesignGui::assureModernWorkflow( getDocument() ) )
if ( !PartDesignGui::assureModernWorkflow( getDocument() ) )
return;
openCommand("Add a part");
@ -71,7 +98,9 @@ void CmdPartDesignPart::activated(int iMsg)
std::string PartName;
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());
// TODO We really must to set label ourselfs? (2015-08-17, Fat-Zer)
doCommand(Doc,"App.activeDocument().%s.Label = '%s'", PartName.c_str(),
QObject::tr(PartName.c_str()).toUtf8().data());
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());
@ -102,7 +131,7 @@ CmdPartDesignBody::CmdPartDesignBody()
void CmdPartDesignBody::activated(int iMsg)
{
if ( PartDesignGui::assureModernWorkflow( getDocument() ) )
if ( !PartDesignGui::assureModernWorkflow( getDocument() ) )
return;
std::vector<App::DocumentObject*> features =
getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
@ -128,19 +157,17 @@ void CmdPartDesignBody::activated(int iMsg)
}
// first check if Part is already created:
App::Part *actPart = getDocument()->Tip.getValue<App::Part *>();
std::string PartName;
if(!actPart){
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.runCommandByName("PartDesign_Part");
actPart = getDocument()->Tip.getValue<App::Part *>();
App::Part *actPart = PartDesignGui::assertActivePart ();
if (!actPart) {
return;
}
openCommand("Add a body");
std::string PartName = actPart->getNameInDocument();
openCommand("Add a Body");
std::string FeatName = getUniqueObjectName("Body");
PartName = actPart->getNameInDocument();
// add the Body feature itself, and make it active
doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", FeatName.c_str());
if (baseFeature) {
@ -175,7 +202,7 @@ CmdPartDesignMigrate::CmdPartDesignMigrate()
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("Migrate");
sToolTipText = QT_TR_NOOP("Migrate document to the new workflow");
sToolTipText = QT_TR_NOOP("Migrate document to the modern partdesign workflow");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
}
@ -183,17 +210,197 @@ CmdPartDesignMigrate::CmdPartDesignMigrate()
void CmdPartDesignMigrate::activated(int iMsg)
{
App::Document *doc = getDocument();
// TODO make a proper implementation
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Not implemented yet"),
QObject::tr("The migration not implemented yet, just force-switching to the new workflow.\n"
"Previous workflow was: %1").arg(int(
PartDesignGui::WorkflowManager::instance()->determinWorkflow( doc ) )));
PartDesignGui::WorkflowManager::instance()->forceWorkflow(doc, PartDesignGui::Workflow::Modern);
std::set<PartDesign::Feature*> migrateFeatures;
// Retrive all PartDesign Features objects and filter out features already belongs to some body
for ( const auto & feat: doc->getObjects( ) ) {
if( feat->isDerivedFrom( PartDesign::Feature::getClassTypeId() ) &&
!PartDesign::Body::findBodyOf( feat ) && PartDesign::Body::isSolidFeature ( feat ) ) {
migrateFeatures.insert ( static_cast <PartDesign::Feature *>( feat ) );
}
}
if ( migrateFeatures.empty() ) {
if ( !PartDesignGui::isModernWorkflow ( doc ) ) {
// If there is nothing to migrate and workflow is still old just set it to modern
PartDesignGui::WorkflowManager::instance()->forceWorkflow (
doc, PartDesignGui::Workflow::Modern );
} else {
// Huh? nothing to migrate?
QMessageBox::warning ( 0, QObject::tr ( "Nothing to migrate" ),
QObject::tr ( "No PartDesign features which doesn't belong to a body found."
" Nothing to migrate." ) );
}
return;
}
// Note: this action is undoable, should it be?
PartDesignGui::WorkflowManager::instance()->forceWorkflow ( doc, PartDesignGui::Workflow::Modern );
// Put features into chains. Each chain should become a separate body.
std::list< std::list<PartDesign::Feature *> > featureChains;
std::list<PartDesign::Feature *> chain; //< the current chain we are working on
for (auto featIt = migrateFeatures.begin(); !migrateFeatures.empty(); ) {
Part::Feature *base = (*featIt)->getBaseObject( /*silent =*/ true );
chain.push_front ( *featIt );
if ( !base || !base->isDerivedFrom (PartDesign::Feature::getClassTypeId () ) ||
PartDesignGui::isAnyNonPartDesignLinksTo ( static_cast <PartDesign::Feature *>(base),
/*respectGroups=*/ true ) ) {
// a feature based on nothing as well as on non-partdesign solid starts a new chain
auto newChainIt = featureChains.emplace (featureChains.end());
newChainIt->splice (newChainIt->end(), chain);
} else {
// we are basing on some partdesign feature wich supposed to belong to some body
PartDesign::Feature *baseFeat = static_cast <PartDesign::Feature *>( base );
auto baseFeatSetIt = find ( migrateFeatures.begin (), migrateFeatures.end (), baseFeat );
if ( baseFeatSetIt != migrateFeatures.end() ) {
// base feature is pending for migration, switch to it and continue over
migrateFeatures.erase(featIt);
featIt = baseFeatSetIt;
continue;
} else {
// The base feature seems already assigned to some chain
// Find which
std::list<PartDesign::Feature *>::iterator baseFeatIt;
auto chainIt = std::find_if( featureChains.begin(), featureChains.end(),
[baseFeat, &baseFeatIt] ( std::list<PartDesign::Feature *>&chain ) mutable -> bool {
baseFeatIt = std::find( chain.begin(), chain.end(), baseFeat );
return baseFeatIt != chain.end();
} );
if ( chainIt != featureChains.end() ) {
assert (baseFeatIt != chainIt->end());
if ( std::next ( baseFeatIt ) == chainIt->end() ) {
// just append our chain to already found
chainIt->splice ( chainIt->end(), chain );
// TODO If we will hit a third part everything will be messed up again.
// Probably it will require a yet another smart-ass find_if. (2015-08-10, Fat-Zer)
} else {
// We have a fork of a partDesign feature here
// add a chain for current body
auto newChainIt = featureChains.emplace (featureChains.end());
newChainIt->splice (newChainIt->end(), chain);
// add a chain for forked one
newChainIt = featureChains.emplace (featureChains.end());
newChainIt->splice (newChainIt->end(), *chainIt,
std::next ( baseFeatIt ), chainIt->end());
}
} else {
// The feature is not present in list pending for migration,
// This generally shouldn't happen but may be if we run into some broken file
// Try to find out the body we should insert into
// TODO Some error/warning is needed here (2015-08-10, Fat-Zer)
auto newChainIt = featureChains.emplace (featureChains.end());
newChainIt->splice (newChainIt->end(), chain);
}
}
}
migrateFeatures.erase ( featIt );
featIt = migrateFeatures.begin ();
// TODO Align visability (2015-08-17, Fat-Zer)
} /* for */
// add a part if there is no active yet
App::Part *actPart = PartDesignGui::assertActivePart ();
if (!actPart) {
return;
}
// do the actual migration
Gui::Command::openCommand("Migrate legacy part design features to Bodies");
for ( auto chainIt = featureChains.begin(); !featureChains.empty();
featureChains.erase (chainIt), chainIt = featureChains.begin () ) {
#ifndef FC_DEBUG
if ( chainIt->empty () ) { // prevent crash in release in case of errors
continue;
}
#else
assert ( !chainIt->empty () );
#endif
Part::Feature *base = chainIt->front()->getBaseObject ( /*silent =*/ true );
// Find a suitable chain to work with
for( ; chainIt != featureChains.end(); chainIt ++) {
base = chainIt->front()->getBaseObject ( /*silent =*/ true );
if (!base || !base->isDerivedFrom ( PartDesign::Feature::getClassTypeId () ) ) {
break; // no base is ok
} else {
// The base feature is a PartDesign, it's a fork, try to reassign it to a body...
base = PartDesign::Body::findBodyOf ( base );
if ( base ) {
break;
}
}
}
if ( chainIt == featureChains.end() ) {
// Shouldn't happen, may be only in case of some circular dependency?
// TODO Some error message (2015-08-11, Fat-Zer)
chainIt = featureChains.begin();
base = chainIt->front()->getBaseObject ( /*silent =*/ true );
}
// Construct a Pretty Body name based on the Tip
std::string bodyName = getUniqueObjectName (
std::string ( chainIt->back()->getNameInDocument() ).append ( "Body" ).c_str () ) ;
// Create a body for the chain
doCommand ( Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", bodyName.c_str () );
doCommand ( Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)",
actPart->getNameInDocument (), bodyName.c_str () );
if (base) {
doCommand ( Doc,"App.activeDocument().%s.BaseFeature = App.activeDocument().%s",
bodyName.c_str (), base->getNameInDocument () );
}
// Fill the body with features
for ( auto feature: *chainIt ) {
if ( feature->isDerivedFrom ( PartDesign::SketchBased::getClassTypeId() ) ) {
// add the sketch and also reroute it if needed
PartDesign::SketchBased *sketchBased = static_cast<PartDesign::SketchBased *> ( feature );
Part::Part2DObject *sketch = sketchBased->getVerifiedSketch( /*silent =*/ true);
if ( sketch ) {
doCommand ( Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
bodyName.c_str (), sketch->getNameInDocument() );
if ( sketch->isDerivedFrom ( Sketcher::SketchObject::getClassTypeId() ) ) {
try {
PartDesignGui::fixSketchSupport ( static_cast<Sketcher::SketchObject *> ( 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::fromUtf8(sketch->Label.getValue()) ) );
}
} else {
// TODO Message that sketchbased is based not on a sketch (2015-08-11, Fat-Zer)
}
}
}
doCommand ( Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)",
bodyName.c_str (), feature->getNameInDocument() );
PartDesignGui::relinkToBody ( feature );
}
}
updateActive();
}
bool CmdPartDesignMigrate::isActive(void)
{
return hasActiveDocument() && !PartDesignGui::isLegacyWorkflow ( getDocument () );
return hasActiveDocument();
}
//===========================================================================

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com *
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@ -189,6 +189,7 @@ void fixSketchSupport (Sketcher::SketchObject* sketch)
// 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));
// TODO Issue a message if sketch have coordinates offset inside the plain (2016-08-15, Fat-Zer)
if (fabs(offset) < Precision::Confusion()) {
// One of the base planes
@ -222,9 +223,120 @@ void fixSketchSupport (Sketcher::SketchObject* sketch)
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
}
}
bool isPartDesignAwareObjecta (App::DocumentObject *obj, bool respectGroups = false ) {
return (obj->isDerivedFrom( PartDesign::Feature::getClassTypeId () ) ||
PartDesign::Body::isAllowed ( obj ) ||
obj->isDerivedFrom ( PartDesign::Body::getClassTypeId () ) ||
( respectGroups && (
obj->isDerivedFrom (App::GeoFeatureGroup::getClassTypeId () ) ||
obj->isDerivedFrom (App::DocumentObjectGroup::getClassTypeId () )
) ) );
}
} /* PartDesignGui */
bool isAnyNonPartDesignLinksTo ( PartDesign::Feature *feature, bool respectGroups ) {
App::Document *doc = feature->getDocument();
for ( const auto & obj: doc->getObjects () ) {
if ( !isPartDesignAwareObjecta ( obj, respectGroups ) ) {
std::vector <App::Property *> properties;
obj->getPropertyList ( properties );
for (auto prop: properties ) {
if ( prop->isDerivedFrom ( App::PropertyLink::getClassTypeId() ) ) {
if ( static_cast <App::PropertyLink *> ( prop )->getValue () == feature ) {
return true;
}
} else if ( prop->isDerivedFrom ( App::PropertyLinkSub::getClassTypeId() ) ) {
if ( static_cast <App::PropertyLinkSub *> ( prop )->getValue () == feature ) {
return true;
}
} else if ( prop->isDerivedFrom ( App::PropertyLinkList::getClassTypeId() ) ) {
auto values = static_cast <App::PropertyLinkList *> ( prop )->getValues ();
if ( std::find ( values.begin (), values.end (), feature ) != values.end() ) {
return true;
}
} else if ( prop->isDerivedFrom ( App::PropertyLinkSubList::getClassTypeId() ) ) {
auto values = static_cast <App::PropertyLinkSubList *> ( prop )->getValues ();
if ( std::find ( values.begin (), values.end (), feature ) != values.end() ) {
return true;
}
}
}
}
}
return false;
}
void relinkToBody (PartDesign::Feature *feature) {
App::Document *doc = feature->getDocument();
PartDesign::Body *body = PartDesign::Body::findBodyOf ( feature );
if (!body) {
throw Base::Exception ("Coudn't find body for the feature");
}
std::string bodyName = body->getNameInDocument ();
for ( const auto & obj: doc->getObjects () ) {
if ( !isPartDesignAwareObjecta ( obj ) ) {
std::vector <App::Property *> properties;
obj->getPropertyList ( properties );
for (auto prop: properties ) {
std::string valueStr;
if ( prop->isDerivedFrom ( App::PropertyLink::getClassTypeId() ) ) {
App::PropertyLink *propLink = static_cast <App::PropertyLink *> ( prop );
if ( propLink->getValue() != feature ) {
continue;
}
valueStr = std::string ( "App.activeDocument()." ).append ( bodyName );
} else if ( prop->isDerivedFrom ( App::PropertyLinkSub::getClassTypeId() ) ) {
App::PropertyLinkSub *propLink = static_cast <App::PropertyLinkSub *> ( prop );
if ( propLink->getValue() != feature ) {
continue;
}
valueStr = buildLinkSubPythonStr ( body, propLink->getSubValues() );
} else if ( prop->isDerivedFrom ( App::PropertyLinkList::getClassTypeId() ) ) {
App::PropertyLinkList *propLink = static_cast <App::PropertyLinkList *> ( prop );
std::vector <App::DocumentObject *> linkList = propLink->getValues ();
bool valueChanged=false;
for (auto & link : linkList ) {
if ( link == feature ) {
link = body;
valueChanged = true;
}
}
if ( valueChanged ) {
valueStr = buildLinkListPythonStr ( linkList );
// TODO Issue some message here due to it likely will break something
// (2015-08-13, Fat-Zer)
}
} else if ( prop->isDerivedFrom ( App::PropertyLinkSub::getClassTypeId() ) ) {
App::PropertyLinkSubList *propLink = static_cast <App::PropertyLinkSubList *> ( prop );
std::vector <App::DocumentObject *> linkList = propLink->getValues ();
bool valueChanged=false;
for (auto & link : linkList ) {
if ( link == feature ) {
link = body;
valueChanged = true;
}
}
if ( valueChanged ) {
valueStr = buildLinkSubListPythonStr ( linkList, propLink->getSubValues() );
// TODO Issue some message here due to it likely will break something
// (2015-08-13, Fat-Zer)
}
}
if ( !valueStr.empty () ) {
Gui::Command::doCommand ( Gui::Command::Doc, "App.activeDocument().%s.%s=%s",
obj->getNameInDocument (), prop->getName (), valueStr.c_str() );
}
}
}
}
}
} /* PartDesignGui */

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com *
* Copyright (C) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@ -28,6 +28,7 @@
*/
namespace PartDesign {
class Body;
class Feature;
}
namespace App {
@ -64,6 +65,15 @@ PartDesign::Body *setUpPart(const App::Part *);
/// Fix sketch support after moving a free sketch into a body
void fixSketchSupport(Sketcher::SketchObject* sketch);
} /* PartDesignGui */
/**
* Returns true if document has any non-PartDesign objects that links to the given object.
* If respectGroups is true don't count links from App::GeoFeatureGroup-derived objects (default is false)
*/
bool isAnyNonPartDesignLinksTo ( PartDesign::Feature *feature, bool respectGroups=false );
/// Relink all nonPartDesign features to the body instead of the given partDesign Feature
void relinkToBody ( PartDesign::Feature *feature );
} /* PartDesignGui */
#endif /* end of include guard: UTILS_H_CS5LK2ZQ */

View File

@ -65,153 +65,6 @@ Workbench::~Workbench() {
WorkflowManager::destruct();
}
// 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)
{
if (doc == NULL) return;

View File

@ -78,7 +78,6 @@ private:
// Add new objects to the body, if appropriate
//void slotNewObject(const App::DocumentObject& obj);
//void _doMigration(const App::Document* doc);
void _switchToDocument(const App::Document* doc);
};

View File

@ -72,10 +72,11 @@ WorkflowManager::~WorkflowManager() {
// Those destruction/construction is not really needed and could be done in the instance()
// but to make things a bit more cleare better to keep them around.
void WorkflowManager::init() {
if (_instance) {
throw Base::Exception( "Trying to init the workflow manager second time." );
if (!_instance) {
_instance = new WorkflowManager();
} else {
//throw Base::Exception( "Trying to init the workflow manager second time." );
}
_instance = new WorkflowManager();
}
WorkflowManager *WorkflowManager::instance() {
@ -135,7 +136,6 @@ Workflow WorkflowManager::determinWorkflow( App::Document *doc) {
// Guess the workflow again
rv = guessWorkflow (doc);
if (rv != Workflow::Modern) {
QMessageBox msgBox;
@ -156,7 +156,7 @@ Workflow WorkflowManager::determinWorkflow( App::Document *doc) {
"If you refuse to migrate you won't be able to use new PartDesign features"
" like Bodies and Parts. As a result you also won't be able to use your parts"
" in the assembly workbench.\n"
"Although you will be able to migrate any moment later with 'Part Design->Migrate'." ) );
"Although you will be able to migrate any moment later with 'Part Design->Migrate...'." ) );
msgBox.setIcon( QMessageBox::Question );
QPushButton * yesBtn = msgBox.addButton ( QMessageBox::Yes );
QPushButton * manuallyBtn = msgBox.addButton (
@ -171,7 +171,6 @@ Workflow WorkflowManager::determinWorkflow( App::Document *doc) {
msgBox.exec();
if ( msgBox.clickedButton() == yesBtn ) {
// TODO Assure that this will actually work (2015-08-02, Fat-Zer)
Gui::Application::Instance->commandManager().runCommandByName("PartDesign_Migrate");
rv = Workflow::Modern;
} else if ( msgBox.clickedButton() == manuallyBtn ) {
@ -183,6 +182,7 @@ Workflow WorkflowManager::determinWorkflow( App::Document *doc) {
// Actually set the result in our map
dwMap[ doc ] = rv;
return rv;
}

View File

@ -69,7 +69,6 @@ public:
/**
* Force the desired workflow in document
* Note: currently added for testing purpose; May be removed later
*/
void forceWorkflow (const App::Document *doc, Workflow wf);