Exemple #1
0
void CmdPartDesignDuplicateSelection::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false);

    std::vector<App::DocumentObject*> beforeFeatures = getDocument()->getObjects();

    openCommand("Duplicate a PartDesign object");
    doCommand(Doc,"FreeCADGui.runCommand('Std_DuplicateSelection')");

    if (pcActiveBody) {
        // Find the features that were added
        std::vector<App::DocumentObject*> afterFeatures = getDocument()->getObjects();
        std::vector<App::DocumentObject*> newFeatures;
        std::sort(beforeFeatures.begin(), beforeFeatures.end());
        std::sort(afterFeatures.begin(), afterFeatures.end());
        std::set_difference(afterFeatures.begin(), afterFeatures.end(), beforeFeatures.begin(), beforeFeatures.end(),
                            std::back_inserter(newFeatures));

        for (auto feature : newFeatures) {
            if (PartDesign::Body::isAllowed(feature)) {
                doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",
                          pcActiveBody->getNameInDocument(), feature->getNameInDocument());
                doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", feature->getNameInDocument());
            }
        }

        // Adjust visibility of features
        doCommand(Gui,"Gui.activeDocument().show(\"%s\")", newFeatures.back()->getNameInDocument());
    }

    updateActive();
}
Exemple #2
0
void CmdPartDesignMoveFeatureInTree::activated(int iMsg)
{
    Q_UNUSED(iMsg);
    std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId());
    if (features.empty()) return;

    PartDesign::Body *body = PartDesignGui::getBodyFor ( features.front(), false );
    App::DocumentObject * bodyBase = nullptr;
    // sanity check
    bool allFeaturesFromSameBody = true;

    if ( body ) {
        bodyBase= body->BaseFeature.getValue();
        for ( auto feat: features ) {
            if ( !body->hasObject ( feat ) ) {
                allFeaturesFromSameBody = false;
                break;
            }
            if ( bodyBase== feat) {
                QMessageBox::warning (0, QObject::tr( "Selection error" ),
                        QObject::tr( "Impossible to move the base feature of a body." ) );
                return;
            }
        }
    }
    if (!body || ! allFeaturesFromSameBody) {
        QMessageBox::warning (0, QObject::tr( "Selection error" ),
                QObject::tr( "Select one or more features from the same body." ) );
        return;
    }

    // Create a list of all features in this body
    const std::vector<App::DocumentObject*> & model = body->Group.getValues();

    // Ask user to select the target feature
    bool ok;
    QStringList items;
    if ( bodyBase ) {
        items.push_back( QString::fromUtf8 ( bodyBase->Label.getValue () ) );
    } else {
        items.push_back( QObject::tr( "Beginning of the body" ) );
    }
    for ( auto feat: model ) {
        items.push_back( QString::fromUtf8 ( feat->Label.getValue() ) );
    }

    QString text = QInputDialog::getItem(Gui::getMainWindow(),
        qApp->translate("PartDesign_MoveFeatureInTree", "Select feature"),
        qApp->translate("PartDesign_MoveFeatureInTree", "Select a feature from the list"),
        items, 0, false, &ok);
    if (!ok) return;
    int index = items.indexOf(text);
    // first object is the beginning of the body
    App::DocumentObject* target = index != 0 ? model[index-1] : nullptr;

    openCommand("Move an object inside tree");

    for ( auto feat: features ) {
        if ( feat == target ) continue;

        std::string targetStr;
        if (target) {
            targetStr.append("App.activeDocument().").append(target->getNameInDocument());
        } else {
            targetStr = "None";
        }

        // Remove and re-insert the feature to/from the Body
        // TODO if tip was moved the new position of tip is quite undetermined (2015-08-07, Fat-Zer)
        // TODO warn the user if we are moving an object to some place before the object's link (2015-08-07, Fat-Zer)
        doCommand ( Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)",
                body->getNameInDocument(), feat->getNameInDocument() );
        doCommand ( Doc, "App.activeDocument().%s.insertObject(App.activeDocument().%s, %s, True)",
                body->getNameInDocument(), feat->getNameInDocument(), targetStr.c_str () );
    }

    updateActive();
}
Exemple #3
0
void CmdPartDesignMoveFeature::activated(int iMsg)
{
    Q_UNUSED(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 have dependencies in the source body"));
        return;
    }

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

    // Create a list of all bodies in this part
    std::vector<App::DocumentObject*> bodies = getDocument()->getObjectsOfType(Part::BodyBase::getClassTypeId());

    std::set<App::DocumentObject*> source_bodies;
    for (auto feat : features) {
        PartDesign::Body* source = PartDesign::Body::findBodyOf(feat);
        source_bodies.insert(static_cast<App::DocumentObject*>(source));
    }

    std::vector<App::DocumentObject*> target_bodies;
    for (auto body : bodies) {
        if (!source_bodies.count(body))
            target_bodies.push_back(body);
    }

    if (target_bodies.empty())
    {
        QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Features cannot be moved"),
            QObject::tr("There are no other bodies to move to"));
        return;
    }

    // Ask user to select the target body (remove source bodies from list)
    bool ok;
    QStringList items;
    for (auto body : target_bodies) {
        items.push_back(QString::fromUtf8(body->Label.getValue()));
    }
    QString text = QInputDialog::getItem(Gui::getMainWindow(),
        qApp->translate("PartDesign_MoveFeature", "Select body"),
        qApp->translate("PartDesign_MoveFeature", "Select a body from the list"),
        items, 0, false, &ok);
    if (!ok) return;
    int index = items.indexOf(text);
    if (index < 0) return;

    PartDesign::Body* target = static_cast<PartDesign::Body*>(target_bodies[index]);

    openCommand("Move an object");

    for (auto feat: features) {
        // Find body of this feature
        Part::BodyBase* source = PartDesign::Body::findBodyOf(feat);
        bool featureWasTip = false;

        if (source == target) continue;

        // Remove from the source body if the feature belonged to a body
        if (source) {
            featureWasTip = (source->Tip.getValue() == feat);
            doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)",
                      source->getNameInDocument(), (feat)->getNameInDocument());
        }

        App::DocumentObject* targetOldTip = target->Tip.getValue();

        // Add to target body (always at the Tip)
        doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)",
                      target->getNameInDocument(), (feat)->getNameInDocument());
        // Recompute to update the shape
        doCommand(Gui,"App.activeDocument().recompute()");

        // Adjust visibility of features
        // TODO: May be something can be done in view provider (2015-08-05, Fat-Zer)
        // If we removed the tip of the source body, make the new tip visible
        if ( featureWasTip ) {
            App::DocumentObject * sourceNewTip = source->Tip.getValue();
            if (sourceNewTip)
                doCommand(Gui,"Gui.activeDocument().show(\"%s\")", sourceNewTip->getNameInDocument());
        }

        // Hide old tip and show new tip (the moved feature) of the target body
        App::DocumentObject* targetNewTip = target->Tip.getValue();
        if ( targetOldTip != targetNewTip ) {
            if ( targetOldTip ) {
                doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", targetOldTip->getNameInDocument());
            }
            if (targetNewTip) {
                doCommand(Gui,"Gui.activeDocument().show(\"%s\")", targetNewTip->getNameInDocument());
            }
        }

        // Fix sketch support
        if (feat->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
            Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(feat);
            try {
                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.").
                        arg( QString::fromLatin1( sketch->Label.getValue () ) ) );
            }
        }

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

    updateActive();
}