From 957cedc1ffc055f67a60690ab6e38c1b57404aff Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 15 Oct 2013 17:11:49 +0200 Subject: [PATCH] + Add a sketch validation panel --- src/Mod/PartDesign/Gui/Workbench.cpp | 1 + src/Mod/Sketcher/App/SketchObject.cpp | 7 +- src/Mod/Sketcher/Gui/CMakeLists.txt | 5 + src/Mod/Sketcher/Gui/Command.cpp | 36 +++ .../Sketcher/Gui/TaskSketcherValidation.cpp | 260 ++++++++++++++++++ src/Mod/Sketcher/Gui/TaskSketcherValidation.h | 66 +++++ .../Sketcher/Gui/TaskSketcherValidation.ui | 44 +++ src/Mod/Sketcher/Gui/Workbench.cpp | 1 + 8 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp create mode 100644 src/Mod/Sketcher/Gui/TaskSketcherValidation.h create mode 100644 src/Mod/Sketcher/Gui/TaskSketcherValidation.ui diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 977f110bd..b272e4d0a 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -206,6 +206,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Sketcher_ViewSketch" << "Sketcher_MapSketch" << "Sketcher_ReorientSketch" + << "Sketcher_ValidateSketch" << geom << cons << "Separator" diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index ec4cfa8c2..65529b46a 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -394,7 +394,12 @@ int SketchObject::setConstruction(int GeoId, bool on) int SketchObject::addConstraints(const std::vector &ConstraintList) { - return -1; + const std::vector< Constraint * > &vals = this->Constraints.getValues(); + + std::vector< Constraint * > newVals(vals); + newVals.insert(newVals.end(), ConstraintList.begin(), ConstraintList.end()); + this->Constraints.setValues(newVals); + return this->Constraints.getSize()-1; } int SketchObject::addConstraint(const Constraint *constraint) diff --git a/src/Mod/Sketcher/Gui/CMakeLists.txt b/src/Mod/Sketcher/Gui/CMakeLists.txt index d2b6ca04a..dd436b67f 100644 --- a/src/Mod/Sketcher/Gui/CMakeLists.txt +++ b/src/Mod/Sketcher/Gui/CMakeLists.txt @@ -31,6 +31,7 @@ set(SketcherGui_MOC_HDRS TaskSketcherCreateCommands.h TaskSketcherGeneral.h TaskSketcherMessages.h + TaskSketcherValidation.h TaskDlgEditSketch.h SketchOrientationDialog.h ) @@ -43,6 +44,7 @@ set(SketcherGui_UIC_SRCS TaskSketcherConstrains.ui TaskSketcherGeneral.ui TaskSketcherMessages.ui + TaskSketcherValidation.ui InsertDatum.ui SketchOrientationDialog.ui ) @@ -75,6 +77,9 @@ SET(SketcherGui_SRCS TaskSketcherMessages.ui TaskSketcherMessages.cpp TaskSketcherMessages.h + TaskSketcherValidation.ui + TaskSketcherValidation.cpp + TaskSketcherValidation.h ViewProviderSketch.cpp ViewProviderSketch.h DrawSketchHandler.cpp diff --git a/src/Mod/Sketcher/Gui/Command.cpp b/src/Mod/Sketcher/Gui/Command.cpp index 4ad5ae9d5..4a5b3954e 100644 --- a/src/Mod/Sketcher/Gui/Command.cpp +++ b/src/Mod/Sketcher/Gui/Command.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include "SketchOrientationDialog.h" #include "ViewProviderSketch.h" +#include "TaskSketcherValidation.h" using namespace std; using namespace SketcherGui; @@ -418,6 +420,39 @@ bool CmdSketcherViewSketch::isActive(void) return false; } +DEF_STD_CMD_A(CmdSketcherValidateSketch); + +CmdSketcherValidateSketch::CmdSketcherValidateSketch() + : Command("Sketcher_ValidateSketch") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Validate sketch..."); + sToolTipText = QT_TR_NOOP("Validate sketch"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + eType = 0; +} + +void CmdSketcherValidateSketch::activated(int iMsg) +{ + std::vector selection = getSelection().getSelectionEx(0, Sketcher::SketchObject::getClassTypeId()); + if (selection.size() != 1) { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("CmdSketcherValidateSketch", "Wrong selection"), + qApp->translate("CmdSketcherValidateSketch", "Select one sketch, please.")); + return; + } + + Sketcher::SketchObject* Obj = static_cast(selection[0].getObject()); + Gui::Control().showDialog(new TaskSketcherValidation(Obj)); +} + +bool CmdSketcherValidateSketch::isActive(void) +{ + return (hasActiveDocument() && !Gui::Control().activeDialog()); +} + @@ -431,4 +466,5 @@ void CreateSketcherCommands(void) rcCmdMgr.addCommand(new CmdSketcherMapSketch()); rcCmdMgr.addCommand(new CmdSketcherLeaveSketch()); rcCmdMgr.addCommand(new CmdSketcherViewSketch()); + rcCmdMgr.addCommand(new CmdSketcherValidateSketch()); } diff --git a/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp b/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp new file mode 100644 index 000000000..7396bc23c --- /dev/null +++ b/src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp @@ -0,0 +1,260 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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_ +#endif + +#include +#include +#include +#include + +#include "ui_TaskSketcherValidation.h" +#include "TaskSketcherValidation.h" +#include +#include +#include +#include +#include +#include + +using namespace SketcherGui; +using namespace Gui::TaskView; + +/* TRANSLATOR SketcherGui::SketcherValidation */ + +SketcherValidation::SketcherValidation(Sketcher::SketchObject* Obj, QWidget* parent) + : QWidget(parent), ui(new Ui_TaskSketcherValidation()), sketch(Obj) +{ + ui->setupUi(this); +} + +SketcherValidation::~SketcherValidation() +{ +} + +void SketcherValidation::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + QWidget::changeEvent(e); +} + +typedef struct { + Base::Vector3d v; + int GeoId; + Sketcher::PointPos PosId; +} VertexIds; + +struct Vertex_Less : public std::binary_function +{ + Vertex_Less(double tolerance) : tolerance(tolerance){} + bool operator()(const VertexIds& x, + const VertexIds& y) const + { + if (fabs (x.v.x - y.v.x) > tolerance) + return x.v.x < y.v.x; + if (fabs (x.v.y - y.v.y) > tolerance) + return x.v.y < y.v.y; + if (fabs (x.v.z - y.v.z) > tolerance) + return x.v.z < y.v.z; + return false; // points are considered to be equal + } +private: + double tolerance; +}; + +struct Vertex_EqualTo : public std::binary_function +{ + Vertex_EqualTo(double tolerance) : tolerance(tolerance){} + bool operator()(const VertexIds& x, + const VertexIds& y) const + { + if (fabs (x.v.x - y.v.x) <= tolerance) { + if (fabs (x.v.y - y.v.y) <= tolerance) { + if (fabs (x.v.z - y.v.z) <= tolerance) { + return true; + } + } + } + return false; + } +private: + double tolerance; +}; + +typedef struct { + int First; + int Second; + Sketcher::PointPos FirstPos; + Sketcher::PointPos SecondPos; +} ConstraintIds; + +struct Constraint_Less : public std::binary_function +{ + bool operator()(const ConstraintIds& x, + const ConstraintIds& y) const + { + int x1 = x.First; + int x2 = x.Second; + int y1 = y.First; + int y2 = y.Second; + + if (x1 > x2) + { std::swap(x1, x2); } + if (y1 > y2) + { std::swap(y1, y2); } + + if (x1 < y1) return true; + else if (x1 > y1) return false; + else if (x2 < y2) return true; + else if (x2 > y2) return false; + return false; + } +}; + +void SketcherValidation::on_findButton_clicked() +{ +} + +void SketcherValidation::on_fixButton_clicked() +{ + std::vector vertexIds; + const std::vector& geom = sketch->getInternalGeometry(); + for (std::size_t i=0; igetTypeId() == Part::GeomLineSegment::getClassTypeId()) { + const Part::GeomLineSegment *segm = dynamic_cast(g); + VertexIds id; + id.GeoId = (int)i; + id.PosId = Sketcher::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = (int)i; + id.PosId = Sketcher::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + else if (g->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { + const Part::GeomArcOfCircle *segm = dynamic_cast(g); + VertexIds id; + id.GeoId = (int)i; + id.PosId = Sketcher::start; + id.v = segm->getStartPoint(); + vertexIds.push_back(id); + id.GeoId = (int)i; + id.PosId = Sketcher::end; + id.v = segm->getEndPoint(); + vertexIds.push_back(id); + } + } + + std::set coincidences; + double prec = 0.1; // Precision::Confusion() + std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(prec)); + std::vector::iterator vt = vertexIds.begin(); + Vertex_EqualTo pred(prec); + while (vt < vertexIds.end()) { + // get first item whose adjacent element has the same vertex coordinates + vt = std::adjacent_find(vt, vertexIds.end(), pred); + if (vt < vertexIds.end()) { + std::vector::iterator vn; + for (vn = vt+1; vn != vertexIds.end(); ++vn) { + if (pred(*vt,*vn)) { + ConstraintIds id; + id.First = vt->GeoId; + id.FirstPos = vt->PosId; + id.Second = vn->GeoId; + id.SecondPos = vn->PosId; + coincidences.insert(id); + } + else { + break; + } + } + + vt = vn; + } + } + + std::vector constraint = sketch->Constraints.getValues(); + for (std::vector::iterator it = constraint.begin(); it != constraint.end(); ++it) { + if ((*it)->Type == Sketcher::Coincident) { + ConstraintIds id; + id.First = (*it)->First; + id.FirstPos = (*it)->FirstPos; + id.Second = (*it)->Second; + id.SecondPos = (*it)->SecondPos; + std::set::iterator pos = coincidences.find(id); + if (pos != coincidences.end()) { + coincidences.erase(pos); + } + } + } + + // undo command open + App::Document* doc = sketch->getDocument(); + doc->openTransaction("add coincident constraint"); + std::vector constr; + for (std::set::iterator it = coincidences.begin(); it != coincidences.end(); ++it) { + Sketcher::Constraint* c = new Sketcher::Constraint(); + c->Type = Sketcher::Coincident; + c->First = it->First; + c->Second = it->Second; + c->FirstPos = it->FirstPos; + c->SecondPos = it->SecondPos; + constr.push_back(c); + } + sketch->addConstraints(constr); + for (std::vector::iterator it = constr.begin(); it != constr.end(); ++it) { + delete *it; + } + + // finish the transaction and update + Gui::WaitCursor wc; + doc->commitTransaction(); + doc->recompute(); +} + +// ----------------------------------------------- + +TaskSketcherValidation::TaskSketcherValidation(Sketcher::SketchObject* Obj) +{ + QWidget* widget = new SketcherValidation(Obj); + Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox( + QPixmap(), widget->windowTitle(), true, 0); + taskbox->groupLayout()->addWidget(widget); + Content.push_back(taskbox); +} + +TaskSketcherValidation::~TaskSketcherValidation() +{ +} + +#include "moc_TaskSketcherValidation.cpp" diff --git a/src/Mod/Sketcher/Gui/TaskSketcherValidation.h b/src/Mod/Sketcher/Gui/TaskSketcherValidation.h new file mode 100644 index 000000000..df6dc3a83 --- /dev/null +++ b/src/Mod/Sketcher/Gui/TaskSketcherValidation.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef SKETCHERGUI_TASKSKETCHERVALIDATION_H +#define SKETCHERGUI_TASKSKETCHERVALIDATION_H + +#include +#include + +namespace Sketcher { class SketchObject; } + +namespace SketcherGui { + +class Ui_TaskSketcherValidation; +class SketcherValidation : public QWidget +{ + Q_OBJECT + +public: + SketcherValidation(Sketcher::SketchObject* Obj, QWidget* parent = 0); + ~SketcherValidation(); + +protected: + void changeEvent(QEvent *e); + +private Q_SLOTS: + void on_findButton_clicked(); + void on_fixButton_clicked(); + +private: + std::auto_ptr ui; + Sketcher::SketchObject* sketch; +}; + +class TaskSketcherValidation : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskSketcherValidation(Sketcher::SketchObject* Obj); + ~TaskSketcherValidation(); +}; + +} //namespace SketcherGui + +#endif // SKETCHERGUI_TASKSKETCHERVALIDATION_H diff --git a/src/Mod/Sketcher/Gui/TaskSketcherValidation.ui b/src/Mod/Sketcher/Gui/TaskSketcherValidation.ui new file mode 100644 index 000000000..aa3cde3f2 --- /dev/null +++ b/src/Mod/Sketcher/Gui/TaskSketcherValidation.ui @@ -0,0 +1,44 @@ + + + SketcherGui::TaskSketcherValidation + + + + 0 + 0 + 242 + 75 + + + + Sketcher validation + + + + + + Missing coincidences + + + + + + Find + + + + + + + Fix + + + + + + + + + + + diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index fda421b15..3d6b36d4c 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -99,6 +99,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Sketcher_ViewSketch" << "Sketcher_MapSketch" << "Sketcher_ReorientSketch" + << "Sketcher_ValidateSketch" << geom << cons ;