Esempio n. 1
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();
}
bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName)
{
    // TODO review this function (2015-09-04, Fat-Zer)
    PartDesign::Body *body;
    App::DocumentObject* originGroupObject = nullptr;

    if ( support ) {
        body = PartDesign::Body::findBodyOf (support);
    } else {
        body = PartDesignGui::getBody (false);
    }

    if ( body ) { // Search for Part of the body
        originGroupObject = App::OriginGroupExtension::getGroupOfObject ( body ) ;
    } else if ( support ) { // if no body search part for support
        originGroupObject = App::OriginGroupExtension::getGroupOfObject ( support ) ;
    } else { // fallback to active part
        originGroupObject = PartDesignGui::getActivePart ( );
    }
    
    App::OriginGroupExtension* originGroup = nullptr;
    if(originGroupObject)
        originGroup = originGroupObject->getExtensionByType<App::OriginGroupExtension>();

    // Don't allow selection in other document
    if ( support && pDoc != support->getDocument() ) {
        return false;
    }

    // Enable selection from origin of current part/
    if ( pObj->getTypeId().isDerivedFrom(App::OriginFeature::getClassTypeId()) ) {
        bool fits = false;
        if ( plane && pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ) {
            fits = true;
        } else if ( edge && pObj->getTypeId().isDerivedFrom(App::Line::getClassTypeId()) ) {
            fits = true;
        }

        if (fits) { // check that it is actually belongs to the chosen body or part
            try { // here are some throwers
                if (body) {
                    if (body->getOrigin ()->hasObject (pObj) ) {
                        return true;
                    }
                } else if (originGroup ) {
                    if ( originGroup->getOrigin ()->hasObject (pObj) ) {
                        return true;
                    }
                }
            } catch (const Base::Exception)
            { }
        }
        return false; // The Plane/Axis doesn't fits our needs
    }

    if (pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {

        if (!body) { // Allow selecting Part::Datum features from the active Body
            return false;
        } else if (!allowOtherBody && !body->hasObject(pObj)) {
            return false;
        }

        if (plane && (pObj->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())))
            return true;
        if (edge && (pObj->getTypeId().isDerivedFrom(PartDesign::Line::getClassTypeId())))
            return true;
        if (point && (pObj->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())))
            return true;

        return false;
    }

    // Handle selection of geometry elements
    if (!sSubName || sSubName[0] == '\0')
        return false;
    if (!allowOtherBody) {
        if (support == NULL)
            return false;
        if (pObj != support)
            return false;
    }
    std::string subName(sSubName);
    if (edge && subName.size() > 4 && subName.substr(0,4) == "Edge") {
        const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue();
        TopoDS_Shape sh = shape.getSubShape(subName.c_str());
        const TopoDS_Edge& edge = TopoDS::Edge(sh);
        if (!edge.IsNull()) {
            if (planar) {
                BRepAdaptor_Curve adapt(edge);
                if (adapt.GetType() == GeomAbs_Line)
                    return true;
            } else {
                return true;
            }
        }
    }
    if (plane && subName.size() > 4 && subName.substr(0,4) == "Face") {
        const Part::TopoShape &shape = static_cast<const Part::Feature*>(pObj)->Shape.getValue();
        TopoDS_Shape sh = shape.getSubShape(subName.c_str());
        const TopoDS_Face& face = TopoDS::Face(sh);
        if (!face.IsNull()) {
            if (planar) {
                BRepAdaptor_Surface adapt(face);
                if (adapt.GetType() == GeomAbs_Plane)
                    return true;
            } else {
                return true;
            }
        }
    }
    if (point && subName.size() > 6 && subName.substr(0,6) == "Vertex") {
        return true;
    }
    return false;
}