diff --git a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp index 290d738e9f03..f0d59d7a9e50 100644 --- a/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp +++ b/src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp @@ -214,6 +214,37 @@ bool CmdSketcherBSplineKnotMultiplicity::isActive(void) return isSketcherBSplineActive(getActiveGuiDocument(), false); } +// +DEF_STD_CMD_A(CmdSketcherBSplinePoleWeight) + +CmdSketcherBSplinePoleWeight::CmdSketcherBSplinePoleWeight() + : Command("Sketcher_BSplinePoleWeight") +{ + sAppModule = "Sketcher"; + sGroup = QT_TR_NOOP("Sketcher"); + sMenuText = QT_TR_NOOP("Show/hide B-spline control point weight"); + sToolTipText = QT_TR_NOOP("Switches between showing and hiding the control point weight for all B-splines"); + sWhatsThis = "Sketcher_BSplinePoleWeight"; + sStatusTip = sToolTipText; + sPixmap = "Sketcher_BSplinePoleWeight"; + sAccel = ""; + eType = ForEdit; +} + +void CmdSketcherBSplinePoleWeight::activated(int iMsg) +{ + Q_UNUSED(iMsg); + + Gui::Document* doc = getActiveGuiDocument(); + SketcherGui::ViewProviderSketch* vp = static_cast(doc->getInEdit()); + ShowRestoreInformationLayer(vp, "BSplinePoleWeightVisible"); +} + +bool CmdSketcherBSplinePoleWeight::isActive(void) +{ + return isSketcherBSplineActive(getActiveGuiDocument(), false); +} + // Composite drop down menu for show/hide geometry information layer DEF_STD_CMD_ACLU(CmdSketcherCompBSplineShowHideGeometryInformation) @@ -223,7 +254,7 @@ CmdSketcherCompBSplineShowHideGeometryInformation::CmdSketcherCompBSplineShowHid sAppModule = "Sketcher"; sGroup = QT_TR_NOOP("Sketcher"); sMenuText = QT_TR_NOOP("Show/hide B-spline information layer"); - sToolTipText = QT_TR_NOOP("Show/hide B-spline information layer"); + sToolTipText = sMenuText; sWhatsThis = "Sketcher_CompBSplineShowHideGeometryInformation"; sStatusTip = sToolTipText; eType = ForEdit; @@ -242,6 +273,8 @@ void CmdSketcherCompBSplineShowHideGeometryInformation::activated(int iMsg) cmd = rcCmdMgr.getCommandByName("Sketcher_BSplineComb"); else if (iMsg == 3) cmd = rcCmdMgr.getCommandByName("Sketcher_BSplineKnotMultiplicity"); + else if (iMsg == 4) + cmd = rcCmdMgr.getCommandByName("Sketcher_BSplinePoleWeight"); else return; @@ -254,6 +287,8 @@ void CmdSketcherCompBSplineShowHideGeometryInformation::activated(int iMsg) assert(iMsg < a.size()); pcAction->setIcon(a[iMsg]->icon()); + // we must also set the tooltip of the used command + pcAction->setToolTip(a[iMsg]->toolTip()); } Gui::Action * CmdSketcherCompBSplineShowHideGeometryInformation::createAction(void) @@ -270,6 +305,8 @@ Gui::Action * CmdSketcherCompBSplineShowHideGeometryInformation::createAction(vo c3->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_BSplineComb")); QAction* c4 = pcAction->addAction(QString()); c4->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_BSplineKnotMultiplicity")); + QAction* c5 = pcAction->addAction(QString()); + c5->setIcon(Gui::BitmapFactory().iconFromTheme("Sketcher_BSplinePoleWeight")); _pcAction = pcAction; languageChange(); @@ -318,6 +355,14 @@ void CmdSketcherCompBSplineShowHideGeometryInformation::languageChange() "Switches between showing and hiding the knot multiplicity for all B-splines")); c4->setStatusTip(QApplication::translate("Sketcher_BSplineKnotMultiplicity", "Switches between showing and hiding the knot multiplicity for all B-splines")); + + QAction* c5 = a[4]; + c5->setText(QApplication::translate("CmdSketcherCompBSplineShowHideGeometryInformation", + "Show/hide B-spline control point weight")); + c5->setToolTip(QApplication::translate("Sketcher_BSplinePoleWeight", + "Switches between showing and hiding the control point weight for all B-splines")); + c5->setStatusTip(QApplication::translate("Sketcher_BSplinePoleWeight", + "Switches between showing and hiding the control point weight for all B-splines")); } void CmdSketcherCompBSplineShowHideGeometryInformation::updateAction(int /*mode*/) @@ -945,6 +990,7 @@ void CreateSketcherCommandsBSpline(void) rcCmdMgr.addCommand(new CmdSketcherBSplinePolygon()); rcCmdMgr.addCommand(new CmdSketcherBSplineComb()); rcCmdMgr.addCommand(new CmdSketcherBSplineKnotMultiplicity()); + rcCmdMgr.addCommand(new CmdSketcherBSplinePoleWeight()); rcCmdMgr.addCommand(new CmdSketcherCompBSplineShowHideGeometryInformation()); rcCmdMgr.addCommand(new CmdSketcherConvertToNURB()); rcCmdMgr.addCommand(new CmdSketcherIncreaseDegree()); diff --git a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc index d559d213e1b0..03a33af692b4 100644 --- a/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc +++ b/src/Mod/Sketcher/Gui/Resources/Sketcher.qrc @@ -232,6 +232,7 @@ icons/splines/Sketcher_BSplineIncreaseDegree.svg icons/splines/Sketcher_BSplineIncreaseKnotMultiplicity.svg icons/splines/Sketcher_BSplineKnotMultiplicity.svg + icons/splines/Sketcher_BSplinePoleWeight.svg icons/splines/Sketcher_BSplinePolygon.svg diff --git a/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplinePoleWeight.svg b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplinePoleWeight.svg new file mode 100644 index 000000000000..2c38916e9a56 --- /dev/null +++ b/src/Mod/Sketcher/Gui/Resources/icons/splines/Sketcher_BSplinePoleWeight.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [agryson] Alexander Gryson + + + Sketcher_Create_Periodic_BSpline + 2017-02-15 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/Sketcher/Gui/Resources/icons/Sketcher_Toggle_BSpline_Information.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index d4677522b78a..000e4cc5f166 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -3843,7 +3843,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer double maxcurv = 0; double maxdisttocenterofmass = 0; - for(int i = 0; i < ndiv; i++) { + for (int i = 0; i < ndiv; i++) { paramlist[i] = firstparam + i * step; pointatcurvelist[i] = spline->pointAtParameter(paramlist[i]); @@ -3859,12 +3859,12 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer curvaturelist[i] = 0; } - if(curvaturelist[i] > maxcurv) + if (curvaturelist[i] > maxcurv) maxcurv = curvaturelist[i]; double tempf = ( pointatcurvelist[i] - midp ).Length(); - if( tempf > maxdisttocenterofmass ) + if (tempf > maxdisttocenterofmass) maxdisttocenterofmass = tempf; } @@ -3903,7 +3903,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer midp /= poles.size(); - if(rebuildinformationlayer) { + if (rebuildinformationlayer) { SoSwitch *sw = new SoSwitch(); sw->whichChild = hGrpsk->GetBool("BSplineDegreeVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; @@ -3943,7 +3943,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer else { SoSwitch *sw = static_cast(edit->infoGroup->getChild(currentInfoNode)); - if(visibleInformationChanged) + if (visibleInformationChanged) sw->whichChild = hGrpsk->GetBool("BSplineDegreeVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; SoSeparator *sep = static_cast(sw->getChild(0)); @@ -3956,7 +3956,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer currentInfoNode++; // switch to next node // control polygon -------------------------------------------------------- - if(rebuildinformationlayer) { + if (rebuildinformationlayer) { SoSwitch *sw = new SoSwitch(); sw->whichChild = hGrpsk->GetBool("BSplineControlPolygonVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; @@ -3975,7 +3975,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer SoCoordinate3 *polygoncoords = new SoCoordinate3; - if(spline->isPeriodic()) { + if (spline->isPeriodic()) { polygoncoords->point.setNum(poles.size()+1); } else { @@ -3989,7 +3989,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer vts[i].setValue((*it).x,(*it).y,zInfo); } - if(spline->isPeriodic()) { + if (spline->isPeriodic()) { vts[poles.size()].setValue(poles[0].x,poles[0].y,zInfo); } @@ -4086,7 +4086,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer pointatcomblist[i] = pointatcurvelist[i] - combrepscalehyst * curvaturelist[i] * normallist[i]; } - if(rebuildinformationlayer) { + if (rebuildinformationlayer) { SoSwitch *sw = new SoSwitch(); sw->whichChild = hGrpsk->GetBool("BSplineCombVisible", true)?SO_SWITCH_ALL:SO_SWITCH_NONE; @@ -4177,7 +4177,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer std::vector::const_iterator itm; - if(rebuildinformationlayer) { + if (rebuildinformationlayer) { for( itk = knots.begin(), itm = mult.begin(); itk != knots.end() && itm != mult.end(); ++itk, ++itm) { @@ -4199,14 +4199,14 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer Base::Vector3d knotposition = spline->pointAtParameter(*itk); - translate->translation.setValue(knotposition.x,knotposition.y,zInfo); + translate->translation.setValue(knotposition.x, knotposition.y, zInfo); SoFont *font = new SoFont; font->name.setValue("Helvetica"); font->size.setValue(fontSize); SoText2 *degreetext = new SoText2; - degreetext->string = SbString("(")+SbString(*itm)+SbString(")"); + degreetext->string = SbString("(") + SbString(*itm) + SbString(")"); sep->addChild(translate); sep->addChild(mat); @@ -4235,13 +4235,95 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer static_cast(sep->getChild(GEOINFO_BSPLINE_DEGREE_POS))->translation.setValue(knotposition.x,knotposition.y,zInfo); - static_cast(sep->getChild(GEOINFO_BSPLINE_DEGREE_TEXT))->string = SbString("(")+SbString(*itm)+SbString(")"); + static_cast(sep->getChild(GEOINFO_BSPLINE_DEGREE_TEXT))->string = SbString("(") + SbString(*itm) + SbString(")"); currentInfoNode++; // switch to next node } } // End of knot multiplicity + + // pole weights -------------------------------------------------------- + std::vector weights = spline->getWeights(); + QString WeightString; + int itw; + // since the first and last control point of a spline is also treated as knot and thus + // can also have a displayed multiplicity, we must assure the multiplicity is not visibly overwritten + // we add spaces to show the weight behind the multiplicity + auto TextBegin = hGrpsk->GetBool("BSplineKnotMultiplicityVisible", true) ? " [" : "["; + + if (rebuildinformationlayer) { + + for (itw = 0; itw != weights.size(); ++itw) { + + SoSwitch* sw = new SoSwitch(); + + sw->whichChild = hGrpsk->GetBool("BSplinePoleWeightVisible", true) ? SO_SWITCH_ALL : SO_SWITCH_NONE; + + SoSeparator* sep = new SoSeparator(); + sep->ref(); + // no caching for fluctuand data structures + sep->renderCaching = SoSeparator::OFF; + + // every information visual node gets its own material for to-be-implemented preselection and selection + SoMaterial* mat = new SoMaterial; + mat->ref(); + mat->diffuseColor = InformationColor; + + SoTranslation* translate = new SoTranslation; + + Base::Vector3d poleposition = poles[itw]; + + SoFont* font = new SoFont; + font->name.setValue("Helvetica"); + font->size.setValue(fontSize); + + translate->translation.setValue(poleposition.x, poleposition.y, zInfo); + + // set up string with weight value and the user-defined number of decimals + WeightString = QString::fromLatin1("%1").arg(weights[itw], 0, 'f', Base::UnitsApi::getDecimals()); + + SoText2* WeightText = new SoText2; + WeightText->string = SbString(TextBegin) + SbString(WeightString.toStdString().c_str()) + SbString("]"); + + sep->addChild(translate); + sep->addChild(mat); + sep->addChild(font); + sep->addChild(WeightText); + + sw->addChild(sep); + + edit->infoGroup->addChild(sw); + sep->unref(); + mat->unref(); + + currentInfoNode++; // switch to next node + } + } + else { + for (itw = 0; itw != weights.size(); ++itw) { + SoSwitch* sw = static_cast(edit->infoGroup->getChild(currentInfoNode)); + + if (visibleInformationChanged) + sw->whichChild = hGrpsk->GetBool("BSplinePoleWeightVisible", true) ? SO_SWITCH_ALL : SO_SWITCH_NONE; + + SoSeparator* sep = static_cast(sw->getChild(0)); + + Base::Vector3d poleposition = poles[itw]; + + static_cast(sep->getChild(GEOINFO_BSPLINE_DEGREE_POS)) + ->translation.setValue(poleposition.x, poleposition.y, zInfo); + + WeightString = QString::fromLatin1("%1").arg(weights[itw], 0, 'f', Base::UnitsApi::getDecimals()); + + static_cast(sep->getChild(GEOINFO_BSPLINE_DEGREE_TEXT)) + ->string = SbString(TextBegin) + SbString(WeightString.toStdString().c_str()) + SbString("]"); + + currentInfoNode++; // switch to next node + } + } + + // End of pole weights }