예제 #1
0
/**
 *  Constructs a VisualInspection as a child of 'parent', with the
 *  name 'name' and widget flags set to 'f'.
 */
VisualInspection::VisualInspection(QWidget* parent, Qt::WindowFlags fl)
    : QDialog(parent, fl), ui(new Ui_VisualInspection)
{
    ui->setupUi(this);
    connect(ui->treeWidgetActual, SIGNAL(itemClicked(QTreeWidgetItem*, int)), 
            this, SLOT(onActivateItem(QTreeWidgetItem*)));
    connect(ui->treeWidgetNominal, SIGNAL(itemClicked(QTreeWidgetItem*, int)), 
            this, SLOT(onActivateItem(QTreeWidgetItem*)));
    connect(ui->buttonBox, SIGNAL(helpRequested()),
            Gui::getMainWindow(), SLOT(whatsThis()));

    //FIXME: Not used yet
    ui->textLabel2->hide();
    ui->thickness->hide();
    ui->searchRadius->setUnit(Base::Unit::Length);
    ui->searchRadius->setRange(0, DBL_MAX);
    ui->thickness->setUnit(Base::Unit::Length);
    ui->thickness->setRange(0, DBL_MAX);

    App::Document* doc = App::GetApplication().getActiveDocument();
    // disable Ok button and enable of at least one item in each view is on
    buttonOk = ui->buttonBox->button(QDialogButtonBox::Ok);
    buttonOk->setDisabled(true);

    if (!doc) {
        ui->treeWidgetActual->setDisabled(true);
        ui->treeWidgetNominal->setDisabled(true);
        return;
    }

    Gui::Document* gui = Gui::Application::Instance->getDocument(doc);

    std::vector<App::DocumentObject*> obj = doc->getObjects();
    Base::Type point = Base::Type::fromName("Points::Feature");
    Base::Type mesh  = Base::Type::fromName("Mesh::Feature");
    Base::Type shape = Base::Type::fromName("Part::Feature");
    for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) {
        if ((*it)->getTypeId().isDerivedFrom(point) ||
            (*it)->getTypeId().isDerivedFrom(mesh)  ||
            (*it)->getTypeId().isDerivedFrom(shape)) {
            Gui::ViewProvider* view = gui->getViewProvider(*it);
            QIcon px = view->getIcon();
            SingleSelectionItem* item1 = new SingleSelectionItem(ui->treeWidgetActual);
            item1->setText(0, QString::fromUtf8((*it)->Label.getValue()));
            item1->setData(0, Qt::UserRole, QString::fromLatin1((*it)->getNameInDocument()));
            item1->setCheckState(0, Qt::Unchecked);
            item1->setIcon(0, px);

            SingleSelectionItem* item2 = new SingleSelectionItem(ui->treeWidgetNominal);
            item2->setText(0, QString::fromUtf8((*it)->Label.getValue()));
            item2->setData(0, Qt::UserRole, QString::fromLatin1((*it)->getNameInDocument()));
            item2->setCheckState(0, Qt::Unchecked);
            item2->setIcon(0, px);

            item1->setCompetitiveItem(item2);
            item2->setCompetitiveItem(item1);
        }
    }

    loadSettings();
}
예제 #2
0
bool Mirroring::accept()
{
    if (ui->shapes->selectedItems().isEmpty()) {
        QMessageBox::critical(this, windowTitle(),
            tr("Select a shape for mirroring, first."));
        return false;
    }

    App::Document* activeDoc = App::GetApplication().getDocument((const char*)this->document.toLatin1());
    if (!activeDoc) {
        QMessageBox::critical(this, windowTitle(),
            tr("No such document '%1'.").arg(this->document));
        return false;
    }

    Gui::WaitCursor wc;
    unsigned int count = activeDoc->countObjectsOfType(Base::Type::fromName("Part::Mirroring"));
    activeDoc->openTransaction("Mirroring");

    QString shape, label;
    QRegExp rx(QString::fromLatin1(" \\(Mirror #\\d+\\)$"));
    QList<QTreeWidgetItem *> items = ui->shapes->selectedItems();
    float normx=0, normy=0, normz=0;
    int index = ui->comboBox->currentIndex();
    if (index == 0)
        normz = 1.0f;
    else if (index == 1)
        normy = 1.0f;
    else
        normx = 1.0f;
    double basex = ui->baseX->value();
    double basey = ui->baseY->value();
    double basez = ui->baseZ->value();
    for (QList<QTreeWidgetItem *>::iterator it = items.begin(); it != items.end(); ++it) {
        shape = (*it)->data(0, Qt::UserRole).toString();
        label = (*it)->text(0);

        // if we already have the suffix " (Mirror #<number>)" remove it
        int pos = label.indexOf(rx);
        if (pos > -1)
            label = label.left(pos);
        label.append(QString::fromLatin1(" (Mirror #%1)").arg(++count));

        QString code = QString::fromLatin1(
            "__doc__=FreeCAD.getDocument(\"%1\")\n"
            "__doc__.addObject(\"Part::Mirroring\")\n"
            "__doc__.ActiveObject.Source=__doc__.getObject(\"%2\")\n"
            "__doc__.ActiveObject.Label=\"%3\"\n"
            "__doc__.ActiveObject.Normal=(%4,%5,%6)\n"
            "__doc__.ActiveObject.Base=(%7,%8,%9)\n"
            "del __doc__")
            .arg(this->document).arg(shape).arg(label)
            .arg(normx).arg(normy).arg(normz)
            .arg(basex).arg(basey).arg(basez);
        Gui::Application::Instance->runPythonCode((const char*)code.toLatin1());
        QByteArray from = shape.toLatin1();
        Gui::Command::copyVisual("ActiveObject", "ShapeColor", from);
        Gui::Command::copyVisual("ActiveObject", "LineColor", from);
        Gui::Command::copyVisual("ActiveObject", "PointColor", from);
    }

    activeDoc->commitTransaction();
    activeDoc->recompute();
    return true;
}
예제 #3
0
bool Tessellation::accept()
{
    if (ui->treeWidget->selectedItems().isEmpty()) {
        QMessageBox::critical(this, windowTitle(),
            tr("Select a shape for meshing, first."));
        return false;
    }

    App::Document* activeDoc = App::GetApplication().getDocument((const char*)this->document.toLatin1());
    if (!activeDoc) {
        QMessageBox::critical(this, windowTitle(),
            tr("No such document '%1'.").arg(this->document));
        return false;
    }

    try {
        QString shape, label;
        Gui::WaitCursor wc;

        int method = buttonGroup->checkedId();

        activeDoc->openTransaction("Meshing");
        QList<QTreeWidgetItem *> items = ui->treeWidget->selectedItems();
        std::vector<Part::Feature*> shapes = Gui::Selection().getObjectsOfType<Part::Feature>();
        for (QList<QTreeWidgetItem *>::iterator it = items.begin(); it != items.end(); ++it) {
            shape = (*it)->data(0, Qt::UserRole).toString();
            label = (*it)->text(0);

            QString cmd;
            if (method == 0) { // Standard
                double devFace = ui->spinSurfaceDeviation->value().getValue();
                cmd = QString::fromLatin1(
                    "__doc__=FreeCAD.getDocument(\"%1\")\n"
                    "__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
                    "__mesh__.Mesh=Mesh.Mesh(__doc__.getObject(\"%2\").Shape.tessellate(%3))\n"
                    "__mesh__.Label=\"%4 (Meshed)\"\n"
                    "__mesh__.ViewObject.CreaseAngle=25.0\n"
                    "del __doc__, __mesh__\n")
                    .arg(this->document)
                    .arg(shape)
                    .arg(devFace)
                    .arg(label);
            }
            else if (method == 1) { // Mefisto
                double maxEdge = ui->spinMaximumEdgeLength->value().getValue();
                if (!ui->spinMaximumEdgeLength->isEnabled())
                    maxEdge = 0;
                cmd = QString::fromLatin1(
                    "__doc__=FreeCAD.getDocument(\"%1\")\n"
                    "__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
                    "__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,MaxLength=%3)\n"
                    "__mesh__.Label=\"%4 (Meshed)\"\n"
                    "__mesh__.ViewObject.CreaseAngle=25.0\n"
                    "del __doc__, __mesh__\n")
                    .arg(this->document)
                    .arg(shape)
                    .arg(maxEdge)
                    .arg(label);
            }
            else if (method == 2) { // Netgen
                int fineness = ui->comboFineness->currentIndex();
                double growthRate = ui->doubleGrading->value();
                double nbSegPerEdge = ui->spinEdgeElements->value();
                double nbSegPerRadius = ui->spinCurvatureElements->value();
                bool secondOrder = ui->checkSecondOrder->isChecked();
                bool optimize = ui->checkOptimizeSurface->isChecked();
                bool allowquad = ui->checkQuadDominated->isChecked();
                if (fineness < 5) {
                    cmd = QString::fromLatin1(
                        "__doc__=FreeCAD.getDocument(\"%1\")\n"
                        "__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
                        "__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,"
                        "Fineness=%3,SecondOrder=%4,Optimize=%5,AllowQuad=%6)\n"
                        "__mesh__.Label=\"%7 (Meshed)\"\n"
                        "__mesh__.ViewObject.CreaseAngle=25.0\n"
                        "del __doc__, __mesh__\n")
                        .arg(this->document)
                        .arg(shape)
                        .arg(fineness)
                        .arg(secondOrder ? 1 : 0)
                        .arg(optimize ? 1 : 0)
                        .arg(allowquad ? 1 : 0)
                        .arg(label);
                }
                else {
                    cmd = QString::fromLatin1(
                        "__doc__=FreeCAD.getDocument(\"%1\")\n"
                        "__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
                        "__mesh__.Mesh=MeshPart.meshFromShape(Shape=__doc__.getObject(\"%2\").Shape,"
                        "GrowthRate=%3,SegPerEdge=%4,SegPerRadius=%5,SecondOrder=%6,Optimize=%7,AllowQuad=%8)\n"
                        "__mesh__.Label=\"%9 (Meshed)\"\n"
                        "__mesh__.ViewObject.CreaseAngle=25.0\n"
                        "del __doc__, __mesh__\n")
                        .arg(this->document)
                        .arg(shape)
                        .arg(growthRate)
                        .arg(nbSegPerEdge)
                        .arg(nbSegPerRadius)
                        .arg(secondOrder ? 1 : 0)
                        .arg(optimize ? 1 : 0)
                        .arg(allowquad ? 1 : 0)
                        .arg(label);
                }
            }
            Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toUtf8());
        }
        activeDoc->commitTransaction();
    }
    catch (const Base::Exception& e) {
        Base::Console().Error(e.what());
    }

    return true;
}
예제 #4
0
bool DlgFilletEdges::accept()
{
    if (!d->object) {
        QMessageBox::warning(this, tr("No shape selected"),
            tr("No valid shape is selected.\n"
               "Please select a valid shape in the drop-down box first."));
        return false;
    }
    App::Document* activeDoc = App::GetApplication().getActiveDocument();
    QAbstractItemModel* model = ui->treeView->model();
    bool end_radius = !ui->treeView->isColumnHidden(2);
    bool todo = false;

    QString shape, type, name;
    std::string fillet = getFilletType();
    int index = ui->shapeObject->currentIndex();
    shape = ui->shapeObject->itemData(index).toString();
    type = QString::fromAscii("Part::%1").arg(QString::fromAscii(fillet.c_str()));

    if (d->fillet)
        name = QString::fromAscii(d->fillet->getNameInDocument());
    else
        name = QString::fromAscii(activeDoc->getUniqueObjectName(fillet.c_str()).c_str());

    activeDoc->openTransaction(fillet.c_str());
    QString code;
    if (!d->fillet) {
        code = QString::fromAscii(
        "FreeCAD.ActiveDocument.addObject(\"%1\",\"%2\")\n"
        "FreeCAD.ActiveDocument.%2.Base = FreeCAD.ActiveDocument.%3\n")
        .arg(type).arg(name).arg(shape);
    }
    code += QString::fromAscii("__fillets__ = []\n");
    for (int i=0; i<model->rowCount(); ++i) {
        QVariant value = model->index(i,0).data(Qt::CheckStateRole);
        Qt::CheckState checkState = static_cast<Qt::CheckState>(value.toInt());

        // is item checked
        if (checkState & Qt::Checked) {
            // the index value of the edge
            int id = model->index(i,0).data(Qt::UserRole).toInt();
            double r1 = model->index(i,1).data().toDouble();
            double r2 = r1;
            if (end_radius)
                r2 = model->index(i,2).data().toDouble();
            code += QString::fromAscii(
                "__fillets__.append((%1,%2,%3))\n")
                .arg(id).arg(r1,0,'f',2).arg(r2,0,'f',2);
            todo = true;
        }
    }

    if (!todo) {
        QMessageBox::warning(this, tr("No edge selected"),
            tr("No edge entity is checked to fillet.\n"
               "Please check one or more edge entities first."));
        return false;
    }

    Gui::WaitCursor wc;
    code += QString::fromAscii(
        "FreeCAD.ActiveDocument.%1.Edges = __fillets__\n"
        "del __fillets__\n"
        "FreeCADGui.ActiveDocument.%2.Visibility = False\n")
        .arg(name).arg(shape);
    Gui::Application::Instance->runPythonCode((const char*)code.toAscii());
    activeDoc->commitTransaction();
    activeDoc->recompute();
    if (d->fillet) {
        Gui::ViewProvider* vp;
        vp = Gui::Application::Instance->getViewProvider(d->fillet);
        if (vp) vp->show();
    }

    QByteArray to = name.toAscii();
    QByteArray from = shape.toAscii();
    Gui::Command::copyVisual(to, "ShapeColor", from);
    Gui::Command::copyVisual(to, "LineColor", from);
    Gui::Command::copyVisual(to, "PointColor", from);
    return true;
}
/**
 * Builds a mesh solid from the currently active solid type.
 */
