View Issue Details

IDProjectCategoryView StatusLast Update
0000695SketcherPatchpublic2014-01-12 22:09
Reporterjrheinlaender Assigned Tologari81  
PrioritynormalSeverityfeatureReproducibilityalways
Status closedResolutionwon't fix 
Summary0000695: Sketcher: Adding constraint for diameter of circle or arc
DescriptionThis patch adds a new diameter constraint to the sketcher.
The code is copied and adapter from the radius constraint with minimal changes
Additional InformationAttached the patch and two icons
TagsNo tags attached.
FreeCAD Information

Activities

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 &params, 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 &params, 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"
constraint_diameter.diff (22,426 bytes)   

2012-05-05 10:59

 

Constraint_Diameter.svg (11,317 bytes)

2012-05-05 11:03

 

logari81

2012-05-14 11:47

developer   ~0002044

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.

jrheinlaender

2012-05-14 13:22

developer   ~0002045

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"
constraint_diameter_2.diff (18,122 bytes)   

logari81

2012-12-20 21:07

developer   ~0002714

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.

jrheinlaender

2012-12-21 09:24

developer   ~0002739

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.

mrlukeparry

2012-12-23 16:25

developer   ~0002758

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?

Jriegel

2014-01-12 17:55

administrator   ~0004055

This patch is quit old now?

Any further action?

logari81

2014-01-12 18:11

developer   ~0004059

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.

Jriegel

2014-01-12 22:09

administrator   ~0004068

Ok

Issue History

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 Jriegel Status new => assigned
2012-05-06 11:59 Jriegel 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 Jriegel Note Added: 0004055
2014-01-12 18:11 logari81 Note Added: 0004059
2014-01-12 22:09 Jriegel Note Added: 0004068
2014-01-12 22:09 Jriegel Status assigned => closed
2014-01-12 22:09 Jriegel Resolution open => won't fix