Skip to content

Commit

Permalink
PD MoveFeature:Check if feature has dependencies in source body
Browse files Browse the repository at this point in the history
  • Loading branch information
usakhelo authored and wwmayer committed Aug 24, 2016
1 parent dcd9420 commit f49ddae
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 24 deletions.
14 changes: 13 additions & 1 deletion src/Mod/PartDesign/Gui/CommandBody.cpp
Expand Up @@ -587,8 +587,17 @@ void CmdPartDesignMoveFeature::activated(int iMsg)
std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
if (features.empty()) return;

// Check if all features are valid to move
if (std::any_of(std::begin(features), std::end(features), [](App::DocumentObject* obj){return !PartDesignGui::isFeatureMovable(obj); }))
{
//show messagebox and cancel
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Features cannot be moved"),
QObject::tr("Some of the selected features has dependencies in the source body"));
return;
}

// Collect dependenies of the selected features
std::vector<App::DocumentObject*> dependencies = PartDesignGui::collectDependencies(features);
std::vector<App::DocumentObject*> dependencies = PartDesignGui::collectMovableDependencies(features);
if (!dependencies.empty())
features.insert(std::end(features), std::begin(dependencies), std::end(dependencies));

Expand Down Expand Up @@ -665,6 +674,9 @@ void CmdPartDesignMoveFeature::activated(int iMsg)
arg( QString::fromLatin1( sketch->Label.getValue () ) ) );
}
}

//relink origin for sketches and datums (coordinates)
PartDesignGui::relinkToOrigin(feat, target);
}

updateActive();
Expand Down
100 changes: 79 additions & 21 deletions src/Mod/PartDesign/Gui/Utils.cpp
Expand Up @@ -346,21 +346,71 @@ void relinkToBody (PartDesign::Feature *feature) {
}
}

std::vector<App::DocumentObject*> collectDependencies(std::vector<App::DocumentObject*>& features)
bool isFeatureMovable(App::DocumentObject* const feat)
{
if (feat->getTypeId().isDerivedFrom(PartDesign::Feature::getClassTypeId())) {
auto prim = static_cast<PartDesign::Feature*>(feat);
App::DocumentObject* bf = prim->BaseFeature.getValue();
if (bf)
return false;
}

if (feat->getTypeId().isDerivedFrom(PartDesign::FeaturePrimitive::getClassTypeId())) {
auto prim = static_cast<PartDesign::FeaturePrimitive*>(feat);

if (!isFeatureMovable(prim->CoordinateSystem.getValue()))
return false;
}

if (feat->getTypeId().isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) {
auto prim = static_cast<PartDesign::ProfileBased*>(feat);
auto sk = prim->getVerifiedSketch(true);

if (!isFeatureMovable(static_cast<App::DocumentObject*>(sk)))
return false;

if (auto prop = static_cast<App::PropertyLinkList*>(prim->getPropertyByName("Sections"))) {
if (std::any_of(prop->getValues().begin(), prop->getValues().end(), [](App::DocumentObject* obj){return !isFeatureMovable(obj); }))
return false;
}

if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("ReferenceAxis"))) {
App::DocumentObject* axis = prop->getValue();
if (!isFeatureMovable(static_cast<App::DocumentObject*>(axis)))
return false;
}

if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("Spine"))) {
App::DocumentObject* axis = prop->getValue();
if (!isFeatureMovable(static_cast<App::DocumentObject*>(axis)))
return false;
}

if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
App::DocumentObject* axis = prop->getValue();
if (!isFeatureMovable(static_cast<App::DocumentObject*>(axis)))
return false;
}

}

if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId()) ||
feat->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
auto attachable = static_cast<Part::AttachableObject*>(feat);
App::DocumentObject* support = attachable->Support.getValue();
if (!support || !support->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()))
return false;
}

return true;
}

std::vector<App::DocumentObject*> collectMovableDependencies(std::vector<App::DocumentObject*>& features)
{
std::set<App::DocumentObject*> unique_objs;

for (auto const &feat : features)
{
// Get support of the sketch
if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
//not sure if support feature should be moved
//Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(feat);
//App::DocumentObject* support = sketch->Support.getValue();
//if (support)
// temp.push_back(support);
}

// Get coordinate system object
if (feat->getTypeId().isDerivedFrom(PartDesign::FeaturePrimitive::getClassTypeId())) {
auto prim = static_cast<PartDesign::FeaturePrimitive*>(feat);
Expand All @@ -369,7 +419,7 @@ std::vector<App::DocumentObject*> collectDependencies(std::vector<App::DocumentO
unique_objs.insert(cs);
}

// Get parts from profile based features
// Get sketches and datums from profile based features
if (feat->getTypeId().isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) {
auto prim = static_cast<PartDesign::ProfileBased*>(feat);
Part::Part2DObject* sk = prim->getVerifiedSketch(true);
Expand All @@ -395,26 +445,34 @@ std::vector<App::DocumentObject*> collectDependencies(std::vector<App::DocumentO
}
if (auto prop = static_cast<App::PropertyLinkSub*>(prim->getPropertyByName("AuxillerySpine"))) {
App::DocumentObject* axis = prop->getValue();
if (axis && !PartDesign::Feature::isDatum(axis)){
if (axis && !axis->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId())){
unique_objs.insert(axis);
}
}
}

if (feat->getTypeId().isDerivedFrom(PartDesign::Boolean::getClassTypeId())) {
auto boolobj = static_cast<PartDesign::Boolean*>(feat);
for (App::DocumentObject* obj : boolobj->Bodies.getValues()) {
unique_objs.insert(boolobj);
}
}
}

std::vector<App::DocumentObject*> result;
result.reserve(unique_objs.size());
for (std::set<App::DocumentObject*>::iterator it = unique_objs.begin(); it != unique_objs.end(); ++it)
result.push_back(*it);
result.insert(result.begin(), unique_objs.begin(), unique_objs.end());

return result;
}

void relinkToOrigin(App::DocumentObject* feat, PartDesign::Body* targetbody)
{
if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId()) ||
feat->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
auto attachable = static_cast<Part::AttachableObject*>(feat);
App::DocumentObject* support = attachable->Support.getValue();
if (support && support->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId())) {
auto originfeat = static_cast<App::OriginFeature*>(support);
App::OriginFeature* targetOriginFeature = targetbody->getOrigin()->getOriginFeature(originfeat->Role.getValue());
if (targetOriginFeature) {
attachable->Support.setValue(static_cast<App::DocumentObject*>(targetOriginFeature), "");
}
}
}
}

} /* PartDesignGui */
8 changes: 6 additions & 2 deletions src/Mod/PartDesign/Gui/Utils.h
Expand Up @@ -64,8 +64,12 @@ bool isAnyNonPartDesignLinksTo ( PartDesign::Feature *feature, bool respectGroup
/// Relink all nonPartDesign features to the body instead of the given partDesign Feature
void relinkToBody ( PartDesign::Feature *feature );

/// Collect all needed dependencies of the features during the move from one body to another
std::vector<App::DocumentObject*> collectDependencies(std::vector<App::DocumentObject*>& features);
/// Check if feature is dependent on anything except movable sketches and datums
bool isFeatureMovable(App::DocumentObject* feature);
/// Collect dependencies of the features during the move. Dependecies should only be dependent on origin
std::vector<App::DocumentObject*> collectMovableDependencies(std::vector<App::DocumentObject*>& features);
/// Relink sketches and datums to target body's origin
void relinkToOrigin(App::DocumentObject* feature, PartDesign::Body* body);

} /* PartDesignGui */

Expand Down

0 comments on commit f49ddae

Please sign in to comment.