void MeshGui::DlgRegularSolidImp::on_createSolidButton_clicked()
{
    try {
        Gui::WaitCursor wc;
        QString cmd; std::string name;
        App::Document* doc = App::GetApplication().getActiveDocument();
        if (!doc) {
            QMessageBox::warning(this, tr("Create %1").arg(comboBox1->currentText()), tr("No active document"));
            return;
        }
        if (comboBox1->currentIndex() == 0) {         // cube
            name = doc->getUniqueObjectName("Cube");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Cube\",\"%1\")\n"
                "App.ActiveDocument.%1.Length=%2\n"
                "App.ActiveDocument.%1.Width=%3\n"
                "App.ActiveDocument.%1.Height=%4\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(boxLength->value(),0,'f',2)
                .arg(boxWidth->value(),0,'f',2)
                .arg(boxHeight->value(),0,'f',2);
        }
        else if (comboBox1->currentIndex() == 1) {  // cylinder
            name = doc->getUniqueObjectName("Cylinder");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Cylinder\",\"%1\")\n"
                "App.ActiveDocument.%1.Radius=%2\n"
                "App.ActiveDocument.%1.Length=%3\n"
                "App.ActiveDocument.%1.EdgeLength=%4\n"
                "App.ActiveDocument.%1.Closed=%5\n"
                "App.ActiveDocument.%1.Sampling=%6\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(cylinderRadius->value(),0,'f',2)
                .arg(cylinderLength->value(),0,'f',2)
                .arg(cylinderEdgeLength->value(),0,'f',2)
                .arg(QLatin1String((cylinderClosed->isChecked()?"True":"False")))
                .arg(cylinderCount->value());
        }
        else if (comboBox1->currentIndex() == 2) {  // cone
            name = doc->getUniqueObjectName("Cone");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Cone\",\"%1\")\n"
                "App.ActiveDocument.%1.Radius1=%2\n"
                "App.ActiveDocument.%1.Radius2=%3\n"
                "App.ActiveDocument.%1.Length=%4\n"
                "App.ActiveDocument.%1.EdgeLength=%5\n"
                "App.ActiveDocument.%1.Closed=%6\n"
                "App.ActiveDocument.%1.Sampling=%7\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(coneRadius1->value(),0,'f',2)
                .arg(coneRadius2->value(),0,'f',2)
                .arg(coneLength->value(),0,'f',2)
                .arg(coneEdgeLength->value(),0,'f',2)
                .arg(QLatin1String((coneClosed->isChecked()?"True":"False")))
                .arg(coneCount->value());
        }
        else if (comboBox1->currentIndex() == 3) {  // sphere
            name = doc->getUniqueObjectName("Sphere");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Sphere\",\"%1\")\n"
                "App.ActiveDocument.%1.Radius=%2\n"
                "App.ActiveDocument.%1.Sampling=%3\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(sphereRadius->value(),0,'f',2)
                .arg(sphereCount->value());
        }
        else if (comboBox1->currentIndex() == 4) {  // ellipsoid
            name = doc->getUniqueObjectName("Ellipsoid");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Ellipsoid\",\"%1\")\n"
                "App.ActiveDocument.%1.Radius1=%2\n"
                "App.ActiveDocument.%1.Radius2=%3\n"
                "App.ActiveDocument.%1.Sampling=%4\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(ellipsoidRadius1->value(),0,'f',2)
                .arg(ellipsoidRadius2->value(),0,'f',2)
                .arg(ellipsoidCount->value());
        }
        else if (comboBox1->currentIndex() == 5) {  // toroid
            name = doc->getUniqueObjectName("Torus");
            cmd = QString(QLatin1String(
                "App.ActiveDocument.addObject(\"Mesh::Torus\",\"%1\")\n"
                "App.ActiveDocument.%1.Radius1=%2\n"
                "App.ActiveDocument.%1.Radius2=%3\n"
                "App.ActiveDocument.%1.Sampling=%4\n"))
                .arg(QLatin1String(name.c_str()))
                .arg(toroidRadius1->value(),0,'f',2)
                .arg(toroidRadius2->value(),0,'f',2)
                .arg(toroidCount->value());
        }

        // Execute the Python block
        QString solid = tr("Create %1").arg(comboBox1->currentText());
        Gui::Application::Instance->activeDocument()->openCommand(solid.toUtf8());
        Gui::Command::doCommand(Gui::Command::Doc, (const char*)cmd.toAscii());
        Gui::Application::Instance->activeDocument()->commitCommand();
        Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().recompute()");
        Gui::Command::doCommand(Gui::Command::Gui, "Gui.SendMsgToActiveView(\"ViewFit\")");
    }
    catch (const Base::PyException& e) {
        QMessageBox::warning(this, tr("Create %1").arg(comboBox1->currentText()),
            QString::fromLatin1(e.what()));
    }
}
예제 #6
0
bool SelectionSingleton::setPreselect(const char* pDocName, const char* pObjectName, const char* pSubName, float x, float y, float z)
{
    static char buf[513];

    if (DocName != "")
        rmvPreselect();

    if (ActiveGate) {
        App::Document* pDoc = getDocument(pDocName);
        if (pDoc) {
            if (pObjectName) {
                App::DocumentObject* pObject = pDoc->getObject(pObjectName);
                if (!ActiveGate->allow(pDoc,pObject,pSubName)) {
                    QString msg;
                    if (ActiveGate->notAllowedReason.length() > 0){
                        msg = QObject::tr(ActiveGate->notAllowedReason.c_str());
                    } else {
                        msg = QCoreApplication::translate("SelectionFilter","Not allowed:");
                    }
                    msg.append(
                                QObject::tr(" %1.%2.%3 ")
                               .arg(QString::fromLatin1(pDocName))
                               .arg(QString::fromLatin1(pObjectName))
                               .arg(QString::fromLatin1(pSubName))
                                );

                    if (getMainWindow()) {
                        getMainWindow()->showMessage(msg,3000);
                        Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
                        mdi->setOverrideCursor(QCursor(Qt::ForbiddenCursor));
                    }
                    return false;
                }

            }
            else
                return ActiveGate->allow(pDoc,0,0);
        }
        else
            return false;

    }

    DocName = pDocName;
    FeatName= pObjectName;
    SubName = pSubName;
    hx = x;
    hy = y;
    hz = z;

    // set up the change object
    SelectionChanges Chng;
    Chng.pDocName  = DocName.c_str();
    Chng.pObjectName = FeatName.c_str();
    Chng.pSubName  = SubName.c_str();
    Chng.x = x;
    Chng.y = y;
    Chng.z = z;
    Chng.Type = SelectionChanges::SetPreselect;

    // set the current preselection
    CurrentPreselection = Chng;

    snprintf(buf,512,"Preselected: %s.%s.%s (%f,%f,%f)",Chng.pDocName
                                                       ,Chng.pObjectName
                                                       ,Chng.pSubName
                                                       ,x,y,z);

    //FIXME: We shouldn't replace the possibly defined edit cursor
    //with the arrow cursor. But it seems that we don't even have to.
    //if (getMainWindow()){
    //    getMainWindow()->showMessage(QString::fromLatin1(buf),3000);
    //    Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
    //    mdi->restoreOverrideCursor();
    //}

    Notify(Chng);
    signalSelectionChanged(Chng);

    //Base::Console().Log("Sel : Add preselect %s \n",pObjectName);

    // allows the preselection
    return true;
}
예제 #7
0
static PyObject * importer(PyObject *self, PyObject *args)
{
    char* Name;
    char* DocName=0;
    if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
        return 0;

    PY_TRY {
        //Base::Console().Log("Insert in Part with %s",Name);
        Base::FileInfo file(Name);

        App::Document *pcDoc = 0;
        if (DocName) {
            pcDoc = App::GetApplication().getDocument(DocName);
        }
        if (!pcDoc) {
            pcDoc = App::GetApplication().newDocument("Unnamed");
        }

        Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
        Handle(TDocStd_Document) hDoc;
        hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);

        if (file.hasExtension("stp") || file.hasExtension("step")) {
            try {
                STEPCAFControl_Reader aReader;
                aReader.SetColorMode(true);
                aReader.SetNameMode(true);
                aReader.SetLayerMode(true);
                if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) {
                    PyErr_SetString(PyExc_Exception, "cannot read STEP file");
                    return 0;
                }

                Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100);
                aReader.Reader().WS()->MapReader()->SetProgress(pi);
                pi->NewScope(100, "Reading STEP file...");
                pi->Show();
                aReader.Transfer(hDoc);
                pi->EndScope();
            }
            catch (OSD_Exception) {
                Handle_Standard_Failure e = Standard_Failure::Caught();
                Base::Console().Error("%s\n", e->GetMessageString());
                Base::Console().Message("Try to load STEP file without colors...\n");

                Part::ImportStepParts(pcDoc,Name);
                pcDoc->recompute();
            }
        }
        else if (file.hasExtension("igs") || file.hasExtension("iges")) {
            try {
                IGESControl_Controller::Init();
                Interface_Static::SetIVal("read.surfacecurve.mode",3);
                IGESCAFControl_Reader aReader;
                aReader.SetColorMode(true);
                aReader.SetNameMode(true);
                aReader.SetLayerMode(true);
                if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) {
                    PyErr_SetString(PyExc_Exception, "cannot read IGES file");
                    return 0;
                }

                Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100);
                aReader.WS()->MapReader()->SetProgress(pi);
                pi->NewScope(100, "Reading IGES file...");
                pi->Show();
                aReader.Transfer(hDoc);
                pi->EndScope();
            }
            catch (OSD_Exception) {
                Handle_Standard_Failure e = Standard_Failure::Caught();
                Base::Console().Error("%s\n", e->GetMessageString());
                Base::Console().Message("Try to load IGES file without colors...\n");

                Part::ImportIgesParts(pcDoc,Name);
                pcDoc->recompute();
            }
        }
        else {
            PyErr_SetString(PyExc_Exception, "no supported file format");
            return 0;
        }

