/*************************************************************************** * Copyright (c) 2013 Jan Rheinländer * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include #endif #include "TaskSketchBasedParameters.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ReferenceSelection.h" #include "Workbench.h" using namespace PartDesignGui; using namespace Gui; /* TRANSLATOR PartDesignGui::TaskSketchBasedParameters */ TaskSketchBasedParameters::TaskSketchBasedParameters(PartDesignGui::ViewProvider *vp, QWidget *parent, const std::string& pixmapname, const QString& parname) : TaskBox(Gui::BitmapFactory().pixmap(pixmapname.c_str()),parname,true, parent), vp(vp), blockUpdate(false) { } const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChanges& msg) { // Note: The validity checking has already been done in ReferenceSelection.cpp PartDesign::SketchBased* pcSketchBased = static_cast(vp->getObject()); App::DocumentObject* selObj = pcSketchBased->getDocument()->getObject(msg.pObjectName); if (selObj == pcSketchBased) return QString::fromAscii(""); std::string subname = msg.pSubName; QString refStr; // Remove subname for planes and datum features if (PartDesign::Feature::isDatum(selObj)) { subname = ""; refStr = QString::fromAscii(selObj->getNameInDocument()); } else { int faceId = std::atoi(&subname[4]); refStr = QString::fromAscii(selObj->getNameInDocument()) + QString::fromAscii(":") + QObject::tr("Face") + QString::number(faceId); } std::vector upToFaces(1,subname); pcSketchBased->UpToFace.setValue(selObj, upToFaces); recomputeFeature(); return refStr; } void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar) { // Note: Even if there is no solid, App::Plane and Part::Datum can still be selected PartDesign::SketchBased* pcSketchBased = static_cast(vp->getObject()); PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); App::DocumentObject* curSolid = 0;//the last solid of the body, the one that is likely visible, but can't be used for up-to-face if (activeBody) curSolid = activeBody->getPrevSolidFeature(); else curSolid = pcSketchBased; App::DocumentObject* prevSolid = 0;//the solid this feature will be fused to try { prevSolid = pcSketchBased->getBaseObject(); } catch (Base::Exception) { //this feature is a starting feature } if (pressed) { Gui::Document* doc = Gui::Application::Instance->activeDocument(); if (doc) { if (curSolid) doc->setHide(curSolid->getNameInDocument()); if (prevSolid) doc->setShow(prevSolid->getNameInDocument()); } Gui::Selection().clearSelection(); Gui::Selection().addSelectionGate (new ReferenceSelection(prevSolid, edge, face, planar)); } else { Gui::Selection().rmvSelectionGate(); Gui::Document* doc = Gui::Application::Instance->activeDocument(); if (doc) { if (curSolid) doc->setShow(curSolid->getNameInDocument()); if (prevSolid) doc->setHide(prevSolid->getNameInDocument()); } } } void TaskSketchBasedParameters::exitSelectionMode() { onSelectReference(false, false, false, false); } const QByteArray TaskSketchBasedParameters::onFaceName(const QString& text) { if (text.length() == 0) return QByteArray(); QStringList parts = text.split(QChar::fromAscii(':')); if (parts.length() < 2) parts.push_back(QString::fromAscii("")); // Check whether this is the name of an App::Plane or Part::Datum feature App::DocumentObject* obj = vp->getObject()->getDocument()->getObject(parts[0].toAscii()); if (obj == NULL) return QByteArray(); PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) { // everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree) return QByteArray(); } else if (obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) { if (!activeBody->hasFeature(obj)) return QByteArray(); return QByteArray(); } else { // We must expect that "text" is the translation of "Face" followed by an ID. QString name; QTextStream str(&name); str << "^" << tr("Face") << "(\\d+)$"; QRegExp rx(name); if (text.indexOf(rx) < 0) { return QByteArray(); } int faceId = rx.cap(1).toInt(); std::stringstream ss; ss << "Face" << faceId; std::vector upToFaces(1,ss.str()); PartDesign::SketchBased* pcSketchBased = static_cast(vp->getObject()); pcSketchBased->UpToFace.setValue(obj, upToFaces); recomputeFeature(); return QByteArray(ss.str().c_str()); } } QString TaskSketchBasedParameters::getFaceReference(const QString& obj, const QString& sub) const { QString o = obj.left(obj.indexOf(QString::fromAscii(":"))); if (o == tr("No face selected")) return QString::fromAscii(""); else return QString::fromAscii("(App.activeDocument().") + o + QString::fromAscii(", [\"") + sub + QString::fromAscii("\"])"); } void TaskSketchBasedParameters::onUpdateView(bool on) { blockUpdate = !on; recomputeFeature(); } void TaskSketchBasedParameters::recomputeFeature() { if (!blockUpdate) { PartDesign::SketchBased* pcSketchBased = static_cast(vp->getObject()); pcSketchBased->getDocument()->recomputeFeature(pcSketchBased); } } App::DocumentObject* TaskSketchBasedParameters::getPartPlanes(const char* str) const { //TODO: Adjust to GRAPH handling when available App::DocumentObject* obj = vp->getObject(); App::Part* part = getPartFor(obj, false); if(!part) return nullptr; std::vector origs = part->getObjectsOfType(App::Origin::getClassTypeId()); if(origs.size()<1) return nullptr; App::Origin* orig = static_cast(origs[0]); auto planes = orig->getObjectsOfType(App::Plane::getClassTypeId()); for(App::DocumentObject* plane : planes) { if( strcmp(static_cast(plane)->PlaneType.getValue(), str) == 0) return plane; } return nullptr; } App::DocumentObject* TaskSketchBasedParameters::getPartLines(const char* str) const { //TODO: Adjust to GRAPH handling when available App::DocumentObject* obj = vp->getObject(); App::Part* part = getPartFor(obj, false); std::vector origs; if(part) origs = part->getObjectsOfType(App::Origin::getClassTypeId()); else origs = vp->getObject()->getDocument()->getObjectsOfType(App::Origin::getClassTypeId()); if(origs.size()<1) return nullptr; App::Origin* orig = static_cast(origs[0]); auto lines = orig->getObjectsOfType(App::Line::getClassTypeId()); for(App::DocumentObject* line : lines) { if( strcmp(static_cast(line)->LineType.getValue(), str) == 0) return line; } return nullptr; } TaskSketchBasedParameters::~TaskSketchBasedParameters() { } //************************************************************************** //************************************************************************** // TaskDialog //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TaskDlgSketchBasedParameters::TaskDlgSketchBasedParameters(PartDesignGui::ViewProvider *vp) : TaskDlgFeatureParameters(vp) { } TaskDlgSketchBasedParameters::~TaskDlgSketchBasedParameters() { } //==== calls from the TaskView =============================================================== bool TaskDlgSketchBasedParameters::reject() { PartDesign::SketchBased* pcSketchBased = static_cast(vp->getObject()); // get the Sketch Sketcher::SketchObject *pcSketch = static_cast(pcSketchBased->Sketch.getValue()); bool rv; // rv should be true anyway but to be on the safe side dur to thurver changes better respect it. rv = TaskDlgFeatureParameters::reject(); // if abort command deleted the object the sketch is visible again. // The the previous one feature already should be made visiable if (!Gui::Application::Instance->getViewProvider(pcSketchBased)) { // Make the sketch visiable if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch)) Gui::Application::Instance->getViewProvider(pcSketch)->show(); } return rv; } #include "moc_TaskSketchBasedParameters.cpp"