Allow transforming a Pattern feature into a MultiTransform feature

This commit is contained in:
jrheinlaender 2013-08-22 21:08:21 +02:00 committed by Stefan Tröger
parent 5d39df88ee
commit f9b0e5908a
11 changed files with 638 additions and 284 deletions

View File

@ -126,6 +126,21 @@ const Part::TopoShape Body::getTipShape()
return static_cast<Part::Feature*>(link)->Shape.getShape();
}
App::DocumentObject* Body::getPrevFeature(App::DocumentObject *start) const
{
std::vector<App::DocumentObject*> features = Model.getValues();
if (features.empty()) return NULL;
App::DocumentObject* st = (start == NULL ? Tip.getValue() : start);
if (st == NULL)
return st; // Tip is NULL
std::vector<App::DocumentObject*>::iterator it = std::find(features.begin(), features.end(), st);
if (it == features.end()) return NULL; // Invalid start object
it--;
return *it;
}
App::DocumentObject* Body::getPrevSolidFeature(App::DocumentObject *start, const bool inclusive)
{
std::vector<App::DocumentObject*> features = Model.getValues();

View File

@ -58,6 +58,9 @@ public:
/// Get the tip shape
const Part::TopoShape getTipShape();
/// Return the previous feature
App::DocumentObject* getPrevFeature(App::DocumentObject *start = NULL) const;
/**
* Return the solid feature before the given feature, or before the Tip feature
* That is, sketches and datum features are skipped

View File

@ -70,6 +70,8 @@
#include <Mod/PartDesign/App/FeatureSubtractive.h>
#include <Mod/PartDesign/App/FeatureGroove.h>
#include <Mod/PartDesign/App/FeatureRevolution.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/PartDesign/App/DatumPoint.h>
#include <Mod/PartDesign/App/DatumLine.h>
#include <Mod/PartDesign/App/DatumPlane.h>
@ -1741,7 +1743,7 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform()
{
sAppModule = "PartDesign";
sGroup = QT_TR_NOOP("PartDesign");
sMenuText = QT_TR_NOOP("MultiTransform");
sMenuText = QT_TR_NOOP("Create MultiTransform");
sToolTipText = QT_TR_NOOP("Create a multitransform feature");
sWhatsThis = "PartDesign_MultiTransform";
sStatusTip = sToolTipText;
@ -1750,28 +1752,79 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform()
void CmdPartDesignMultiTransform::activated(int iMsg)
{
std::string FeatName, selNames;
std::vector<App::DocumentObject*> features;
std::vector<std::string> selList;
prepareTransformed(this, "MultiTransform", features, FeatName, selList, selNames);
if (features.empty())
return;
PartDesign::Body *pcActiveBody = PartDesignGui::getBody();
if (!pcActiveBody)
return;
updateActive();
doCommand(Doc,selNames.c_str());
if (!pcActiveBody) return;
// Make sure the user isn't presented with an empty screen because no transformations are defined yet...
App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true);
if (prevSolid != NULL) {
Part::Feature* feat = static_cast<Part::Feature*>(prevSolid);
doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape",
FeatName.c_str(), feat->getNameInDocument());
std::vector<App::DocumentObject*> features;
// Check if a Transformed feature has been selected, convert it to MultiTransform
features = getSelection().getObjectsOfType(PartDesign::Transformed::getClassTypeId());
if (!features.empty()) {
// Throw out MultiTransform features, we don't want to nest them
for (std::vector<App::DocumentObject*>::iterator f = features.begin(); f != features.end(); ) {
if ((*f)->getTypeId().isDerivedFrom(PartDesign::MultiTransform::getClassTypeId()))
f = features.erase(f);
else
f++;
}
if (features.empty()) return;
// Note: If multiple Transformed features were selected, only the first one is used
PartDesign::Transformed* trFeat = static_cast<PartDesign::Transformed*>(features.front());
// Move the insert point back one feature
App::DocumentObject* oldTip = pcActiveBody->Tip.getValue();
App::DocumentObject* prevFeature = pcActiveBody->getPrevFeature(trFeat);
Gui::Selection().clearSelection();
if (prevFeature != NULL)
Gui::Selection().addSelection(prevFeature->getDocument()->getName(), prevFeature->getNameInDocument());
openCommand("Convert to MultiTransform feature");
doCommand(Gui, "FreeCADGui.runCommand('PartDesign_MoveTip')");
// Remove the Transformed feature from the Body
doCommand(Doc, "App.activeDocument().%s.removeFeature(App.activeDocument().%s)",
pcActiveBody->getNameInDocument(), trFeat->getNameInDocument());
// Create a MultiTransform feature and move the Transformed feature inside it
std::string FeatName = getUniqueObjectName("MultiTransform");
doCommand(Doc, "App.activeDocument().addObject(\"PartDesign::MultiTransform\",\"%s\")", FeatName.c_str());
doCommand(Doc, "App.activeDocument().%s.Originals = App.activeDocument().%s.Originals", FeatName.c_str(), trFeat->getNameInDocument());
doCommand(Doc, "App.activeDocument().%s.Originals = []", trFeat->getNameInDocument());
doCommand(Doc, "App.activeDocument().%s.Transformations = [App.activeDocument().%s]", FeatName.c_str(), trFeat->getNameInDocument());
// Add the MultiTransform into the Body at the current insert point
finishFeature(this, FeatName);
// Restore the insert point
if (oldTip != trFeat) {
Gui::Selection().clearSelection();
Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
Gui::Selection().clearSelection();
} // otherwise the insert point remains at the new MultiTransform, which is fine
} else {
std::string FeatName, selNames;
std::vector<std::string> selList;
prepareTransformed(this, "MultiTransform", features, FeatName, selList, selNames);
if (features.empty())
return;
PartDesign::Body *pcActiveBody = PartDesignGui::getBody();
if (!pcActiveBody)
return;
updateActive();
doCommand(Doc,selNames.c_str());
// Make sure the user isn't presented with an empty screen because no transformations are defined yet...
App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true);
if (prevSolid != NULL) {
Part::Feature* feat = static_cast<Part::Feature*>(prevSolid);
doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape",
FeatName.c_str(), feat->getNameInDocument());
}
finishFeature(this, FeatName);
}
finishFeature(this, FeatName);
}
bool CmdPartDesignMultiTransform::isActive(void)

File diff suppressed because it is too large Load Diff

View File

@ -338,7 +338,7 @@ void TaskLinearPatternParameters::onDirectionChanged(int num) {
else if (num == ui->comboDirection->count() - 1) {
// enter reference selection mode
hideObject();
showOriginals();
showBase();
referenceSelectionMode = true;
Gui::Selection().clearSelection();
addReferenceSelectionGate(true, true);

View File

@ -264,7 +264,7 @@ void TaskMirroredParameters::onPlaneChanged(int num) {
else if (num == ui->comboPlane->count() - 1) {
// enter reference selection mode
hideObject();
showOriginals();
showBase();
referenceSelectionMode = true;
Gui::Selection().clearSelection();
addReferenceSelectionGate(false, true);

View File

@ -291,7 +291,7 @@ void TaskMultiTransformParameters::finishAdd(std::string &newFeatName)
if (row < 0) {
// Happens when first row (first transformation) is created
// Hide all the originals now (hiding them in Command.cpp presents the user with an empty screen!)
hideOriginals();
hideBase();
}
// Insert new transformation after the selected row

View File

@ -274,7 +274,7 @@ void TaskPolarPatternParameters::onAxisChanged(int num) {
else if (num == ui->comboAxis->count() - 1) {
// enter reference selection mode
hideObject();
showOriginals();
showBase();
referenceSelectionMode = true;
Gui::Selection().clearSelection();
addReferenceSelectionGate(true, false);

View File

@ -194,23 +194,35 @@ void TaskTransformedParameters::showObject()
}
}
void TaskTransformedParameters::hideOriginals()
void TaskTransformedParameters::hideBase()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc) {
std::vector<App::DocumentObject*> originals = getOriginals();
for (std::vector<App::DocumentObject*>::iterator it = originals.begin(); it != originals.end(); ++it)
doc->setHide((*it)->getNameInDocument());
PartDesign::Body* pcActiveBody = PartDesignGui::getBody();
if (doc && pcActiveBody) {
App::DocumentObject* prevFeature;
if (insideMultiTransform) {
prevFeature = pcActiveBody->getPrevSolidFeature(parentTask->TransformedView->getObject(), false);
} else {
prevFeature = pcActiveBody->getPrevSolidFeature(TransformedView->getObject(), false);
}
doc->setHide(prevFeature->getNameInDocument());
}
}
void TaskTransformedParameters::showOriginals()
void TaskTransformedParameters::showBase()
{
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (doc) {
std::vector<App::DocumentObject*> originals = getOriginals();
for (std::vector<App::DocumentObject*>::iterator it = originals.begin(); it != originals.end(); ++it)
doc->setShow((*it)->getNameInDocument());
PartDesign::Body* pcActiveBody = PartDesignGui::getBody();
if (doc && pcActiveBody) {
App::DocumentObject* prevFeature;
if (insideMultiTransform) {
prevFeature = pcActiveBody->getPrevSolidFeature(parentTask->TransformedView->getObject(), false);
} else {
prevFeature = pcActiveBody->getPrevSolidFeature(TransformedView->getObject(), false);
}
doc->setShow(prevFeature->getNameInDocument());
}
}
@ -220,7 +232,7 @@ void TaskTransformedParameters::exitSelectionMode()
referenceSelectionMode = false;
Gui::Selection().rmvSelectionGate();
showObject();
hideOriginals();
hideBase();
}
void TaskTransformedParameters::addReferenceSelectionGate(bool edge, bool face)

View File

@ -83,8 +83,8 @@ protected:
void hideObject();
void showObject();
void hideOriginals();
void showOriginals();
void hideBase();
void showBase();
void addReferenceSelectionGate(bool edge, bool face);

View File

@ -388,9 +388,15 @@ void Workbench::setupContextMenu(const char* recipient, Gui::MenuItem* item) con
Gui::Selection().countObjectsOfType(PartDesign::Feature::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Datum::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Part2DObject::getClassTypeId()) > 0 )
*item << "PartDesign_MoveTip"
<< "PartDesign_MoveFeature"
*item << "PartDesign_MoveTip";
if (Gui::Selection().countObjectsOfType(PartDesign::Feature::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Datum::getClassTypeId()) +
Gui::Selection().countObjectsOfType(Part::Part2DObject::getClassTypeId()) > 0 )
*item << "PartDesign_MoveFeature"
<< "PartDesign_MoveFeatureInTree";
if (Gui::Selection().countObjectsOfType(PartDesign::Transformed::getClassTypeId()) -
Gui::Selection().countObjectsOfType(PartDesign::MultiTransform::getClassTypeId()) == 1 )
*item << "PartDesign_MultiTransform";
}
}