#if 1
        Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure());
        ocaf.loadShapes();
#else
        Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure());
        xcaf.loadShapes();
#endif
        pcDoc->recompute();

    }
    catch (Standard_Failure) {
PyObject* Application::sExport(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
    PyObject* object;
    char* Name;
    if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name))
        return NULL;
    std::string Utf8Name = std::string(Name);
    PyMem_Free(Name);

    PY_TRY {
        App::Document* doc = 0;
        Py::Sequence list(object);
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
            PyObject* item = (*it).ptr();
            if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
                App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
                doc = obj->getDocument();
                break;
            }
        }

        // get the view that belongs to the found document
        if (doc) {
            QString fileName = QString::fromUtf8(Utf8Name.c_str());
            QFileInfo fi;
            fi.setFile(fileName);
            QString ext = fi.completeSuffix().toLower();
            if (ext == QLatin1String("iv") || ext == QLatin1String("wrl") ||
                ext == QLatin1String("vrml") || ext == QLatin1String("wrz") ||
                ext == QLatin1String("svg") || ext == QLatin1String("idtf")) {
                Gui::Document* gui_doc = Application::Instance->getDocument(doc);
                std::list<MDIView*> view3d = gui_doc->getMDIViewsOfType(View3DInventor::getClassTypeId());
                if (view3d.empty()) {
                    PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot export to SVG because document doesn't have a 3d view");
                    return 0;
                }
                else {
                    QString cmd = QString::fromLatin1(
                        "Gui.getDocument(\"%1\").mdiViewsOfType('Gui::View3DInventor')[0].dump(\"%2\")"
                        ).arg(QLatin1String(doc->getName())).arg(fi.absoluteFilePath());
                    Base::Interpreter().runString(cmd.toUtf8());
                }
            }
            else if (ext == QLatin1String("pdf")) {
                Gui::Document* gui_doc = Application::Instance->getDocument(doc);
                if (gui_doc) {
                    Gui::MDIView* view = gui_doc->getActiveView();
                    if (view) {
                        View3DInventor* view3d = qobject_cast<View3DInventor*>(view);
                        if (view3d)
                            view3d->viewAll();
                        QPrinter printer(QPrinter::ScreenResolution);
                        printer.setOutputFormat(QPrinter::PdfFormat);
                        printer.setOutputFileName(fileName);
                        view->print(&printer);
                    }
                }
            }
        }
    } PY_CATCH;

    Py_Return;
}
예제 #9
0
PyObject* Application::sInsert(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
    char* Name;
    char* DocName=0;
    if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName))
        return NULL;
    std::string Utf8Name = std::string(Name);
    PyMem_Free(Name);

    PY_TRY {
        QString fileName = QString::fromUtf8(Utf8Name.c_str());
        QFileInfo fi;
        fi.setFile(fileName);
        QString ext = fi.suffix().toLower();
        if (ext == QLatin1String("iv")) {
            App::Document *doc = 0;
            if (DocName)
                doc = App::GetApplication().getDocument(DocName);
            else
                doc = App::GetApplication().getActiveDocument();
            if (!doc)
                doc = App::GetApplication().newDocument(DocName);

            App::DocumentObject* obj = doc->addObject("App::InventorObject",
                (const char*)fi.baseName().toUtf8());
            obj->Label.setValue((const char*)fi.baseName().toUtf8());
            static_cast<App::PropertyString*>(obj->getPropertyByName("FileName"))
                ->setValue((const char*)fi.absoluteFilePath().toUtf8());
            doc->recompute();
        }
        else if (ext == QLatin1String("wrl") ||
                 ext == QLatin1String("vrml") ||
                 ext == QLatin1String("wrz")) {
            App::Document *doc = 0;
            if (DocName)
                doc = App::GetApplication().getDocument(DocName);
            else
                doc = App::GetApplication().getActiveDocument();
            if (!doc)
                doc = App::GetApplication().newDocument(DocName);

            // Add this to the search path in order to read inline files (#0002029)
            QByteArray path = fi.absolutePath().toUtf8();
            SoInput::addDirectoryFirst(path.constData());

            App::DocumentObject* obj = doc->addObject("App::VRMLObject",
                (const char*)fi.baseName().toUtf8());
            obj->Label.setValue((const char*)fi.baseName().toUtf8());
            static_cast<App::PropertyFileIncluded*>(obj->getPropertyByName("VrmlFile"))
                ->setValue((const char*)fi.absoluteFilePath().toUtf8());
            doc->recompute();

            SoInput::removeDirectory(path.constData());
        }
        else if (ext == QLatin1String("py") || ext == QLatin1String("fcmacro") ||
                 ext == QLatin1String("fcscript")) {
            PythonEditor* editor = new PythonEditor();
            editor->setWindowIcon(Gui::BitmapFactory().iconFromTheme("applications-python"));
            PythonEditorView* edit = new PythonEditorView(editor, getMainWindow());
            edit->open(fileName);
            edit->resize(400, 300);
            getMainWindow()->addWindow( edit );
        }
        else {
            Base::Console().Error("File type '%s' not supported\n", ext.toLatin1().constData());
        }
    } PY_CATCH;

    Py_Return;
}
    Py::Object open(const Py::Tuple& args)
    {
        char* Name;
        if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
            throw Py::Exception();
        std::string EncodedName = std::string(Name);
        PyMem_Free(Name);
        Base::FileInfo fi(EncodedName);
        if (!fi.exists())
            throw Py::RuntimeError("File not found");

        Gui::WaitCursor wc;
        wc.restoreCursor();

        try {
            std::string path = App::GetApplication().getHomePath();
            path += "Mod/Path/PathScripts/";
            QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_pre.py"));
            std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro")
                ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str());
            QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_pre.py"));
            QFileInfoList list = dir1.entryInfoList();
            list << dir2.entryInfoList();
            std::vector<std::string> scripts;
            for (int i = 0; i < list.size(); ++i) {
                QFileInfo fileInfo = list.at(i);
                scripts.push_back(fileInfo.baseName().toStdString());
            }
            std::string processor;
            PathGui::DlgProcessorChooser Dlg(scripts);
            if (Dlg.exec() != QDialog::Accepted) {
                return Py::None();
            }
            processor = Dlg.getProcessor();

            std::ostringstream pre;
            std::ostringstream cmd;
            if (processor.empty()) {
                App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
                Gui::Command::runCommand(Gui::Command::Gui,"import Path");
                cmd << "Path.read(\"" << EncodedName << "\",\"" << pcDoc->getName() << "\")";
                Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str());
            } else {
                for (int i = 0; i < list.size(); ++i) {
                    QFileInfo fileInfo = list.at(i);
                    if (fileInfo.baseName().toStdString() == processor) {
                        if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) {
                            pre << "from PathScripts import " << processor;
                        } else {
                            pre << "import " << processor;
                        }
                        Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str());
                        cmd << processor << ".open(\"" << EncodedName << "\")";
                        Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str());
                    }
                }
            }
        }
        catch (const Base::Exception& e) {
            throw Py::RuntimeError(e.what());
        }

        return Py::None();
    }
