Sketcher: Unit independent pole weight for B-Splines (Weight constraint)

========================================================================

Until now BSpline poles were circles relying on physical length units. This lead to several
problems:
- While the BSpline weight follows the circle size, weights do not have length units, but are adimensinal
- As representation of the BSpline depends on the physical size of the circle, the numerical value to be
  set to a pole circle differs from the numerical value of the weight.

The present commit:
1. Separates pole circle representation (physical size), from the numerical value used in the radius constraint,
so that the value in the constraint is the weight, the value representation is a factor of the weight value (in this
commit is getScaleFactor(), but this will change in the next commit). Dragging accounts for this scale factor too.
2. While Radius constraint button is used to constraint a B-Spline weight as before, this creates a Weight constraint,
which is a new type of constraint. This is done so that the value is truly adimensional and is so presented in all kind
of editors that rely on the units indicated by the constraint. It is obviously also shown as adimensional (thus without units),
in the 3D view and in the datum dialogs.
3. Because the circle of the pole of a B-Spline is not a geometric circle, but a graphical representation of the pole and how
it affects the corresponding B-Spline, constraint creation commands are limited so that no point on object, tangent, perpendicular
or SnellLaw constraints can be created on a B-Spline weight circle. This is also the case for the Diameter constraint, which won't
accept the circle. Equality constraints work either on only circles or only weights, but not on a mixture of them.

