+ Add a sketch validation panel
This commit is contained in:
parent
5bee772e49
commit
957cedc1ff
|
@ -206,6 +206,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
<< "Sketcher_ViewSketch"
|
||||
<< "Sketcher_MapSketch"
|
||||
<< "Sketcher_ReorientSketch"
|
||||
<< "Sketcher_ValidateSketch"
|
||||
<< geom
|
||||
<< cons
|
||||
<< "Separator"
|
||||
|
|
|
@ -394,7 +394,12 @@ int SketchObject::setConstruction(int GeoId, bool on)
|
|||
|
||||
int SketchObject::addConstraints(const std::vector<Constraint *> &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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <Gui/Application.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Control.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/DlgEditFileIncludeProptertyExternal.h>
|
||||
#include <Gui/SelectionFilter.h>
|
||||
|
@ -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<Gui::SelectionObject> 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<Sketcher::SketchObject*>(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());
|
||||
}
|
||||
|
|
260
src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp
Normal file
260
src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp
Normal file
|
@ -0,0 +1,260 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <Precision.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ui_TaskSketcherValidation.h"
|
||||
#include "TaskSketcherValidation.h"
|
||||
#include <Mod/Sketcher/App/SketchObject.h>
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
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<const VertexIds&,
|
||||
const VertexIds&, bool>
|
||||
{
|
||||
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<const VertexIds&,
|
||||
const VertexIds&, bool>
|
||||
{
|
||||
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<const ConstraintIds&,
|
||||
const ConstraintIds&, bool>
|
||||
{
|
||||
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> vertexIds;
|
||||
const std::vector<Part::Geometry *>& geom = sketch->getInternalGeometry();
|
||||
for (std::size_t i=0; i<geom.size(); i++) {
|
||||
Part::Geometry* g = geom[i];
|
||||
if (g->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
const Part::GeomLineSegment *segm = dynamic_cast<const Part::GeomLineSegment*>(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<const Part::GeomArcOfCircle*>(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<ConstraintIds, Constraint_Less> coincidences;
|
||||
double prec = 0.1; // Precision::Confusion()
|
||||
std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(prec));
|
||||
std::vector<VertexIds>::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<VertexIds>::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<Sketcher::Constraint*> constraint = sketch->Constraints.getValues();
|
||||
for (std::vector<Sketcher::Constraint*>::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<ConstraintIds, Constraint_Less>::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<Sketcher::Constraint*> constr;
|
||||
for (std::set<ConstraintIds, Constraint_Less>::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<Sketcher::Constraint*>::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"
|
66
src/Mod/Sketcher/Gui/TaskSketcherValidation.h
Normal file
66
src/Mod/Sketcher/Gui/TaskSketcherValidation.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2013 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <memory>
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
|
||||
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_TaskSketcherValidation> ui;
|
||||
Sketcher::SketchObject* sketch;
|
||||
};
|
||||
|
||||
class TaskSketcherValidation : public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskSketcherValidation(Sketcher::SketchObject* Obj);
|
||||
~TaskSketcherValidation();
|
||||
};
|
||||
|
||||
} //namespace SketcherGui
|
||||
|
||||
#endif // SKETCHERGUI_TASKSKETCHERVALIDATION_H
|
44
src/Mod/Sketcher/Gui/TaskSketcherValidation.ui
Normal file
44
src/Mod/Sketcher/Gui/TaskSketcherValidation.ui
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SketcherGui::TaskSketcherValidation</class>
|
||||
<widget class="QWidget" name="SketcherGui::TaskSketcherValidation">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>242</width>
|
||||
<height>75</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sketcher validation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Missing coincidences</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="findButton">
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPushButton" name="fixButton">
|
||||
<property name="text">
|
||||
<string>Fix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -99,6 +99,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
|||
<< "Sketcher_ViewSketch"
|
||||
<< "Sketcher_MapSketch"
|
||||
<< "Sketcher_ReorientSketch"
|
||||
<< "Sketcher_ValidateSketch"
|
||||
<< geom
|
||||
<< cons
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue
Block a user