예제 #11
0
PyObject* Application::sInsert(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/)
{
    char* Name;
    char* DocName=0;
    if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName))
        return NULL;
    std::string Utf8Name = std::string(Name);
    PyMem_Free(Name);

    PY_TRY {
        QString fileName = QString::fromUtf8(Utf8Name.c_str());
        QFileInfo fi;
        fi.setFile(fileName);
        QString ext = fi.completeSuffix().toLower();
        if (ext == QLatin1String("iv")) {
            App::Document *doc = 0;
            if (DocName)
                doc = App::GetApplication().getDocument(DocName);
            else
                doc = App::GetApplication().getActiveDocument();
            if (!doc)
                doc = App::GetApplication().newDocument(DocName);

            App::DocumentObject* obj = doc->addObject("App::InventorObject",
                (const char*)fi.baseName().toUtf8());
            obj->Label.setValue((const char*)fi.baseName().toUtf8());
            static_cast<App::PropertyString*>(obj->getPropertyByName("FileName"))
                ->setValue((const char*)fi.absoluteFilePath().toUtf8());
            doc->recompute();
        }
        else if (ext == QLatin1String("wrl") ||
                 ext == QLatin1String("vrml") ||
                 ext == QLatin1String("wrz")) {
            App::Document *doc = 0;
            if (DocName)
                doc = App::GetApplication().getDocument(DocName);
            else
                doc = App::GetApplication().getActiveDocument();
            if (!doc)
                doc = App::GetApplication().newDocument(DocName);

            App::DocumentObject* obj = doc->addObject("App::VRMLObject",
                (const char*)fi.baseName().toUtf8());
            obj->Label.setValue((const char*)fi.baseName().toUtf8());
            static_cast<App::PropertyFileIncluded*>(obj->getPropertyByName("VrmlFile"))
                ->setValue((const char*)fi.absoluteFilePath().toUtf8());
            doc->recompute();
        }
        else if (ext == QLatin1String("py") || ext == QLatin1String("fcmacro") ||
                 ext == QLatin1String("fcscript")) {
            PythonEditor* editor = new PythonEditor();
            editor->setWindowIcon(Gui::BitmapFactory().pixmap("applications-python"));
            PythonEditorView* edit = new PythonEditorView(editor, getMainWindow());
            edit->open(fileName);
            edit->resize(400, 300);
            getMainWindow()->addWindow( edit );
        }
    } PY_CATCH;

    Py_Return;
}
    Py::Object exporter(const Py::Tuple& args)
    {
        PyObject* object;
        char* Name;
        if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name))
            throw Py::Exception();

        std::string EncodedName = std::string(Name);
        PyMem_Free(Name);
        Gui::WaitCursor wc;
        wc.restoreCursor();

        try {
            Py::Sequence objlist(object);
            if (objlist.size() == 0)
                throw Py::RuntimeError("No object to export");

            std::string path = App::GetApplication().getHomePath();
            path += "Mod/Path/PathScripts/";
            QDir dir1(QString::fromUtf8(path.c_str()), QString::fromLatin1("*_post.py"));
            std::string cMacroPath = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Macro")
                ->GetASCII("MacroPath",App::Application::getUserMacroDir().c_str());
            QDir dir2(QString::fromUtf8(cMacroPath.c_str()), QString::fromLatin1("*_post.py"));
            QFileInfoList list = dir1.entryInfoList();
            list << dir2.entryInfoList();
            std::vector<std::string> scripts;
            for (int i = 0; i < list.size(); ++i) {
                QFileInfo fileInfo = list.at(i);
                scripts.push_back(fileInfo.baseName().toStdString());
            }
            PathGui::DlgProcessorChooser Dlg(scripts, true);
            if (Dlg.exec() != QDialog::Accepted) {
                return Py::None();
            }
            std::string processor = Dlg.getProcessor();
            std::string arguments = Dlg.getArguments();

            std::ostringstream pre;
            std::ostringstream cmd;
            if (processor.empty()) {
                if (objlist.size() > 1) {
                    throw Py::RuntimeError("Cannot export more than one object without using a post script");
                }
                PyObject* item = objlist[0].ptr();
                if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
                    App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
                    App::Document* doc = obj->getDocument();
                    Gui::Command::runCommand(Gui::Command::Gui,"import Path");
                    cmd << "Path.write(FreeCAD.getDocument(\"" << doc->getName() << "\").getObject(\"" << obj->getNameInDocument() << "\"),\"" << EncodedName << "\")";
                    Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str());
                } else {
                    return Py::None();
                }
            } else {
                for (int i = 0; i < list.size(); ++i) {
                    QFileInfo fileInfo = list.at(i);
                    if (fileInfo.baseName().toStdString() == processor) {
                        if (fileInfo.absoluteFilePath().contains(QString::fromLatin1("PathScripts"))) {
                            pre << "from PathScripts import " << processor;
                        } else {
                            pre << "import " << processor;
                        }
                        Gui::Command::runCommand(Gui::Command::Gui,pre.str().c_str());
                        cmd << processor << ".export(__objs__,\"" << EncodedName << "\",\"" << arguments << "\")";
                        Gui::Command::runCommand(Gui::Command::Gui,cmd.str().c_str());
                    }
                }
            }
        }
        catch (const Base::Exception& e) {
            throw Py::RuntimeError(e.what());
        }

        return Py::None();
    }
