View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0000695 | Sketcher | Patch | public | 2012-05-05 10:57 | 2014-01-12 22:09 |
| Reporter | jrheinlaender | Assigned To | logari81 | ||
| Priority | normal | Severity | feature | Reproducibility | always |
| Status | closed | Resolution | won't fix | ||
| Summary | 0000695: Sketcher: Adding constraint for diameter of circle or arc | ||||
| Description | This patch adds a new diameter constraint to the sketcher. The code is copied and adapter from the radius constraint with minimal changes | ||||
| Additional Information | Attached the patch and two icons | ||||
| Tags | No tags attached. | ||||
| FreeCAD Information | |||||
|
2012-05-05 10:57
|
constraint_diameter.diff (22,426 bytes)
diff --git a/src/Mod/Sketcher/App/Constraint.h b/src/Mod/Sketcher/App/Constraint.h
index 3bfb5e2..eca2054 100644
--- a/src/Mod/Sketcher/App/Constraint.h
+++ b/src/Mod/Sketcher/App/Constraint.h
@@ -45,7 +45,8 @@ enum ConstraintType {
Radius,
Equal,
PointOnObject,
- Symmetric
+ Symmetric,
+ Diameter
};
/// define if you want to use the end or start point
diff --git a/src/Mod/Sketcher/App/ConstraintPyImp.cpp b/src/Mod/Sketcher/App/ConstraintPyImp.cpp
index 7dad2b7..afdf185 100644
--- a/src/Mod/Sketcher/App/ConstraintPyImp.cpp
+++ b/src/Mod/Sketcher/App/ConstraintPyImp.cpp
@@ -124,6 +124,10 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
this->getConstraintPtr()->Type = Radius;
valid = true;
}
+ else if (strcmp("Diameter",ConstraintType) == 0) {
+ this->getConstraintPtr()->Type = Diameter;
+ valid = true;
+ }
if (valid) {
this->getConstraintPtr()->First = FirstIndex;
this->getConstraintPtr()->Value = Value;
diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp
index 608d9da..9bb542c 100644
--- a/src/Mod/Sketcher/App/Sketch.cpp
+++ b/src/Mod/Sketcher/App/Sketch.cpp
@@ -524,6 +524,9 @@ int Sketch::addConstraint(const Constraint *constraint)
case Radius:
rtn = addRadiusConstraint(constraint->First, constraint->Value);
break;
+ case Diameter:
+ rtn = addDiameterConstraint(constraint->First, constraint->Value);
+ break;
case Equal:
rtn = addEqualConstraint(constraint->First,constraint->Second);
break;
@@ -1319,6 +1322,31 @@ int Sketch::addRadiusConstraint(int geoId, double value)
return -1;
}
+int Sketch::addDiameterConstraint(int geoId, double value)
+{
+ geoId = checkGeoId(geoId);
+
+ if (Geoms[geoId].type == Circle) {
+ GCS::Circle &c = Circles[Geoms[geoId].index];
+ // add the parameter for the diameter
+ FixParameters.push_back(new double(value / 2.0));
+ double *radius = FixParameters[FixParameters.size()-1];
+ int tag = ++ConstraintsCounter;
+ GCSsys.addConstraintCircleRadius(c, radius, tag);
+ return ConstraintsCounter;
+ }
+ else if (Geoms[geoId].type == Arc) {
+ GCS::Arc &a = Arcs[Geoms[geoId].index];
+ // add the parameter for the diameter
+ FixParameters.push_back(new double(value / 2.0));
+ double *radius = FixParameters[FixParameters.size()-1];
+ int tag = ++ConstraintsCounter;
+ GCSsys.addConstraintArcRadius(a, radius, tag);
+ return ConstraintsCounter;
+ }
+ return -1;
+}
+
// line orientation angle constraint
int Sketch::addAngleConstraint(int geoId, double value)
{
@@ -1839,7 +1867,7 @@ Base::Vector3d Sketch::getPoint(int geoId, PointPos pos)
}
int Sketch::diagnose(void)
-{
+{
Conflicting.clear();
if (GCSsys.isInit()) {
int dofs = GCSsys.diagnose(Parameters, Conflicting);
diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h
index ec10842..763d565 100644
--- a/src/Mod/Sketcher/App/Sketch.h
+++ b/src/Mod/Sketcher/App/Sketch.h
@@ -28,8 +28,8 @@
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/TopoShape.h>
#include "Constraint.h"
-
-#include "freegcs/GCS.h"
+
+#include "freegcs/GCS.h"
#include <Base/Persistence.h>
@@ -160,6 +160,8 @@ public:
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/// add a radius constraint on a circle or an arc
int addRadiusConstraint(int geoId, double value);
+ /// add a diameter constraint on a circle or an arc
+ int addDiameterConstraint(int geoId, double value);
/// add an angle constraint on a line or between two lines
int addAngleConstraint(int geoId, double value);
int addAngleConstraint(int geoId1, int geoId2, double value);
diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp
index 95aa455..c589ddd 100644
--- a/src/Mod/Sketcher/App/SketchObject.cpp
+++ b/src/Mod/Sketcher/App/SketchObject.cpp
@@ -148,10 +148,11 @@ int SketchObject::setDatum(int ConstrId, double Datum)
type != DistanceX &&
type != DistanceY &&
type != Radius &&
+ type != Diameter &&
type != Angle)
return -1;
- if ((type == Distance || type == Radius) && Datum <= 0)
+ if ((type == Distance || type == Radius || type == Diameter) && Datum <= 0)
return (Datum == 0) ? -5 : -4;
// copy the list
diff --git a/src/Mod/Sketcher/App/freegcs/GCS.cpp b/src/Mod/Sketcher/App/freegcs/GCS.cpp
index d17e79b..c388678 100644
--- a/src/Mod/Sketcher/App/freegcs/GCS.cpp
+++ b/src/Mod/Sketcher/App/freegcs/GCS.cpp
@@ -42,7 +42,7 @@ typedef boost::adjacency_list <boost::vecS, boost::vecS, boost::undirectedS> Gra
// System
System::System()
: clist(0),
- c2p(), p2c(),
+ c2p(), p2c(),
subsyslist(0),
reference(),
init(false)
@@ -52,7 +52,7 @@ System::System()
System::System(std::vector<Constraint *> clist_)
: c2p(), p2c(),
subsyslist(0),
- reference(),
+ reference(),
init(false)
{
// create own (shallow) copy of constraints
@@ -505,11 +505,21 @@ int System::addConstraintCircleRadius(Circle &c, double *radius, int tagId)
return addConstraintEqual(c.rad, radius, tagId);
}
+int System::addConstraintCircleDiameter(Circle &c, double *diameter, int tagId)
+{
+ return addConstraintEqual(c.rad, diameter, tagId);
+}
+
int System::addConstraintArcRadius(Arc &a, double *radius, int tagId)
{
return addConstraintEqual(a.rad, radius, tagId);
}
+int System::addConstraintArcDiameter(Arc &a, double *diameter, int tagId)
+{
+ return addConstraintEqual(a.rad, diameter, tagId);
+}
+
int System::addConstraintEqualLength(Line &l1, Line &l2, double *length, int tagId)
{
addConstraintP2PDistance(l1.p1, l1.p2, length, tagId);
@@ -730,14 +740,14 @@ int System::solve_BFGS(SubSystem *subsys, bool isFine)
double convergence = isFine ? XconvergenceFine : XconvergenceRough;
int maxIterNumber = MaxIterations * xsize;
double diverging_lim = 1e6*err + 1e12;
-
+
for (int iter=1; iter < maxIterNumber; iter++) {
if (h.norm() <= convergence || err <= smallF)
break;
if (err > diverging_lim || err != err) // check for diverging and NaN
break;
-
+
y = grad;
subsys->calcGrad(grad);
y = grad - y; // = grad - gradold
@@ -1001,7 +1011,7 @@ int System::solve_DL(SubSystem* subsys)
if (stop)
break;
-// it didn't work in some tests
+// it didn't work in some tests
// // restrict h_dl according to maxStep
// double scale = subsys->maxStep(h_dl);
// if (scale < 1.)
@@ -1262,7 +1272,7 @@ int System::diagnose(VEC_pD ¶ms, VEC_I &conflicting)
int params_num = qrJT.rows();
int constr_num = qrJT.cols();
int rank = qrJT.rank();
-
+
Eigen::MatrixXd R;
if (constr_num >= params_num)
R = qrJT.matrixQR().triangularView<Eigen::Upper>();
@@ -1307,7 +1317,7 @@ int System::diagnose(VEC_pD ¶ms, VEC_I &conflicting)
if (params_num == rank) // over-constrained
return params_num - constr_num;
}
-
+
return params_num - rank;
}
return params.size();
diff --git a/src/Mod/Sketcher/App/freegcs/GCS.h b/src/Mod/Sketcher/App/freegcs/GCS.h
index f17f585..2fe4782 100644
--- a/src/Mod/Sketcher/App/freegcs/GCS.h
+++ b/src/Mod/Sketcher/App/freegcs/GCS.h
@@ -140,7 +140,9 @@ namespace GCS
int addConstraintTangentArc2Arc(Arc &a1, bool reverse1, Arc &a2, bool reverse2,
int tagId=0);
int addConstraintCircleRadius(Circle &c, double *radius, int tagId=0);
+ int addConstraintCircleDiameter(Circle &c, double *diameter, int tagId=0);
int addConstraintArcRadius(Arc &a, double *radius, int tagId=0);
+ int addConstraintArcDiameter(Arc &a, double *diameter, int tagId=0);
int addConstraintEqualLength(Line &l1, Line &l2, double *length, int tagId=0);
int addConstraintEqualRadius(Circle &c1, Circle &c2, int tagId=0);
int addConstraintEqualRadius(Circle &c1, Arc &a2, int tagId=0);
diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp
index fd795eb..6cb691d 100644
--- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp
+++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp
@@ -1506,6 +1506,86 @@ bool CmdSketcherConstrainRadius::isActive(void)
return isCreateConstraintActive( getActiveGuiDocument() );
}
+DEF_STD_CMD_A(CmdSketcherConstrainDiameter);
+
+CmdSketcherConstrainDiameter::CmdSketcherConstrainDiameter()
+ :Command("Sketcher_ConstrainDiameter")
+{
+ sAppModule = "Sketcher";
+ sGroup = QT_TR_NOOP("Sketcher");
+ sMenuText = QT_TR_NOOP("Constrain diameter");
+ sToolTipText = QT_TR_NOOP("Fix the diameter of a circle or an arc");
+ sWhatsThis = sToolTipText;
+ sStatusTip = sToolTipText;
+ sPixmap = "Constraint_Diameter";
+ sAccel = "D";
+ eType = ForEdit;
+}
+
+void CmdSketcherConstrainDiameter::activated(int iMsg)
+{
+ // get the selection
+ std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
+
+ // only one sketch with its subelements are allowed to be selected
+ if (selection.size() != 1) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+ }
+
+ // get the needed lists and objects
+ const std::vector<std::string> &SubNames = selection[0].getSubNames();
+ Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
+
+ if (SubNames.size() != 1) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+ }
+
+ if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") {
+ int GeoId = std::atoi(SubNames[0].substr(4,4000).c_str());
+
+ const Part::Geometry *geom = Obj->getGeometry(GeoId);
+ if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
+ const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
+ double ActDiameter = arc->getRadius() * 2.0;
+
+ openCommand("add diameter constraint");
+ Gui::Command::doCommand(
+ Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Diameter',%d,%f)) ",
+ selection[0].getFeatName(),GeoId,ActDiameter);
+ commitCommand();
+ //updateActive();
+ getSelection().clearSelection();
+ return;
+ }
+ else if (geom->getTypeId() == Part::GeomCircle::getClassTypeId()) {
+ const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geom);
+ double ActDiameter = circle->getRadius() * 2.0;
+
+ openCommand("add diameter constraint");
+ Gui::Command::doCommand(
+ Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Diameter',%d,%f)) ",
+ selection[0].getFeatName(),GeoId,ActDiameter);
+ commitCommand();
+ //updateActive();
+ getSelection().clearSelection();
+ return;
+ }
+ }
+
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+}
+
+bool CmdSketcherConstrainDiameter::isActive(void)
+{
+ return isCreateConstraintActive( getActiveGuiDocument() );
+}
+
DEF_STD_CMD_A(CmdSketcherConstrainAngle);
@@ -1878,6 +1958,7 @@ void CreateSketcherCommandsConstraints(void)
rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceX());
rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceY());
rcCmdMgr.addCommand(new CmdSketcherConstrainRadius());
+ rcCmdMgr.addCommand(new CmdSketcherConstrainDiameter());
rcCmdMgr.addCommand(new CmdSketcherConstrainAngle());
rcCmdMgr.addCommand(new CmdSketcherConstrainEqual());
rcCmdMgr.addCommand(new CmdSketcherConstrainPointOnObject());
diff --git a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
index 8fe503c..bf3a19e 100644
--- a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
+++ b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
@@ -66,7 +66,8 @@ void EditDatumDialog::exec(bool atCursor)
// Return if constraint doesn't have editable value
if (Constr->Type == Sketcher::Distance ||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
- Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
+ Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Diameter ||
+ Constr->Type == Sketcher::Angle) {
if (vp->getSketchObject()->hasConflicts()) {
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Distance constraint"),
diff --git a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
index bdc5ad8..a8eeef5 100644
--- a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
+++ b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
@@ -15,6 +15,7 @@
<file>icons/small/Constraint_PointOnStart_sm.xpm</file>
<file>icons/small/Constraint_PointToObject_sm.xpm</file>
<file>icons/small/Constraint_Radius_sm.xpm</file>
+ <file>icons/small/Constraint_Diameter_sm.xpm</file>
<file>icons/small/Constraint_Tangent_sm.xpm</file>
<file>icons/small/Constraint_TangentToEnd_sm.xpm</file>
<file>icons/small/Constraint_TangentToStart_sm.xpm</file>
@@ -37,6 +38,7 @@
<file>icons/Constraint_PointOnStart.svg</file>
<file>icons/Constraint_PointToObject.svg</file>
<file>icons/Constraint_Radius.svg</file>
+ <file>icons/Constraint_Diameter.svg</file>
<file>icons/Constraint_Tangent.svg</file>
<file>icons/Constraint_TangentToEnd.svg</file>
<file>icons/Constraint_TangentToStart.svg</file>
diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
index 36c6057..08bf1e1 100644
--- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
+++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
@@ -169,7 +169,8 @@ void TaskSketcherConstrains::on_listWidgetConstraints_itemActivated(QListWidgetI
// if its the right constraint
if (it->Type == Sketcher::Distance ||
it->Type == Sketcher::DistanceX || it->Type == Sketcher::DistanceY ||
- it->Type == Sketcher::Radius || it->Type == Sketcher::Angle) {
+ it->Type == Sketcher::Radius || it->Type == Sketcher::Diameter ||
+ it->Type == Sketcher::Angle) {
EditDatumDialog *editDatumDialog = new EditDatumDialog(this->sketchView, it->ConstraintNbr);
editDatumDialog->exec(false);
@@ -196,6 +197,7 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
QIcon tang ( Gui::BitmapFactory().pixmap("Constraint_Tangent") );
QIcon dist ( Gui::BitmapFactory().pixmap("Constraint_Length") );
QIcon radi ( Gui::BitmapFactory().pixmap("Constraint_Radius") );
+ QIcon diam ( Gui::BitmapFactory().pixmap("Constraint_Diameter") );
QIcon angl ( Gui::BitmapFactory().pixmap("Constraint_InternalAngle") );
QIcon equal( Gui::BitmapFactory().pixmap("Constraint_EqualLength") );
QIcon pntoo( Gui::BitmapFactory().pixmap("Constraint_PointOnObject") );
@@ -278,6 +280,12 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
ui->listWidgetConstraints->addItem(new ConstraintItem(radi,name,i-1,(*it)->Type));
}
break;
+ case Sketcher::Diameter:
+ if(Filter<3 || (*it)->Name != ""){
+ name = QString::fromLatin1("%1 (%2)").arg(name).arg((*it)->Value);
+ ui->listWidgetConstraints->addItem(new ConstraintItem(diam,name,i-1,(*it)->Type));
+ }
+ break;
case Sketcher::Angle:
if(Filter<3 || (*it)->Name != ""){
name = QString::fromLatin1("%1 (%2)").arg(name).arg(Base::toDegrees<double>(std::abs((*it)->Value)));
diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
index ee289f1..23aca8a 100644
--- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
+++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
@@ -726,7 +726,8 @@ void ViewProviderSketch::editDoubleClicked(void)
// if its the right constraint
if (Constr->Type == Sketcher::Distance ||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
- Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
+ Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Diameter ||
+ Constr->Type == Sketcher::Angle) {
EditDatumDialog * editDatumDialog = new EditDatumDialog(this, edit->PreselectConstraint);
SoIdleSensor* sensor = new SoIdleSensor(EditDatumDialog::run, editDatumDialog);
@@ -870,7 +871,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
Constraint *Constr = constrlist[constNum];
if (Constr->Type == Distance || Constr->Type == DistanceX || Constr->Type == DistanceY ||
- Constr->Type == Radius) {
+ Constr->Type == Radius || Constr->Type == Diameter) {
int intGeoCount = getSketchObject()->getHighestCurveIndex() + 1;
int extGeoCount = getSketchObject()->getExternalGeometryCount();
@@ -927,14 +928,14 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
Base::Vector3d vec = Base::Vector3d(toPos.fX, toPos.fY, 0) - p2;
Base::Vector3d dir;
- if (Constr->Type == Distance || Constr->Type == Radius)
+ if (Constr->Type == Distance || Constr->Type == Radius || Constr->Type == Diameter)
dir = (p2-p1).Normalize();
else if (Constr->Type == DistanceX)
dir = Base::Vector3d( (p2.x - p1.x >= FLT_EPSILON) ? 1 : -1, 0, 0);
else if (Constr->Type == DistanceY)
dir = Base::Vector3d(0, (p2.y - p1.y >= FLT_EPSILON) ? 1 : -1, 0);
- if (Constr->Type == Radius)
+ if (Constr->Type == Radius || Constr->Type == Diameter)
Constr->LabelDistance = vec.x * dir.x + vec.y * dir.y;
else {
Base::Vector3d norm(-dir.y,dir.x,0);
@@ -1417,7 +1418,7 @@ void ViewProviderSketch::updateColor(void)
// Check Constraint Type
ConstraintType type = getSketchObject()->Constraints.getValues()[i]->Type;
bool hasDatumLabel = (type == Sketcher::Angle ||
- type == Sketcher::Radius ||
+ type == Sketcher::Radius || type == Sketcher::Diameter ||
type == Sketcher::Distance || type == Sketcher::DistanceX || type == Sketcher::DistanceY);
if (edit->SelConstraintSet.find(i) != edit->SelConstraintSet.end()) {
@@ -2436,6 +2437,7 @@ Restart:
}
break;
case Radius:
+ case Diameter:
{
assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount);
@@ -2451,6 +2453,8 @@ Restart:
double angle = (startangle + endangle)/2;
pnt1 = arc->getCenter();
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
+ if (Constr->Type == Diameter)
+ pnt1 = pnt1 - radius * Base::Vector3d(cos(angle),sin(angle),0.);
}
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
@@ -2458,6 +2462,8 @@ Restart:
double angle = M_PI/4;
pnt1 = circle->getCenter();
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
+ if (Constr->Type == Diameter)
+ pnt1 = pnt1 - radius * Base::Vector3d(cos(angle),sin(angle),0.);
} else
break;
} else
@@ -2572,6 +2578,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case DistanceX:
case DistanceY:
case Radius:
+ case Diameter:
case Angle:
{
SoSeparator *sepDatum = new SoSeparator();
diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp
index 15a285f..65292a2 100644
--- a/src/Mod/Sketcher/Gui/Workbench.cpp
+++ b/src/Mod/Sketcher/Gui/Workbench.cpp
@@ -83,6 +83,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
+ << "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainAngle"
@@ -136,6 +137,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
+ << "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainAngle"
|
|
2012-05-05 10:59
|
|
|
2012-05-05 11:03
|
|
|
|
Thanks for your patch. Since this patch touches FreeGCS I will reassign it to myself. Your diff file includes white space changes, please don't include whitespace in future patches. I am not sure if I will incorporate this patch exactly as it is. It seems reasonable but maybe we could save some of the duplicated code. |
|
|
Sorry about the white spaces - I am only just learning about git I also thought about the duplicate code. But since I have only a limited understanding of the code, I tried to modify as little original code as possible There's another diff attached without whitespace and also without two functions which I later saw were superfluous |
|
2012-05-14 13:30
|
constraint_diameter_2.diff (18,122 bytes)
diff --git a/src/Mod/Sketcher/App/Constraint.h b/src/Mod/Sketcher/App/Constraint.h
index 3bfb5e2..eca2054 100644
--- a/src/Mod/Sketcher/App/Constraint.h
+++ b/src/Mod/Sketcher/App/Constraint.h
@@ -45,7 +45,8 @@ enum ConstraintType {
Radius,
Equal,
PointOnObject,
- Symmetric
+ Symmetric,
+ Diameter
};
/// define if you want to use the end or start point
diff --git a/src/Mod/Sketcher/App/ConstraintPyImp.cpp b/src/Mod/Sketcher/App/ConstraintPyImp.cpp
index 7dad2b7..afdf185 100644
--- a/src/Mod/Sketcher/App/ConstraintPyImp.cpp
+++ b/src/Mod/Sketcher/App/ConstraintPyImp.cpp
@@ -124,6 +124,10 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
this->getConstraintPtr()->Type = Radius;
valid = true;
}
+ else if (strcmp("Diameter",ConstraintType) == 0) {
+ this->getConstraintPtr()->Type = Diameter;
+ valid = true;
+ }
if (valid) {
this->getConstraintPtr()->First = FirstIndex;
this->getConstraintPtr()->Value = Value;
diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp
index 608d9da..9bb542c 100644
--- a/src/Mod/Sketcher/App/Sketch.cpp
+++ b/src/Mod/Sketcher/App/Sketch.cpp
@@ -524,6 +524,9 @@ int Sketch::addConstraint(const Constraint *constraint)
case Radius:
rtn = addRadiusConstraint(constraint->First, constraint->Value);
break;
+ case Diameter:
+ rtn = addDiameterConstraint(constraint->First, constraint->Value);
+ break;
case Equal:
rtn = addEqualConstraint(constraint->First,constraint->Second);
break;
@@ -1319,6 +1322,31 @@ int Sketch::addRadiusConstraint(int geoId, double value)
return -1;
}
+int Sketch::addDiameterConstraint(int geoId, double value)
+{
+ geoId = checkGeoId(geoId);
+
+ if (Geoms[geoId].type == Circle) {
+ GCS::Circle &c = Circles[Geoms[geoId].index];
+ // add the parameter for the diameter
+ FixParameters.push_back(new double(value / 2.0));
+ double *radius = FixParameters[FixParameters.size()-1];
+ int tag = ++ConstraintsCounter;
+ GCSsys.addConstraintCircleRadius(c, radius, tag);
+ return ConstraintsCounter;
+ }
+ else if (Geoms[geoId].type == Arc) {
+ GCS::Arc &a = Arcs[Geoms[geoId].index];
+ // add the parameter for the diameter
+ FixParameters.push_back(new double(value / 2.0));
+ double *radius = FixParameters[FixParameters.size()-1];
+ int tag = ++ConstraintsCounter;
+ GCSsys.addConstraintArcRadius(a, radius, tag);
+ return ConstraintsCounter;
+ }
+ return -1;
+}
+
// line orientation angle constraint
int Sketch::addAngleConstraint(int geoId, double value)
{
diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h
index ec10842..763d565 100644
--- a/src/Mod/Sketcher/App/Sketch.h
+++ b/src/Mod/Sketcher/App/Sketch.h
@@ -160,6 +160,8 @@ public:
int addTangentConstraint(int geoId1, PointPos pos1, int geoId2, PointPos pos2);
/// add a radius constraint on a circle or an arc
int addRadiusConstraint(int geoId, double value);
+ /// add a diameter constraint on a circle or an arc
+ int addDiameterConstraint(int geoId, double value);
/// add an angle constraint on a line or between two lines
int addAngleConstraint(int geoId, double value);
int addAngleConstraint(int geoId1, int geoId2, double value);
diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp
index 95aa455..c589ddd 100644
--- a/src/Mod/Sketcher/App/SketchObject.cpp
+++ b/src/Mod/Sketcher/App/SketchObject.cpp
@@ -148,10 +148,11 @@ int SketchObject::setDatum(int ConstrId, double Datum)
type != DistanceX &&
type != DistanceY &&
type != Radius &&
+ type != Diameter &&
type != Angle)
return -1;
- if ((type == Distance || type == Radius) && Datum <= 0)
+ if ((type == Distance || type == Radius || type == Diameter) && Datum <= 0)
return (Datum == 0) ? -5 : -4;
// copy the list
diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp
index fd795eb..6cb691d 100644
--- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp
+++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp
@@ -1506,6 +1506,86 @@ bool CmdSketcherConstrainRadius::isActive(void)
return isCreateConstraintActive( getActiveGuiDocument() );
}
+DEF_STD_CMD_A(CmdSketcherConstrainDiameter);
+
+CmdSketcherConstrainDiameter::CmdSketcherConstrainDiameter()
+ :Command("Sketcher_ConstrainDiameter")
+{
+ sAppModule = "Sketcher";
+ sGroup = QT_TR_NOOP("Sketcher");
+ sMenuText = QT_TR_NOOP("Constrain diameter");
+ sToolTipText = QT_TR_NOOP("Fix the diameter of a circle or an arc");
+ sWhatsThis = sToolTipText;
+ sStatusTip = sToolTipText;
+ sPixmap = "Constraint_Diameter";
+ sAccel = "D";
+ eType = ForEdit;
+}
+
+void CmdSketcherConstrainDiameter::activated(int iMsg)
+{
+ // get the selection
+ std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
+
+ // only one sketch with its subelements are allowed to be selected
+ if (selection.size() != 1) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+ }
+
+ // get the needed lists and objects
+ const std::vector<std::string> &SubNames = selection[0].getSubNames();
+ Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
+
+ if (SubNames.size() != 1) {
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+ }
+
+ if (SubNames[0].size() > 4 && SubNames[0].substr(0,4) == "Edge") {
+ int GeoId = std::atoi(SubNames[0].substr(4,4000).c_str());
+
+ const Part::Geometry *geom = Obj->getGeometry(GeoId);
+ if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
+ const Part::GeomArcOfCircle *arc = dynamic_cast<const Part::GeomArcOfCircle *>(geom);
+ double ActDiameter = arc->getRadius() * 2.0;
+
+ openCommand("add diameter constraint");
+ Gui::Command::doCommand(
+ Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Diameter',%d,%f)) ",
+ selection[0].getFeatName(),GeoId,ActDiameter);
+ commitCommand();
+ //updateActive();
+ getSelection().clearSelection();
+ return;
+ }
+ else if (geom->getTypeId() == Part::GeomCircle::getClassTypeId()) {
+ const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geom);
+ double ActDiameter = circle->getRadius() * 2.0;
+
+ openCommand("add diameter constraint");
+ Gui::Command::doCommand(
+ Doc,"App.ActiveDocument.%s.addConstraint(Sketcher.Constraint('Diameter',%d,%f)) ",
+ selection[0].getFeatName(),GeoId,ActDiameter);
+ commitCommand();
+ //updateActive();
+ getSelection().clearSelection();
+ return;
+ }
+ }
+
+ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
+ QObject::tr("Select exactly one arc or circle from the sketch."));
+ return;
+}
+
+bool CmdSketcherConstrainDiameter::isActive(void)
+{
+ return isCreateConstraintActive( getActiveGuiDocument() );
+}
+
DEF_STD_CMD_A(CmdSketcherConstrainAngle);
@@ -1878,6 +1958,7 @@ void CreateSketcherCommandsConstraints(void)
rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceX());
rcCmdMgr.addCommand(new CmdSketcherConstrainDistanceY());
rcCmdMgr.addCommand(new CmdSketcherConstrainRadius());
+ rcCmdMgr.addCommand(new CmdSketcherConstrainDiameter());
rcCmdMgr.addCommand(new CmdSketcherConstrainAngle());
rcCmdMgr.addCommand(new CmdSketcherConstrainEqual());
rcCmdMgr.addCommand(new CmdSketcherConstrainPointOnObject());
diff --git a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
index 58f1f02..ce1a60b 100644
--- a/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
+++ b/src/Mod/Sketcher/Gui/EditDatumDialog.cpp
@@ -66,7 +66,8 @@ void EditDatumDialog::exec(bool atCursor)
// Return if constraint doesn't have editable value
if (Constr->Type == Sketcher::Distance ||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
- Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
+ Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Diameter ||
+ Constr->Type == Sketcher::Angle) {
if (vp->getSketchObject()->hasConflicts()) {
QMessageBox::critical(qApp->activeWindow(), QObject::tr("Distance constraint"),
diff --git a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
index bdc5ad8..a8eeef5 100644
--- a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
+++ b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc
@@ -15,6 +15,7 @@
<file>icons/small/Constraint_PointOnStart_sm.xpm</file>
<file>icons/small/Constraint_PointToObject_sm.xpm</file>
<file>icons/small/Constraint_Radius_sm.xpm</file>
+ <file>icons/small/Constraint_Diameter_sm.xpm</file>
<file>icons/small/Constraint_Tangent_sm.xpm</file>
<file>icons/small/Constraint_TangentToEnd_sm.xpm</file>
<file>icons/small/Constraint_TangentToStart_sm.xpm</file>
@@ -37,6 +38,7 @@
<file>icons/Constraint_PointOnStart.svg</file>
<file>icons/Constraint_PointToObject.svg</file>
<file>icons/Constraint_Radius.svg</file>
+ <file>icons/Constraint_Diameter.svg</file>
<file>icons/Constraint_Tangent.svg</file>
<file>icons/Constraint_TangentToEnd.svg</file>
<file>icons/Constraint_TangentToStart.svg</file>
diff --git a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
index 36c6057..08bf1e1 100644
--- a/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
+++ b/src/Mod/Sketcher/Gui/TaskSketcherConstrains.cpp
@@ -169,7 +169,8 @@ void TaskSketcherConstrains::on_listWidgetConstraints_itemActivated(QListWidgetI
// if its the right constraint
if (it->Type == Sketcher::Distance ||
it->Type == Sketcher::DistanceX || it->Type == Sketcher::DistanceY ||
- it->Type == Sketcher::Radius || it->Type == Sketcher::Angle) {
+ it->Type == Sketcher::Radius || it->Type == Sketcher::Diameter ||
+ it->Type == Sketcher::Angle) {
EditDatumDialog *editDatumDialog = new EditDatumDialog(this->sketchView, it->ConstraintNbr);
editDatumDialog->exec(false);
@@ -196,6 +197,7 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
QIcon tang ( Gui::BitmapFactory().pixmap("Constraint_Tangent") );
QIcon dist ( Gui::BitmapFactory().pixmap("Constraint_Length") );
QIcon radi ( Gui::BitmapFactory().pixmap("Constraint_Radius") );
+ QIcon diam ( Gui::BitmapFactory().pixmap("Constraint_Diameter") );
QIcon angl ( Gui::BitmapFactory().pixmap("Constraint_InternalAngle") );
QIcon equal( Gui::BitmapFactory().pixmap("Constraint_EqualLength") );
QIcon pntoo( Gui::BitmapFactory().pixmap("Constraint_PointOnObject") );
@@ -278,6 +280,12 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
ui->listWidgetConstraints->addItem(new ConstraintItem(radi,name,i-1,(*it)->Type));
}
break;
+ case Sketcher::Diameter:
+ if(Filter<3 || (*it)->Name != ""){
+ name = QString::fromLatin1("%1 (%2)").arg(name).arg((*it)->Value);
+ ui->listWidgetConstraints->addItem(new ConstraintItem(diam,name,i-1,(*it)->Type));
+ }
+ break;
case Sketcher::Angle:
if(Filter<3 || (*it)->Name != ""){
name = QString::fromLatin1("%1 (%2)").arg(name).arg(Base::toDegrees<double>(std::abs((*it)->Value)));
diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
index ee289f1..23aca8a 100644
--- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
+++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
@@ -726,7 +726,8 @@ void ViewProviderSketch::editDoubleClicked(void)
// if its the right constraint
if (Constr->Type == Sketcher::Distance ||
Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY ||
- Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) {
+ Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Diameter ||
+ Constr->Type == Sketcher::Angle) {
EditDatumDialog * editDatumDialog = new EditDatumDialog(this, edit->PreselectConstraint);
SoIdleSensor* sensor = new SoIdleSensor(EditDatumDialog::run, editDatumDialog);
@@ -870,7 +871,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
Constraint *Constr = constrlist[constNum];
if (Constr->Type == Distance || Constr->Type == DistanceX || Constr->Type == DistanceY ||
- Constr->Type == Radius) {
+ Constr->Type == Radius || Constr->Type == Diameter) {
int intGeoCount = getSketchObject()->getHighestCurveIndex() + 1;
int extGeoCount = getSketchObject()->getExternalGeometryCount();
@@ -927,14 +928,14 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2D &toPo
Base::Vector3d vec = Base::Vector3d(toPos.fX, toPos.fY, 0) - p2;
Base::Vector3d dir;
- if (Constr->Type == Distance || Constr->Type == Radius)
+ if (Constr->Type == Distance || Constr->Type == Radius || Constr->Type == Diameter)
dir = (p2-p1).Normalize();
else if (Constr->Type == DistanceX)
dir = Base::Vector3d( (p2.x - p1.x >= FLT_EPSILON) ? 1 : -1, 0, 0);
else if (Constr->Type == DistanceY)
dir = Base::Vector3d(0, (p2.y - p1.y >= FLT_EPSILON) ? 1 : -1, 0);
- if (Constr->Type == Radius)
+ if (Constr->Type == Radius || Constr->Type == Diameter)
Constr->LabelDistance = vec.x * dir.x + vec.y * dir.y;
else {
Base::Vector3d norm(-dir.y,dir.x,0);
@@ -1417,7 +1418,7 @@ void ViewProviderSketch::updateColor(void)
// Check Constraint Type
ConstraintType type = getSketchObject()->Constraints.getValues()[i]->Type;
bool hasDatumLabel = (type == Sketcher::Angle ||
- type == Sketcher::Radius ||
+ type == Sketcher::Radius || type == Sketcher::Diameter ||
type == Sketcher::Distance || type == Sketcher::DistanceX || type == Sketcher::DistanceY);
if (edit->SelConstraintSet.find(i) != edit->SelConstraintSet.end()) {
@@ -2436,6 +2437,7 @@ Restart:
}
break;
case Radius:
+ case Diameter:
{
assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount);
@@ -2451,6 +2453,8 @@ Restart:
double angle = (startangle + endangle)/2;
pnt1 = arc->getCenter();
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
+ if (Constr->Type == Diameter)
+ pnt1 = pnt1 - radius * Base::Vector3d(cos(angle),sin(angle),0.);
}
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = dynamic_cast<const Part::GeomCircle *>(geo);
@@ -2458,6 +2462,8 @@ Restart:
double angle = M_PI/4;
pnt1 = circle->getCenter();
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle),sin(angle),0.);
+ if (Constr->Type == Diameter)
+ pnt1 = pnt1 - radius * Base::Vector3d(cos(angle),sin(angle),0.);
} else
break;
} else
@@ -2572,6 +2578,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case DistanceX:
case DistanceY:
case Radius:
+ case Diameter:
case Angle:
{
SoSeparator *sepDatum = new SoSeparator();
diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp
index 15a285f..65292a2 100644
--- a/src/Mod/Sketcher/Gui/Workbench.cpp
+++ b/src/Mod/Sketcher/Gui/Workbench.cpp
@@ -83,6 +83,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
+ << "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainAngle"
@@ -136,6 +137,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
+ << "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainAngle"
|
|
|
Why not limiting this even more to the Gui. It is just a helper for the user for not multiplying by 2. It could all stay in the Gui we don't need a new constraint type for this in App. But in general, since it is only a multiplication by 2 I am not sure if it deserves a button in the sketcher toolbar. One solution would be to use the length/distance button to trigger this case. |
|
|
Yes putting it in the Gui is fine. For example in AD Inventor the right-click menu brings up the option to switch a dimension between radius and diameter. Though even if internally there is only one constraint, the actual display in the sketcher will have to change from a radius to a diameter dimension. |
|
|
I think it would be good if the user could drag the radius constraint and it automatically converts to the diameter constraint (vice versa). It would be more convenient and more intuitive in my opinion than other toolbar icon. Would FreeGCS be robust to do this change instantaneously? |
|
|
This patch is quit old now? Any further action? |
|
|
I didn't like that this patch duplicates a lot of code.I would rather make the radius constraint toggle-able to diameter-mode rather than adding one more constraint in the App level. My recommendation is not to apply the patch as is. |
|
|
Ok |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2012-05-05 10:57 | jrheinlaender | New Issue | |
| 2012-05-05 10:57 | jrheinlaender | File Added: constraint_diameter.diff | |
| 2012-05-05 10:59 | jrheinlaender | File Added: Constraint_Diameter.svg | |
| 2012-05-05 11:03 | jrheinlaender | File Added: Constraint_Diameter_sm.xpm | |
| 2012-05-05 17:50 | yorik | Project | FreeCAD => Sketcher |
| 2012-05-06 11:59 |
|
Status | new => assigned |
| 2012-05-06 11:59 |
|
Assigned To | => Jriegel |
| 2012-05-14 11:47 | logari81 | Note Added: 0002044 | |
| 2012-05-14 11:47 | logari81 | Assigned To | Jriegel => logari81 |
| 2012-05-14 11:47 | logari81 | Summary | Adding constraint for diameter of circle or arc => Sketcher: Adding constraint for diameter of circle or arc |
| 2012-05-14 13:22 | jrheinlaender | Note Added: 0002045 | |
| 2012-05-14 13:30 | jrheinlaender | File Added: constraint_diameter_2.diff | |
| 2012-12-20 21:07 | logari81 | Note Added: 0002714 | |
| 2012-12-21 09:24 | jrheinlaender | Note Added: 0002739 | |
| 2012-12-23 16:25 | mrlukeparry | Note Added: 0002758 | |
| 2014-01-12 17:55 |
|
Note Added: 0004055 | |
| 2014-01-12 18:11 | logari81 | Note Added: 0004059 | |
| 2014-01-12 22:09 |
|
Note Added: 0004068 | |
| 2014-01-12 22:09 |
|
Status | assigned => closed |
| 2014-01-12 22:09 |
|
Resolution | open => won't fix |
FreeCAD