Skip to content

Commit

Permalink
+ Add a sketch validation panel
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Oct 15, 2013
1 parent 5bee772 commit 957cedc
Show file tree
Hide file tree
Showing 8 changed files with 419 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Mod/PartDesign/Gui/Workbench.cpp
Expand Up @@ -206,6 +206,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Sketcher_ViewSketch"
<< "Sketcher_MapSketch"
<< "Sketcher_ReorientSketch"
<< "Sketcher_ValidateSketch"
<< geom
<< cons
<< "Separator"
Expand Down
7 changes: 6 additions & 1 deletion src/Mod/Sketcher/App/SketchObject.cpp
Expand Up @@ -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)
Expand Down
5 changes: 5 additions & 0 deletions src/Mod/Sketcher/Gui/CMakeLists.txt
Expand Up @@ -31,6 +31,7 @@ set(SketcherGui_MOC_HDRS
TaskSketcherCreateCommands.h
TaskSketcherGeneral.h
TaskSketcherMessages.h
TaskSketcherValidation.h
TaskDlgEditSketch.h
SketchOrientationDialog.h
)
Expand All @@ -43,6 +44,7 @@ set(SketcherGui_UIC_SRCS
TaskSketcherConstrains.ui
TaskSketcherGeneral.ui
TaskSketcherMessages.ui
TaskSketcherValidation.ui
InsertDatum.ui
SketchOrientationDialog.ui
)
Expand Down Expand Up @@ -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
Expand Down
36 changes: 36 additions & 0 deletions src/Mod/Sketcher/Gui/Command.cpp
Expand Up @@ -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>
Expand All @@ -45,6 +46,7 @@

#include "SketchOrientationDialog.h"
#include "ViewProviderSketch.h"
#include "TaskSketcherValidation.h"

using namespace std;
using namespace SketcherGui;
Expand Down Expand Up @@ -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());
}




Expand All @@ -431,4 +466,5 @@ void CreateSketcherCommands(void)
rcCmdMgr.addCommand(new CmdSketcherMapSketch());
rcCmdMgr.addCommand(new CmdSketcherLeaveSketch());
rcCmdMgr.addCommand(new CmdSketcherViewSketch());
rcCmdMgr.addCommand(new CmdSketcherValidateSketch());
}
260 changes: 260 additions & 0 deletions src/Mod/Sketcher/Gui/TaskSketcherValidation.cpp
@@ -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"

0 comments on commit 957cedc

Please sign in to comment.