예제 #13
0
bool TaskWatcherCommandsEmptyDoc::shouldShow()
{
    App::Document* doc = App::GetApplication().getActiveDocument();
    return doc && doc->countObjects() == 0;
}
예제 #14
0
    Py::Object open(const Py::Tuple& args)
    {
        char* Name;
        if (!PyArg_ParseTuple(args.ptr(), "et","utf-8",&Name))
            throw Py::Exception();
        std::string EncodedName = std::string(Name);
        PyMem_Free(Name);

        try {
            Base::Console().Log("Open in Points with %s",EncodedName.c_str());
            Base::FileInfo file(EncodedName.c_str());

            // extract ending
            if (file.extension().empty())
                throw Py::RuntimeError("No file extension");

            if (file.hasExtension("asc")) {
                // create new document and add Import feature
                App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
                Points::Feature *pcFeature = (Points::Feature *)pcDoc->addObject("Points::Feature", file.fileNamePure().c_str());
                Points::PointKernel pkTemp;
                pkTemp.load(EncodedName.c_str());
                pcFeature->Points.setValue( pkTemp );

            }
#ifdef HAVE_PCL_IO
            else if (file.hasExtension("ply")) {
                PlyReader reader;
                reader.read(EncodedName);

                App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
                if (reader.hasProperties()) {
                    Points::FeatureCustom *pcFeature = new Points::FeatureCustom();
                    pcFeature->Points.setValue(reader.getPoints());
                    // add gray values
                    if (reader.hasIntensities()) {
                        Points::PropertyGreyValueList* prop = static_cast<Points::PropertyGreyValueList*>
                            (pcFeature->addDynamicProperty("Points::PropertyGreyValueList", "Intensity"));
                        if (prop) {
                            prop->setValues(reader.getIntensities());
                        }
                    }
                    // add colors
                    if (reader.hasColors()) {
                        App::PropertyColorList* prop = static_cast<App::PropertyColorList*>
                            (pcFeature->addDynamicProperty("App::PropertyColorList", "Color"));
                        if (prop) {
                            prop->setValues(reader.getColors());
                        }
                    }
                    // add normals
                    if (reader.hasNormals()) {
                        Points::PropertyNormalList* prop = static_cast<Points::PropertyNormalList*>
                            (pcFeature->addDynamicProperty("Points::PropertyNormalList", "Normal"));
                        if (prop) {
                            prop->setValues(reader.getNormals());
                        }
                    }

                    // delayed adding of the points feature
                    pcDoc->addObject(pcFeature, file.fileNamePure().c_str());
                    pcDoc->recomputeFeature(pcFeature);
                }
                else {
                    Points::Feature *pcFeature = static_cast<Points::Feature*>
                        (pcDoc->addObject("Points::Feature", file.fileNamePure().c_str()));
                    pcFeature->Points.setValue(reader.getPoints());
                    pcDoc->recomputeFeature(pcFeature);
                }
            }
#endif
            else {
                throw Py::RuntimeError("Unsupported file extension");
            }
        }
        catch (const Base::Exception& e) {
            throw Py::RuntimeError(e.what());
        }

        return Py::None();
    }