Bonus: This commit fixes a bug in master, that using the select equality constraint then click in two geometric elements mode, you
could make a circle equal to an ellipse resulting in malformed solver constraints.
This commit is contained in:
Abdullah Tahiri
2020-12-10 18:34:06 +01:00
committed by abdullahtahiriyo
parent 8080e8df90
commit 95c1a262b7
11 changed files with 444 additions and 85 deletions
+1
View File
@@ -126,6 +126,7 @@ Quantity Constraint::getPresentationValue() const
quantity.setUnit(Unit::Angle);
break;
case SnellsLaw:
case Weight:
quantity.setValue(Value);
break;
default:
+2 -1
View File
@@ -57,6 +57,7 @@ enum ConstraintType {
SnellsLaw = 16,
Block = 17,
Diameter = 18,
Weight = 19,
NumConstraintTypes // must be the last item!
};
@@ -117,7 +118,7 @@ public:
inline bool isDimensional() const {
return Type == Distance || Type == DistanceX || Type == DistanceY ||
Type == Radius || Type == Diameter || Type == Angle || Type == SnellsLaw;
Type == Radius || Type == Diameter || Type == Angle || Type == SnellsLaw || Type == Weight;
}
friend class PropertyConstraintList;
+9
View File
@@ -169,6 +169,13 @@ int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/)
this->getConstraintPtr()->LabelPosition = 10;
valid = true;
}
else if (strcmp("Weight",ConstraintType) == 0) {
this->getConstraintPtr()->Type = Weight;
// set a value that is out of range of result of atan2
// this value is handled in ViewProviderSketch
this->getConstraintPtr()->LabelPosition = 10;
valid = true;
}
if (valid) {
this->getConstraintPtr()->First = FirstIndex;
this->getConstraintPtr()->setValue(Value);
@@ -503,6 +510,7 @@ std::string ConstraintPy::representation(void) const
case Block : result << "'Block' (" << getConstraintPtr()->First << ")>";break;
case Radius : result << "'Radius'>";break;
case Diameter : result << "'Diameter'>";break;
case Weight : result << "'Weight'>";break;
case Parallel : result << "'Parallel'>";break;
case Tangent :
if (this->getConstraintPtr()->Third == Constraint::GeoUndef)
@@ -554,6 +562,7 @@ Py::String ConstraintPy::getType(void) const
case Block : return Py::String("Block");break;
case Radius : return Py::String("Radius");break;
case Diameter : return Py::String("Diameter");break;
case Weight : return Py::String("Weight");break;
case Parallel : return Py::String("Parallel");break;
case Tangent : return Py::String("Tangent");break;
case Perpendicular : return Py::String("Perpendicular");break;
+13
View File
@@ -1406,6 +1406,19 @@ int Sketch::addConstraint(const Constraint *constraint)
rtn = addDiameterConstraint(constraint->First, c.value,c.driving);
break;
}
case Weight:
{
c.value = new double(constraint->getValue());
if(c.driving)
FixParameters.push_back(c.value);
else {
Parameters.push_back(c.value);
DrivenParameters.push_back(c.value);
}
rtn = addRadiusConstraint(constraint->First, c.value,c.driving);
break;
}
case Equal:
rtn = addEqualConstraint(constraint->First,constraint->Second);
break;
+40 -16
View File
@@ -327,7 +327,7 @@ int SketchObject::setDatum(int ConstrId, double Datum)
type != Perpendicular)
return -1;
if ((type == Distance || type == Radius || type == Diameter) && Datum <= 0)
if ((type == Distance || type == Radius || type == Diameter || type == Weight) && Datum <= 0)
return (Datum == 0) ? -5 : -4;
// copy the list
@@ -1243,6 +1243,9 @@ void SketchObject::addGeometryState(const Constraint* cstr) const
{
auto gf = GeometryFacade::getFacade(vals[cstr->First]);
gf->setInternalType(InternalType::BSplineControlPoint);
// handle constraint as adimensional
break;
}
case BSplineKnotPoint:
@@ -3839,6 +3842,7 @@ int SketchObject::addSymmetric(const std::vector<int> &geoIdList, int refGeoId,
(*it)->Type == Sketcher::Equal ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Weight ||
(*it)->Type == Sketcher::Angle ||
(*it)->Type == Sketcher::PointOnObject ){
Constraint *constNew = (*it)->copy();
@@ -4133,9 +4137,10 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
if( ((*it)->Type != Sketcher::DistanceX && (*it)->Type != Sketcher::DistanceY ) ||
(*it)->FirstPos == Sketcher::none ) { // if it is not a point locking DistanceX/Y
if (((*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Distance ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Distance ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Weight ||
(*it)->Type == Sketcher::Radius ) && clone ) {
// Distances on a single Element are mapped to equality constraints in clone mode
Constraint *constNew = (*it)->copy();
@@ -4831,12 +4836,9 @@ int SketchObject::exposeInternalGeometry(int GeoId)
// search for first pole weight constraint
for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin();
it != vals.end(); ++it) {
if((*it)->Type == Sketcher::Radius && (*it)->First == controlpointgeoids[0]) {
if((*it)->Type == Sketcher::Weight && (*it)->First == controlpointgeoids[0]) {
isfirstweightconstrained = true ;
}
else if((*it)->Type == Sketcher::Diameter && (*it)->First == controlpointgeoids[0]) {
isfirstweightconstrained = true ;
}
}
}
@@ -5218,8 +5220,8 @@ int SketchObject::deleteUnusedInternalGeometry(int GeoId, bool delgeoid)
}
}
// ignore radii and diameters
else if (((*itc)->Type!=Sketcher::Radius && (*itc)->Type!=Sketcher::Diameter) && ( (*itc)->Second == (*it) || (*itc)->First == (*it) || (*itc)->Third == (*it)) ) {
// ignore weight constraints
else if (((*itc)->Type!=Sketcher::Weight) && ( (*itc)->Second == (*it) || (*itc)->First == (*it) || (*itc)->Third == (*it)) ) {
(*ita)++;
}
}
@@ -5756,6 +5758,7 @@ int SketchObject::carbonCopy(App::DocumentObject * pObj, bool construction)
if ((*it)->Type == Sketcher::Distance ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Weight ||
(*it)->Type == Sketcher::Angle ||
(*it)->Type == Sketcher::SnellsLaw ||
(*it)->Type == Sketcher::DistanceX ||
@@ -7067,6 +7070,7 @@ bool SketchObject::evaluateConstraint(const Constraint *constraint) const
switch (constraint->Type) {
case Radius:
case Diameter:
case Weight:
case Horizontal:
case Vertical:
case Distance:
@@ -7487,16 +7491,39 @@ void SketchObject::restoreFinished()
void SketchObject::migrateSketch(void)
{
bool updateGeoState = false;
bool noextensions = false;
for( const auto & g : getInternalGeometry() )
if(!g->hasExtension(SketchGeometryExtension::getClassTypeId())) // no extension - legacy file
updateGeoState = true;
noextensions = true;
if(updateGeoState) {
if(noextensions) {
for( auto c : Constraints.getValues()) {
addGeometryState(c);
// Convert B-Spline controlpoints radius/diameter constraints to Weight cosntraints
if(c->Type == InternalAlignment && c->AlignmentType == BSplineControlPoint) {
int circlegeoid = c->First;
int bsplinegeoid = c->Second;
auto bsp = static_cast<const Part::GeomBSplineCurve*>(getGeometry(bsplinegeoid));
std::vector<double> weights = bsp->getWeights();
for( auto ccp : Constraints.getValues()) {
if( (ccp->Type == Radius || ccp->Type == Diameter ) &&
ccp->First == circlegeoid ) {
if(c->InternalAlignmentIndex < int(weights.size())) {
ccp->Type = Weight;
ccp->setValue(weights[c->InternalAlignmentIndex]);
}
}
}
}
}
}
}
@@ -7912,9 +7939,6 @@ int SketchObject::getGeometryId(int GeoId, long &id) const
return 0;
}
// Python Sketcher feature ---------------------------------------------------------
namespace App {
+240 -30
View File
@@ -45,6 +45,7 @@
#include <Mod/Part/App/Geometry.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/Sketcher/App/Sketch.h>
#include <Mod/Sketcher/App/GeometryFacade.h>
#include "ViewProviderSketch.h"
#include "DrawSketchHandler.h"
@@ -255,6 +256,20 @@ bool SketcherGui::IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher
return Obj->isPointOnCurve(GeoIdCurve, p.x, p.y);
}
bool SketcherGui::isBsplinePole(const Part::Geometry * geo)
{
auto gf = GeometryFacade::getFacade(geo);
return gf->getInternalType() == InternalType::BSplineControlPoint;
}
bool SketcherGui::isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId)
{
auto geom = Obj->getGeometry(GeoId);
return isBsplinePole(geom);
}
bool SketcherGui::ReleaseHandler(Gui::Document* doc) {
if (doc) {
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
@@ -2655,6 +2670,14 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg)
continue;
}
if( geom && isBsplinePole(geom)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
abortCommand();
continue;
}
cnt++;
Gui::cmdAppObjectArgs(selection[0].getObject(),"addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
points[iPnt].GeoId, points[iPnt].PosId, curves[iCrv].GeoId);
@@ -2668,9 +2691,10 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg)
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("None of the selected points were constrained "
"onto the respective curves, "
"either because they are parts "
"because they are parts "
"of the same element, "
"or because they are both external geometry."));
"because they are both external geometry, "
"or because the edge is not eligible."));
}
return;
}
@@ -2730,6 +2754,14 @@ void CmdSketcherConstrainPointOnObject::applyConstraint(std::vector<SelIdPair> &
return;
}
if( geom && isBsplinePole(geom)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
abortCommand();
return;
}
if (allOK) {
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('PointOnObject',%d,%d,%d)) ",
GeoIdVt, PosIdVt, GeoIdCrv);
@@ -3508,6 +3540,12 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add perpendicular constraint"));
try{
@@ -3607,6 +3645,12 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
return;
}
if(isBsplinePole(geom2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add perpendicularity constraint"));
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Perpendicular',%d,%d,%d)) ",
GeoId1,PosId1,GeoId2);
@@ -3643,6 +3687,12 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId())
std::swap(GeoId1,GeoId2);
if(isBsplinePole(Obj, GeoId1)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
// GeoId2 is the line
geo1 = Obj->getGeometry(GeoId1);
geo2 = Obj->getGeometry(GeoId2);
@@ -3818,6 +3868,12 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector<SelIdPair> &
if (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId())
std::swap(GeoId1,GeoId2);
if(isBsplinePole(Obj, GeoId1)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
// GeoId2 is the line
geo1 = Obj->getGeometry(GeoId1);
geo2 = Obj->getGeometry(GeoId2);
@@ -3963,6 +4019,12 @@ void CmdSketcherConstrainPerpendicular::applyConstraint(std::vector<SelIdPair> &
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add perpendicular constraint"));
try{
@@ -4112,6 +4174,12 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add tangent constraint"));
try{
@@ -4194,6 +4262,12 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
return;
}
if(isBsplinePole(geom2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add tangent constraint"));
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Tangent',%d,%d,%d)) ",
GeoId1,PosId1,GeoId2);
@@ -4218,6 +4292,11 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
return;
}
if(isBsplinePole(geom1) || isBsplinePole(geom2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
// check if there is a coincidence constraint on GeoId1, GeoId2
const std::vector< Constraint * > &cvals = Obj->Constraints.getValues();
@@ -4437,6 +4516,12 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector<SelIdPair> &selSeq
return;
}
if(isBsplinePole(geom1) || isBsplinePole(geom2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
if( geom1 && geom2 &&
( geom1->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
@@ -4606,6 +4691,12 @@ void CmdSketcherConstrainTangent::applyConstraint(std::vector<SelIdPair> &selSeq
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
openCommand(QT_TRANSLATE_NOOP("Command", "Add tangent constraint"));
try{
@@ -4667,8 +4758,8 @@ CmdSketcherConstrainRadius::CmdSketcherConstrainRadius()
{
sAppModule = "Sketcher";
sGroup = QT_TR_NOOP("Sketcher");
sMenuText = QT_TR_NOOP("Constrain radius");
sToolTipText = QT_TR_NOOP("Fix the radius of a circle or an arc");
sMenuText = QT_TR_NOOP("Constrain radius or weight");
sToolTipText = QT_TR_NOOP("Fix the radius of a circle or an arc or fix the weight of a pole of a B-Spline");
sWhatsThis = "Sketcher_ConstrainRadius";
sStatusTip = sToolTipText;
sPixmap = "Constraint_Radius";
@@ -4715,6 +4806,9 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
std::vector< std::pair<int, double> > geoIdRadiusMap;
std::vector< std::pair<int, double> > externalGeoIdRadiusMap;
bool poles = false;
bool nonpoles = false;
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) {
bool issegmentfixed = false;
int GeoId;
@@ -4742,6 +4836,8 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
else {
geoIdRadiusMap.push_back(std::make_pair(GeoId, radius));
}
nonpoles = true;
}
else if (geom && geom->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = static_cast<const Part::GeomCircle *>(geom);
@@ -4753,6 +4849,11 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
else {
geoIdRadiusMap.push_back(std::make_pair(GeoId, radius));
}
if(isBsplinePole(geom))
poles = true;
else
nonpoles = true;
}
}
@@ -4761,6 +4862,12 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
QObject::tr("Select one or more arcs or circles from the sketch."));
}
if(poles && nonpoles) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select either only one or more B-Spline poles or only one or more arcs or circles from the sketch, but not mixed."));
return;
}
bool commitNeeded=false;
bool updateNeeded=false;
bool commandopened=false;
@@ -4772,8 +4879,13 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
unsigned int constrSize = 0;
for (std::vector< std::pair<int, double> >::iterator it = externalGeoIdRadiusMap.begin(); it != externalGeoIdRadiusMap.end(); ++it) {
Gui::cmdAppObjectArgs(selection[0].getObject(),"addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
it->first,it->second);
if(nonpoles)
Gui::cmdAppObjectArgs(selection[0].getObject(),"addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
it->first,it->second);
else
Gui::cmdAppObjectArgs(selection[0].getObject(),"addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
it->first,it->second);
const std::vector<Sketcher::Constraint *> &ConStr = Obj->Constraints.getValues();
@@ -4829,8 +4941,12 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
if(!commandopened)
openCommand(QT_TRANSLATE_NOOP("Command", "Add radius constraint"));
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
refGeoId,radius);
if(nonpoles)
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
refGeoId,radius);
else
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
refGeoId,radius);
// Add the equality constraints
for (std::vector< std::pair<int, double> >::iterator it = geoIdRadiusMap.begin()+1; it != geoIdRadiusMap.end(); ++it) {
@@ -4844,8 +4960,12 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
if(!commandopened)
openCommand(QT_TRANSLATE_NOOP("Command", "Add radius constraint"));
for (std::vector< std::pair<int, double> >::iterator it = geoIdRadiusMap.begin(); it != geoIdRadiusMap.end(); ++it) {
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
it->first,it->second);
if(nonpoles)
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
it->first,it->second);
else
Gui::cmdAppObjectArgs(selection[0].getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
it->first,it->second);
if (constraintCreationMode==Reference) {
const std::vector<Sketcher::Constraint *> &ConStr = Obj->Constraints.getValues();
@@ -4878,12 +4998,20 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
QDialog dlg(Gui::getMainWindow());
Ui::InsertDatum ui_Datum;
ui_Datum.setupUi(&dlg);
dlg.setWindowTitle(EditDatumDialog::tr("Change radius"));
ui_Datum.label->setText(EditDatumDialog::tr("Radius:"));
Base::Quantity init_val;
init_val.setUnit(Base::Unit::Length);
init_val.setValue(geoIdRadiusMap.front().second);
if(poles) {
dlg.setWindowTitle(EditDatumDialog::tr("Change weight"));
ui_Datum.label->setText(EditDatumDialog::tr("Weight:"));
}
else{
dlg.setWindowTitle(EditDatumDialog::tr("Change radius"));
ui_Datum.label->setText(EditDatumDialog::tr("Radius:"));
init_val.setUnit(Base::Unit::Length);
}
ui_Datum.labelEdit->setValue(init_val);
ui_Datum.labelEdit->selectNumber();
if (constrainEqual || geoIdRadiusMap.size() == 1)
@@ -4989,7 +5117,14 @@ void CmdSketcherConstrainRadius::applyConstraint(std::vector<SelIdPair> &selSeq,
// Create the radius constraint now
openCommand(QT_TRANSLATE_NOOP("Command", "Add radius constraint"));
Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
bool ispole = isBsplinePole(geom);
if(ispole)
Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
GeoId, radius);
else
Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
GeoId, radius);
const std::vector<Sketcher::Constraint *> &ConStr = Obj->Constraints.getValues();
@@ -5022,10 +5157,19 @@ void CmdSketcherConstrainRadius::applyConstraint(std::vector<SelIdPair> &selSeq,
QDialog dlg(Gui::getMainWindow());
Ui::InsertDatum ui_Datum;
ui_Datum.setupUi(&dlg);
dlg.setWindowTitle(EditDatumDialog::tr("Change radius"));
ui_Datum.label->setText(EditDatumDialog::tr("Radius:"));
Base::Quantity init_val;
init_val.setUnit(Base::Unit::Length);
if(ispole) {
dlg.setWindowTitle(EditDatumDialog::tr("Change weight"));
ui_Datum.label->setText(EditDatumDialog::tr("Weight:"));
}
else{
dlg.setWindowTitle(EditDatumDialog::tr("Change radius"));
ui_Datum.label->setText(EditDatumDialog::tr("Radius:"));
init_val.setUnit(Base::Unit::Length);
}
init_val.setValue(radius);
ui_Datum.labelEdit->setValue(init_val);
@@ -5205,6 +5349,12 @@ void CmdSketcherConstrainDiameter::activated(int iMsg)
const Part::GeomCircle *circle = static_cast<const Part::GeomCircle *>(geom);
double radius = circle->getRadius();
if(isBsplinePole(geom)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
continue;
}
if(issegmentfixed) {
externalGeoIdDiameterMap.push_back(std::make_pair(GeoId, 2*radius));
}
@@ -5444,6 +5594,12 @@ void CmdSketcherConstrainDiameter::applyConstraint(std::vector<SelIdPair> &selSe
return;
}
if(isBsplinePole(geom)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
// Create the diameter constraint now
openCommand(QT_TRANSLATE_NOOP("Command", "Add diameter constraint"));
Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Diameter',%d,%f)) ",
@@ -5768,6 +5924,13 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
bool bothexternal=areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2);
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
double ActAngle = 0.0;
openCommand(QT_TRANSLATE_NOOP("Command", "Add angle constraint"));
@@ -5824,6 +5987,12 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
std::swap(PosId1,PosId2);
}
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
if (isEdge(GeoId2,PosId2)) { // line to line angle
const Part::Geometry *geom1 = Obj->getGeometry(GeoId1);
@@ -6109,6 +6278,13 @@ void CmdSketcherConstrainAngle::applyConstraint(std::vector<SelIdPair> &selSeq,
bool bothexternal=areBothPointsOrSegmentsFixed(Obj,GeoId1, GeoId2);
if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2) && isVertex(GeoId3, PosId3)) {
if(isBsplinePole(Obj, GeoId1) || isBsplinePole(Obj, GeoId2)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
double ActAngle = 0.0;
openCommand(QT_TRANSLATE_NOOP("Command", "Add angle constraint"));
@@ -6241,7 +6417,7 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
std::vector<int> ids;
bool lineSel = false, arcSel = false, circSel = false, ellipsSel = false, arcEllipsSel=false, hasAlreadyExternal = false;
bool hyperbSel = false, parabSel=false;
bool hyperbSel = false, parabSel=false, weightSel=false;
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
@@ -6279,20 +6455,30 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
return;
}
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId())
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
lineSel = true;
else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
}
else if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
arcSel = true;
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId())
circSel = true;
else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId())
}
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
if(isBsplinePole(geo))
weightSel = true;
else
circSel = true;
}
else if (geo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
ellipsSel = true;
else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId())
}
else if (geo->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) {
arcEllipsSel = true;
else if (geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId())
}
else if (geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()) {
hyperbSel = true;
else if (geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId())
}
else if (geo->getTypeId() == Part::GeomArcOfParabola::getClassTypeId()) {
parabSel = true;
}
else {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select two or more edges of similar type"));
@@ -6303,10 +6489,11 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
}
// Check for heterogeneous groups in selection
if ( (lineSel && ((arcSel || circSel) || (ellipsSel || arcEllipsSel) || hyperbSel || parabSel) ) ||
((arcSel || circSel) && ((ellipsSel || arcEllipsSel) || hyperbSel || parabSel)) ||
((ellipsSel || arcEllipsSel) && (hyperbSel || parabSel)) ||
(hyperbSel && parabSel) ) {
if ( (lineSel && ((arcSel || circSel) || (ellipsSel || arcEllipsSel) || hyperbSel || parabSel || weightSel) ) ||
((arcSel || circSel) && ((ellipsSel || arcEllipsSel) || hyperbSel || parabSel || weightSel)) ||
((ellipsSel || arcEllipsSel) && (hyperbSel || parabSel || weightSel)) ||
( hyperbSel && (parabSel || weightSel)) ||
( parabSel && weightSel)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select two or more edges of similar type"));
@@ -6348,6 +6535,23 @@ void CmdSketcherConstrainEqual::applyConstraint(std::vector<SelIdPair> &selSeq,
return;
}
const Part::Geometry *geo1 = Obj->getGeometry(GeoId1);
const Part::Geometry *geo2 = Obj->getGeometry(GeoId2);
if ( (geo1->getTypeId() == Part::GeomLineSegment::getClassTypeId() && geo2->getTypeId() != Part::GeomLineSegment::getClassTypeId()) ||
(geo1->getTypeId() == Part::GeomHyperbola::getClassTypeId() && geo2->getTypeId() != Part::GeomHyperbola::getClassTypeId()) ||
(geo1->getTypeId() == Part::GeomParabola::getClassTypeId() && geo2->getTypeId() != Part::GeomParabola::getClassTypeId()) ||
(isBsplinePole(geo1) && !isBsplinePole(geo1)) ||
( (geo1->getTypeId() == Part::GeomCircle::getClassTypeId() || geo1->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) &&
(geo2->getTypeId() != Part::GeomCircle::getClassTypeId() || geo2->getTypeId() != Part::GeomArcOfCircle::getClassTypeId())) ||
( (geo1->getTypeId() == Part::GeomEllipse::getClassTypeId() || geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) &&
(geo2->getTypeId() != Part::GeomEllipse::getClassTypeId() || geo2->getTypeId() != Part::GeomArcOfEllipse::getClassTypeId())) ){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select two or more edges of similar type"));
return;
}
// undo command open
openCommand(QT_TRANSLATE_NOOP("Command", "Add equality constraint"));
Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
@@ -6745,6 +6949,12 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg)
return;
}
if(isBsplinePole(geo)) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select an edge that is not a B-spline weight"));
return;
}
double n2divn1=0;
//the essence.
@@ -51,6 +51,10 @@ bool isConstructionPoint(const Sketcher::SketchObject* Obj, int GeoId);
bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj);
bool isBsplinePole(const Part::Geometry * geo);
bool isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId);
/// Release any currently-active handler for the document.
/// Returns true if a handler was released, and false if not
bool ReleaseHandler(Gui::Document* doc);
+2 -23
View File
@@ -4134,33 +4134,12 @@ public:
//Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add Pole circle"));
//Add pole
double guess = (EditCurve[1]-EditCurve[0]).Length()/6;
auto normalize = [](double guess) {
double units=1.0;
while (guess >= 10.0) {
guess /= 10.0;
units*=10.0;
}
while (guess < 1.0) {
guess *= 10.0;
units/=10.0;
}
return round(guess)*units;
};
guess = normalize(guess);
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
EditCurve[EditCurve.size()-1].x,EditCurve[EditCurve.size()-1].y);
if(EditCurve.size() == 2) {
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Radius',%d,%f)) ",
FirstPoleGeoId, guess );
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
FirstPoleGeoId, 1.0 ); // First pole defaults to 1.0 weight
}
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
+12 -2
View File
@@ -38,6 +38,7 @@
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/Sketcher/App/GeometryFacade.h>
#include "ViewProviderSketch.h"
#include "ui_InsertDatum.h"
@@ -81,13 +82,14 @@ void EditDatumDialog::exec(bool atCursor)
return;
}
Base::Quantity init_val;
QDialog dlg(Gui::getMainWindow());
if (ui_ins_datum == nullptr) {
ui_ins_datum.reset(new Ui_InsertDatum);
ui_ins_datum->setupUi(&dlg);
}
double datum = Constr->getValue();
Base::Quantity init_val;
if (Constr->Type == Sketcher::Angle) {
datum = Base::toDegrees<double>(datum);
@@ -108,6 +110,11 @@ void EditDatumDialog::exec(bool atCursor)
ui_ins_datum->label->setText(tr("Diameter:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
else if (Constr->Type == Sketcher::Weight) {
dlg.setWindowTitle(tr("Insert weight"));
ui_ins_datum->label->setText(tr("Weight:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherWeight"));
}
else if (Constr->Type == Sketcher::SnellsLaw) {
dlg.setWindowTitle(tr("Refractive index ratio", "Constraint_SnellsLaw"));
ui_ins_datum->label->setText(tr("Ratio n2/n1:", "Constraint_SnellsLaw"));
@@ -155,7 +162,10 @@ void EditDatumDialog::exec(bool atCursor)
void EditDatumDialog::accepted()
{
Base::Quantity newQuant = ui_ins_datum->labelEdit->value();
if (newQuant.isQuantity() || (Constr->Type == Sketcher::SnellsLaw && newQuant.isDimensionless())) {
if( newQuant.isQuantity() ||
(Constr->Type == Sketcher::SnellsLaw && newQuant.isDimensionless()) ||
(Constr->Type == Sketcher::Weight && newQuant.isDimensionless())) {
// save the value for the history
ui_ins_datum->labelEdit->pushToHistory();
@@ -138,6 +138,7 @@ public:
case Sketcher::DistanceX:
case Sketcher::DistanceY:
case Sketcher::Radius:
case Sketcher::Weight:
case Sketcher::Diameter:
case Sketcher::Angle:
name = QString::fromLatin1("%1 (%2)").arg(name).arg(constraint->getPresentationValue().getUserString());
@@ -257,6 +258,7 @@ public:
case Sketcher::DistanceY:
return selicon(constraint,vdist,vdist_driven);
case Sketcher::Radius:
case Sketcher::Weight:
return selicon(constraint,radi,radi_driven);
case Sketcher::Diameter:
return selicon(constraint,dia,dia_driven);
@@ -326,6 +328,7 @@ public:
case Sketcher::DistanceY:
case Sketcher::Radius:
case Sketcher::Diameter:
case Sketcher::Weight:
case Sketcher::Angle:
case Sketcher::SnellsLaw:
return ( constraint->First >= 0 || constraint->Second >= 0 || constraint->Third >= 0 );
@@ -945,6 +948,7 @@ void TaskSketcherConstrains::slotConstraintsChanged(void)
case Sketcher::DistanceX:
case Sketcher::DistanceY:
case Sketcher::Radius:
case Sketcher::Weight:
case Sketcher::Diameter:
case Sketcher::Angle:
case Sketcher::SnellsLaw:
+117 -13
View File
@@ -842,9 +842,29 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe
geo->getTypeId() == Part::GeomArcOfHyperbola::getClassTypeId()||
geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
getDocument()->openCommand(QT_TRANSLATE_NOOP("Command", "Drag Curve"));
auto geo = getSketchObject()->getGeometry(edit->DragCurve);
auto gf = GeometryFacade::getFacade(geo);
Base::Vector3d vec(x-xInit,y-yInit,0);
// BSpline weights have a radius corresponding to the weight value
// However, in order for them to have a visual size irrespective of the
// zoom, the scenograph has a size getScaleFactor() times the weight
//
// This code normalizes the information sent to the solver.
if(gf->getInternalType() == InternalType::BSplineControlPoint) {
auto circle = static_cast<const Part::GeomCircle *>(geo);
Base::Vector3d center = circle->getCenter();
Base::Vector3d dir = vec - center;
vec = center - dir / getScaleFactor();
}
try {
Gui::cmdAppObjectArgs(getObject(), "movePoint(%i,%i,App.Vector(%f,%f,0),%i)"
,edit->DragCurve, Sketcher::none, x-xInit, y-yInit, relative ? 1 : 0);
,edit->DragCurve, Sketcher::none, vec.x, vec.y, relative ? 1 : 0);
getDocument()->commitCommand();
tryAutoRecomputeIfNotSolve(getSketchObject());
@@ -1133,7 +1153,7 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
getSketchObject()->getSolvedSketch().initMove(edit->DragCurve, Sketcher::none, false);
const Part::Geometry *geo = getSketchObject()->getGeometry(edit->DragCurve);
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() ) {
geo->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
relative = true;
//xInit = x;
//yInit = y;
@@ -1185,7 +1205,25 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
return true;
case STATUS_SKETCH_DragCurve:
if (edit->DragCurve != -1) {
auto geo = getSketchObject()->getGeometry(edit->DragCurve);
auto gf = GeometryFacade::getFacade(geo);
Base::Vector3d vec(x-xInit,y-yInit,0);
// BSpline weights have a radius corresponding to the weight value
// However, in order for them to have a visual size irrespective of the
// zoom, the scenograph has a size getScaleFactor() times the weight
//
// This code normalizes the information sent to the solver.
if(gf->getInternalType() == InternalType::BSplineControlPoint) {
auto circle = static_cast<const Part::GeomCircle *>(geo);
Base::Vector3d center = circle->getCenter();
Base::Vector3d dir = vec - center;
vec = center - dir / getScaleFactor();
}
if (getSketchObject()->getSolvedSketch().movePoint(edit->DragCurve, Sketcher::none, vec, relative) == 0) {
setPositionText(Base::Vector2d(x,y));
draw(true,false);
@@ -1261,7 +1299,7 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo
#endif
if (Constr->Type == Distance || Constr->Type == DistanceX || Constr->Type == DistanceY ||
Constr->Type == Radius || Constr->Type == Diameter) {
Constr->Type == Radius || Constr->Type == Diameter || Constr-> Type == Weight) {
Base::Vector3d p1(0.,0.,0.), p2(0.,0.,0.);
if (Constr->SecondPos != Sketcher::none) { // point to point distance
@@ -1331,14 +1369,14 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d &toPo
Base::Vector3d vec = Base::Vector3d(toPos.x, toPos.y, 0) - p2;
Base::Vector3d dir;
if (Constr->Type == Distance || Constr->Type == Radius || Constr->Type == Diameter)
if (Constr->Type == Distance || Constr->Type == Radius || Constr->Type == Diameter || Constr->Type == Weight)
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 || Constr->Type == Diameter) {
if (Constr->Type == Radius || Constr->Type == Diameter || Constr->Type == Weight) {
Constr->LabelDistance = vec.x * dir.x + vec.y * dir.y;
Constr->LabelPosition = atan2(dir.y, dir.x);
} else {
@@ -2804,6 +2842,7 @@ void ViewProviderSketch::updateColor(void)
bool hasDatumLabel = (type == Sketcher::Angle ||
type == Sketcher::Radius ||
type == Sketcher::Diameter ||
type == Sketcher::Weight ||
type == Sketcher::Symmetric ||
type == Sketcher::Distance ||
type == Sketcher::DistanceX ||
@@ -3621,18 +3660,69 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
else if ((*it)->getTypeId() == Part::GeomCircle::getClassTypeId()) { // add a circle
const Part::GeomCircle *circle = static_cast<const Part::GeomCircle *>(*it);
Handle(Geom_Circle) curve = Handle(Geom_Circle)::DownCast(circle->handle());
auto gf = GeometryFacade::getFacade(circle);
int countSegments = stdcountsegments;
Base::Vector3d center = circle->getCenter();
double segment = (2 * M_PI) / countSegments;
for (int i=0; i < countSegments; i++) {
gp_Pnt pnt = curve->Value(i*segment);
// BSpline weights have a radius corresponding to the weight value
// However, in order for them to have a visual size irrespective of the
// zoom, the scenograph has a size getScaleFactor() times the weight
//
// This code draws the scaled up version of the geometry for the scenograph
if(gf->getInternalType() == InternalType::BSplineControlPoint) {
for( auto c : getSketchObject()->Constraints.getValues()) {
if( c->Type == InternalAlignment && c->AlignmentType == BSplineControlPoint && c->First == GeoId) {
auto bspline = dynamic_cast<const Part::GeomBSplineCurve *>((*geomlist)[c->Second]);
if(bspline){
auto weights = bspline->getWeights();
double weight = 1.0;
if(c->InternalAlignmentIndex < int(weights.size()))
weight = weights[c->InternalAlignmentIndex];
// tentative scaling factor:
// proportional to the length of the bspline
// inversely proportional to the number of poles
//double scalefactor = bspline->length(bspline->getFirstParameter(), bspline->getLastParameter())/10.0/weights.size();
double scalefactor = getScaleFactor();
double vradius = weight*scalefactor;
// virtual circle or radius vradius
auto mcurve = [&center, vradius](double param, double &x, double &y) {
x = center.x + vradius*cos(param);
y = center.y + vradius*sin(param);
};
double x;
double y;
for (int i=0; i < countSegments; i++) {
double param = 2*M_PI*i/countSegments;
mcurve(param,x,y);
Coords.emplace_back(x, y, 0);
}
mcurve(0,x,y);
Coords.emplace_back(x, y, 0);
}
break;
}
}
}
else {
double segment = (2 * M_PI) / countSegments;
for (int i=0; i < countSegments; i++) {
gp_Pnt pnt = curve->Value(i*segment);
Coords.emplace_back(pnt.X(), pnt.Y(), pnt.Z());
}
gp_Pnt pnt = curve->Value(0);
Coords.emplace_back(pnt.X(), pnt.Y(), pnt.Z());
}
gp_Pnt pnt = curve->Value(0);
Coords.emplace_back(pnt.X(), pnt.Y(), pnt.Z());
Index.push_back(countSegments+1);
edit->CurvIdToGeoId.push_back(GeoId);
Points.push_back(center);
@@ -5344,11 +5434,13 @@ Restart:
asciiText->pnts.finishEditing();
}
break;
case Weight:
case Radius:
{
assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount);
Base::Vector3d pnt1(0.,0.,0.), pnt2(0.,0.,0.);
if (Constr->First != Constraint::GeoUndef) {
const Part::Geometry *geo = GeoById(*geomlist, Constr->First);
@@ -5366,7 +5458,15 @@ Restart:
}
else if (geo->getTypeId() == Part::GeomCircle::getClassTypeId()) {
const Part::GeomCircle *circle = static_cast<const Part::GeomCircle *>(geo);
double radius = circle->getRadius();
auto gf = GeometryFacade::getFacade(geo);
double radius;
if(Constr->Type == Weight)
radius = circle->getRadius()*getScaleFactor();
else
radius = circle->getRadius();
double angle = (double) Constr->LabelPosition;
if (angle == 10) {
angle = 0;
@@ -5385,7 +5485,10 @@ Restart:
SoDatumLabel *asciiText = static_cast<SoDatumLabel *>(sep->getChild(CONSTRAINT_SEPARATOR_INDEX_MATERIAL_OR_DATUMLABEL));
// Get display string with units hidden if so requested
asciiText->string = SbString( getPresentationString(Constr).toUtf8().constData() );
if(Constr->Type == Weight)
asciiText->string = SbString( QString::number(Constr->getValue()).toStdString().c_str());
else
asciiText->string = SbString( getPresentationString(Constr).toUtf8().constData() );
asciiText->datumtype = SoDatumLabel::RADIUS;
asciiText->param1 = Constr->LabelDistance;
@@ -5475,6 +5578,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
case DistanceY:
case Radius:
case Diameter:
case Weight:
case Angle:
{
SoDatumLabel *text = new SoDatumLabel();