예제 #15
0
void CmdSketcherMirrorSketch::activated(int iMsg)
{
    std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx(0, Sketcher::SketchObject::getClassTypeId());
    if (selection.size() < 1) {
        QMessageBox::warning(Gui::getMainWindow(),
            qApp->translate("CmdSketcherMirrorSketch", "Wrong selection"),
            qApp->translate("CmdSketcherMirrorSketch", "Select one or more sketches, please."));
        return;
    }
    
    // Ask the user which kind of mirroring he wants
    SketchMirrorDialog * smd = new SketchMirrorDialog();
    
    int refgeoid=-1;
    Sketcher::PointPos refposid=Sketcher::none;
    
    if( smd->exec() == QDialog::Accepted ){
        refgeoid=smd->RefGeoid;
        refposid=smd->RefPosid;
        
        delete smd;
    }
    else {
        delete smd;
        return;
    }
    
    App::Document* doc = App::GetApplication().getActiveDocument();
    
    openCommand("Create a mirror Sketch for each sketch");
    
    for (std::vector<Gui::SelectionObject>::const_iterator it=selection.begin(); it != selection.end(); ++it) {
        // create Sketch 
        std::string FeatName = getUniqueObjectName("MirroredSketch");
        
        doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str());
        
        Sketcher::SketchObject* mirrorsketch = static_cast<Sketcher::SketchObject*>(doc->getObject(FeatName.c_str()));       
        
        const Sketcher::SketchObject* Obj = static_cast<const Sketcher::SketchObject*>((*it).getObject());
        
        Base::Placement pl = Obj->Placement.getValue();
        
        Base::Vector3d p = pl.getPosition();
        Base::Rotation r = pl.getRotation();
        
        doCommand(Doc,"App.activeDocument().%s.Placement = App.Placement(App.Vector(%f,%f,%f),App.Rotation(%f,%f,%f,%f))",
                  FeatName.c_str(),
                  p.x,p.y,p.z,r[0],r[1],r[2],r[3]);
        
        Sketcher::SketchObject* tempsketch = new Sketcher::SketchObject();
        
        int addedGeometries=tempsketch->addGeometry(Obj->getInternalGeometry());
        
        int addedConstraints=tempsketch->addConstraints(Obj->Constraints.getValues());

        std::vector<int> geoIdList;
        
        for(int i=0;i<=addedGeometries;i++)
            geoIdList.push_back(i);
        
        tempsketch->addSymmetric(geoIdList, refgeoid, refposid);
                
        std::vector<Part::Geometry *> tempgeo = tempsketch->getInternalGeometry();
        std::vector<Sketcher::Constraint *> tempconstr = tempsketch->Constraints.getValues();

        std::vector<Part::Geometry *> mirrorgeo (tempgeo.begin()+addedGeometries+1,tempgeo.end());
        std::vector<Sketcher::Constraint *> mirrorconstr (tempconstr.begin()+addedConstraints+1,tempconstr.end());
        
        for(std::vector<Sketcher::Constraint *>::const_iterator itc=mirrorconstr.begin(); itc != mirrorconstr.end(); ++itc) {
 
            if((*itc)->First!=Sketcher::Constraint::GeoUndef || (*itc)->First==-1 || (*itc)->First==-2) // not x, y axes or origin
                (*itc)->First-=(addedGeometries+1);
            if((*itc)->Second!=Sketcher::Constraint::GeoUndef || (*itc)->Second==-1 || (*itc)->Second==-2) // not x, y axes or origin
                (*itc)->Second-=(addedGeometries+1);
            if((*itc)->Third!=Sketcher::Constraint::GeoUndef || (*itc)->Third==-1 || (*itc)->Third==-2) // not x, y axes or origin
                (*itc)->Third-=(addedGeometries+1);
        }
        
        mirrorsketch->addGeometry(mirrorgeo);
        mirrorsketch->addConstraints(mirrorconstr);
        
        delete tempsketch;
    }
    
    doCommand(Gui,"App.activeDocument().recompute()");
    
}
예제 #16
0
void CmdSketcherMapSketch::activated(int iMsg)
{
    QString msg_str;
    try{
        Attacher::eMapMode suggMapMode;
        std::vector<Attacher::eMapMode> validModes;

        //check that selection is valid for at least some mapping mode.
        Attacher::SuggestResult::eSuggestResult msgid = Attacher::SuggestResult::srOK;
        suggMapMode = SuggestAutoMapMode(&msgid, &msg_str, &validModes);

        App::Document* doc = App::GetApplication().getActiveDocument();
        std::vector<App::DocumentObject*> sketches = doc->getObjectsOfType(Part::Part2DObject::getClassTypeId());
        if (sketches.empty()) {
            QMessageBox::warning(Gui::getMainWindow(),
                qApp->translate(className(), "No sketch found"),
                qApp->translate(className(), "The document doesn't have a sketch"));
            return;
        }

        bool ok;
        QStringList items;
        for (std::vector<App::DocumentObject*>::iterator it = sketches.begin(); it != sketches.end(); ++it)
            items.push_back(QString::fromUtf8((*it)->Label.getValue()));
        QString text = QInputDialog::getItem(Gui::getMainWindow(),
            qApp->translate(className(), "Select sketch"),
            qApp->translate(className(), "Select a sketch from the list"),
            items, 0, false, &ok);
        if (!ok) return;
        int index = items.indexOf(text);
        Part2DObject &sketch = *(static_cast<Part2DObject*>(sketches[index]));


        // check circular dependency
        std::vector<Gui::SelectionObject> selobjs = Gui::Selection().getSelectionEx();
        for (size_t i = 0  ;  i < selobjs.size()  ;  ++i){
            App::DocumentObject* part = static_cast<Part::Feature*>(selobjs[i].getObject());
            if (!part) {
                assert(0);
                throw Base::Exception("Unexpected null pointer in CmdSketcherMapSketch::activated");
            }
            std::vector<App::DocumentObject*> input = part->getOutList();
            if (std::find(input.begin(), input.end(), &sketch) != input.end()) {
                throw ExceptionWrongInput(QT_TR_NOOP("Some of the selected objects depend on the sketch to be mapped. Circular dependencies are not allowed!"));
            }
        }

        //Ask for a new mode.
        //outline:
        // * find out the modes that are compatible with selection.
        // * Test if current mode is OK.
        // * fill in the dialog
        // * execute the dialog
        // * collect dialog result
        // * action

        bool bAttach = true;
        bool bCurIncompatible = false;
        // * find out the modes that are compatible with selection.
        eMapMode curMapMode = eMapMode(sketch.MapMode.getValue());
        // * Test if current mode is OK.
        if (std::find(validModes.begin(), validModes.end(), curMapMode) == validModes.end())
            bCurIncompatible = true;

        // * fill in the dialog
        validModes.insert(validModes.begin(), Attacher::mmDeactivated);
        if(bCurIncompatible)
            validModes.push_back(curMapMode);
        //bool ok; //already defined
        //QStringList items; //already defined
        items.clear();
        items.push_back(QObject::tr("Don't attach"));
        int iSugg = 0;//index of the auto-suggested mode in the list of valid modes
        int iCurr = 0;//index of current mode in the list of valid modes
        for (size_t i = 0  ;  i < validModes.size()  ;  ++i){
            items.push_back(QString::fromLatin1(AttachEngine::getModeName(validModes[i]).c_str()));
            if (validModes[i] == curMapMode) {
                iCurr = items.size() - 1;
                items.back().append(bCurIncompatible?
                                        qApp->translate(className()," (incompatible with selection)")
                                      :
                                        qApp->translate(className()," (current)")  );
            }
            if (validModes[i] == suggMapMode){
                iSugg = items.size() - 1;
                if(iSugg == 1){
                    iSugg = 0;//redirect deactivate to detach
                } else {
                    items.back().append(qApp->translate(className()," (suggested)"));
                }
            }
        }
        // * execute the dialog
        text = QInputDialog::getItem(Gui::getMainWindow()
            ,qApp->translate(className(), "Sketch attachment")
            ,bCurIncompatible?
              qApp->translate(className(), "Current attachment mode is incompatible with the new selection. Select the method to attach this sketch to selected objects.")
              :
              qApp->translate(className(), "Select the method to attach this sketch to selected objects.")
            ,items
            , bCurIncompatible ? iSugg : iCurr
            , false
            , &ok);
        // * collect dialog result
        if (!ok) return;
        index = items.indexOf(text);
        if (index == 0){
            bAttach = false;
            suggMapMode = Attacher::mmDeactivated;
        } else {
            bAttach = true;
            suggMapMode = validModes[index-1];
        }

        // * action
        std::string featName = sketch.getNameInDocument();
        if (bAttach) {
            App::PropertyLinkSubList support;
            Gui::Selection().getAsPropertyLinkSubList(support);
            std::string supportString = support.getPyReprString();

            openCommand("Attach Sketch");
            doCommand(Gui,"App.activeDocument().%s.MapMode = \"%s\"",featName.c_str(),AttachEngine::getModeName(suggMapMode).c_str());
            doCommand(Gui,"App.activeDocument().%s.Support = %s",featName.c_str(),supportString.c_str());
            commitCommand();
        } else {
            openCommand("Detach Sketch");
            doCommand(Gui,"App.activeDocument().%s.MapMode = \"%s\"",featName.c_str(),AttachEngine::getModeName(suggMapMode).c_str());
            doCommand(Gui,"App.activeDocument().%s.Support = None",featName.c_str());
            commitCommand();
        }
    } catch (ExceptionWrongInput &e) {
        QMessageBox::warning(Gui::getMainWindow(),
                             qApp->translate(className(), "Map sketch"),
                             qApp->translate(className(), "Can't map a sketch to support:\n"
                                         "%1").arg(e.ErrMsg.length() ? e.ErrMsg : msg_str));
    }
}