SketcherGui: apply clang-format

This commit is contained in:
Abdullah Tahiri
2023-05-25 17:08:03 +02:00
committed by abdullahtahiriyo
parent fd8b50d23f
commit ec899d75c6
98 changed files with 17648 additions and 13572 deletions
+30 -21
View File
@@ -57,16 +57,19 @@ void loadSketcherResource()
Gui::Translator::instance()->refresh();
}
namespace SketcherGui {
class Module : public Py::ExtensionModule<Module>
namespace SketcherGui
{
class Module: public Py::ExtensionModule<Module>
{
public:
Module() : Py::ExtensionModule<Module>("SketcherGui")
Module()
: Py::ExtensionModule<Module>("SketcherGui")
{
initialize("This module is the SketcherGui module."); // register with Python
initialize("This module is the SketcherGui module.");// register with Python
}
~Module() override {}
~Module() override
{}
private:
};
@@ -76,7 +79,7 @@ PyObject* initModule()
return Base::Interpreter().addModule(new Module);
}
} // namespace SketcherGui
}// namespace SketcherGui
/* Python entry */
PyMOD_INIT_FUNC(SketcherGui)
@@ -89,7 +92,7 @@ PyMOD_INIT_FUNC(SketcherGui)
Base::Interpreter().runString("import PartGui");
Base::Interpreter().runString("import Sketcher");
}
catch(const Base::Exception& e) {
catch (const Base::Exception& e) {
PyErr_SetString(PyExc_ImportError, e.what());
PyMOD_Return(nullptr);
}
@@ -101,7 +104,7 @@ PyMOD_INIT_FUNC(SketcherGui)
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/elements"));
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/general"));
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/geometry"));
//Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/obsolete"));
// Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/obsolete"));
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/pointers"));
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/splines"));
Gui::BitmapFactory().addPath(QString::fromLatin1(":/icons/tools"));
@@ -118,23 +121,29 @@ PyMOD_INIT_FUNC(SketcherGui)
SketcherGui::Workbench::init();
// Add Types to module
Base::Interpreter().addType(&SketcherGui::ViewProviderSketchGeometryExtensionPy ::Type,sketcherGuiModule,"ViewProviderSketchGeometryExtension");
Base::Interpreter().addType(&SketcherGui::ViewProviderSketchGeometryExtensionPy ::Type,
sketcherGuiModule,
"ViewProviderSketchGeometryExtension");
// init objects
SketcherGui::ViewProviderSketch ::init();
SketcherGui::ViewProviderPython ::init();
SketcherGui::ViewProviderCustom ::init();
SketcherGui::ViewProviderCustomPython ::init();
SketcherGui::SoZoomTranslation ::initClass();
SketcherGui::PropertyConstraintListItem ::init();
SketcherGui::ViewProviderSketchGeometryExtension ::init();
SketcherGui::ViewProviderSketch ::init();
SketcherGui::ViewProviderPython ::init();
SketcherGui::ViewProviderCustom ::init();
SketcherGui::ViewProviderCustomPython ::init();
SketcherGui::SoZoomTranslation ::initClass();
SketcherGui::PropertyConstraintListItem ::init();
SketcherGui::ViewProviderSketchGeometryExtension ::init();
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettings> ( QT_TRANSLATE_NOOP("QObject","Sketcher") );
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsGrid> ( QT_TRANSLATE_NOOP("QObject","Sketcher") );
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsDisplay> ( QT_TRANSLATE_NOOP("QObject","Sketcher") );
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsColors> ( QT_TRANSLATE_NOOP("QObject","Sketcher") );
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettings>(
QT_TRANSLATE_NOOP("QObject", "Sketcher"));
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsGrid>(
QT_TRANSLATE_NOOP("QObject", "Sketcher"));
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsDisplay>(
QT_TRANSLATE_NOOP("QObject", "Sketcher"));
(void)new Gui::PrefPageProducer<SketcherGui::SketcherSettingsColors>(
QT_TRANSLATE_NOOP("QObject", "Sketcher"));
// add resources and reloads the translators
// add resources and reloads the translators
loadSketcherResource();
PyMOD_Return(sketcherGuiModule);
+6 -4
View File
@@ -24,7 +24,10 @@
#ifndef SKETCHERGUI_AutoConstraint_H
#define SKETCHERGUI_AutoConstraint_H
namespace SketcherGui {
#include <Mod/Sketcher/App/Constraint.h>
namespace SketcherGui
{
// A Simple data type to hold basic information for suggested constraints
struct AutoConstraint
@@ -40,8 +43,7 @@ struct AutoConstraint
Sketcher::PointPos PosId;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_AutoConstraint_H
#endif// SKETCHERGUI_AutoConstraint_H
File diff suppressed because it is too large Load Diff
+45 -41
View File
@@ -43,20 +43,21 @@ using namespace std;
using namespace SketcherGui;
using namespace Sketcher;
bool isAlterGeoActive(Gui::Document *doc)
bool isAlterGeoActive(Gui::Document* doc)
{
if (doc) {
if (doc) {
// checks if a Sketch Viewprovider is in Edit
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
(SketcherGui::ViewProviderSketch::getClassTypeId())) {
return true;
if (doc->getInEdit()
&& doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
return true;
}
}
return false;
}
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode;
@@ -64,20 +65,20 @@ extern GeometryCreationMode geometryCreationMode;
DEF_STD_CMD_A(CmdSketcherToggleConstruction)
CmdSketcherToggleConstruction::CmdSketcherToggleConstruction()
:Command("Sketcher_ToggleConstruction")
: Command("Sketcher_ToggleConstruction")
{
sAppModule = "Sketcher";
sGroup = "Sketcher";
sMenuText = QT_TR_NOOP("Toggle construction geometry");
sToolTipText = QT_TR_NOOP("Toggles the toolbar or selected geometry to/from construction mode");
sWhatsThis = "Sketcher_ToggleConstruction";
sStatusTip = sToolTipText;
sPixmap = "Sketcher_ToggleConstruction";
sAccel = "G, N";
eType = ForEdit;
sAppModule = "Sketcher";
sGroup = "Sketcher";
sMenuText = QT_TR_NOOP("Toggle construction geometry");
sToolTipText = QT_TR_NOOP("Toggles the toolbar or selected geometry to/from construction mode");
sWhatsThis = "Sketcher_ToggleConstruction";
sStatusTip = sToolTipText;
sPixmap = "Sketcher_ToggleConstruction";
sAccel = "G, N";
eType = ForEdit;
// list of toggle construction commands
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CreateLine");
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CreateRectangle");
rcCmdMgr.addCommandMode("ToggleConstruction", "Sketcher_CreateRectangle_Center");
@@ -115,9 +116,9 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
{
Q_UNUSED(iMsg);
// Option A: nothing is selected change creation mode from/to construction
if(Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) == 0){
if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) == 0) {
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
if (geometryCreationMode == Construction) {
geometryCreationMode = Normal;
@@ -128,28 +129,30 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
rcCmdMgr.updateCommands("ToggleConstruction", static_cast<int>(geometryCreationMode));
}
else // there was a selection, so operate in toggle mode.
else// there was a selection, so operate in toggle mode.
{
// get the selection
std::vector<Gui::SelectionObject> selection;
selection = getSelection().getSelectionEx(nullptr, Sketcher::SketchObject::getClassTypeId());
selection =
getSelection().getSelectionEx(nullptr, Sketcher::SketchObject::getClassTypeId());
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
Sketcher::SketchObject* Obj =
static_cast<Sketcher::SketchObject*>(selection[0].getObject());
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("Select edge(s) from the sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select edge(s) from the sketch."));
return;
}
// get the needed lists and objects
const std::vector<std::string> &SubNames = selection[0].getSubNames();
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("Select edge(s) from the sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select edge(s) from the sketch."));
return;
}
@@ -159,13 +162,14 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
// go through the selected subelements
bool verticesonly = true;
for(const auto & subname : SubNames) {
if (subname.size() > 4 && subname.substr(0,4) == "Edge") {
for (const auto& subname : SubNames) {
if (subname.size() > 4 && subname.substr(0, 4) == "Edge") {
verticesonly = false;
}
}
for (std::vector<std::string>::const_iterator it=SubNames.begin();it!=SubNames.end();++it){
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end();
++it) {
// It was decided to provide a special behaviour:
// Vertices will only be toggled to/from construction IF ONLY
// vertices are within the group.
@@ -179,26 +183,26 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
// only handle edges
if (it->size() > 4 && it->substr(0,4) == "Edge") {
int GeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
if (it->size() > 4 && it->substr(0, 4) == "Edge") {
int GeoId = std::atoi(it->substr(4, 4000).c_str()) - 1;
// issue the actual commands to toggle
Gui::cmdAppObjectArgs(selection[0].getObject(), "toggleConstruction(%d) ", GeoId);
}
else if (verticesonly && it->size() > 6 && it->substr(0,6) == "Vertex") {
int vertexId = std::atoi(it->substr(6,4000).c_str()) - 1;
else if (verticesonly && it->size() > 6 && it->substr(0, 6) == "Vertex") {
int vertexId = std::atoi(it->substr(6, 4000).c_str()) - 1;
int geoId;
PointPos pos;
Obj->getGeoVertexIndex(vertexId,geoId, pos);
Obj->getGeoVertexIndex(vertexId, geoId, pos);
auto geo = Obj->getGeometry(geoId);
if(geo && geo->getTypeId() == Part::GeomPoint::getClassTypeId()) {
if (geo && geo->getTypeId() == Part::GeomPoint::getClassTypeId()) {
// issue the actual commands to toggle
Gui::cmdAppObjectArgs(selection[0].getObject(), "toggleConstruction(%d) ", geoId);
Gui::cmdAppObjectArgs(
selection[0].getObject(), "toggleConstruction(%d) ", geoId);
}
}
}
// finish the transaction and update
commitCommand();
@@ -212,14 +216,14 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
bool CmdSketcherToggleConstruction::isActive()
{
return isAlterGeoActive( getActiveGuiDocument() );
return isAlterGeoActive(getActiveGuiDocument());
}
}
}// namespace SketcherGui
void CreateSketcherCommandsAlterGeo()
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdSketcherToggleConstruction());
}
File diff suppressed because it is too large Load Diff
+26 -36
View File
@@ -24,12 +24,11 @@
#ifndef SKETCHERGUI_CommandConstraints_H
#define SKETCHERGUI_CommandConstraints_H
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/Sketcher/App/Constraint.h>
#include <Mod/Sketcher/App/SketchObject.h>
namespace SketcherGui {
namespace SketcherGui
{
// These functions are declared here to promote code reuse from other modules
@@ -42,12 +41,8 @@ namespace SketcherGui {
/// NOTE: A command must be opened before calling this function, which this function
/// commits or aborts as appropriate. The reason is for compatibility reasons with
/// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp
void makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj,
const Part::GeomEllipse *ellipse,
const Part::Geometry *geom2,
int geoId1,
int geoId2
);
void makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj, const Part::GeomEllipse* ellipse,
const Part::Geometry* geom2, int geoId1, int geoId2);
/// Makes a tangency constraint using external construction line between
/// aoe => an arc of ellipse
/// geom2 => any of an arc of ellipse, a circle, or an arc (of circle)
@@ -57,11 +52,8 @@ void makeTangentToEllipseviaNewPoint(Sketcher::SketchObject* Obj,
/// commits or aborts as appropriate. The reason is for compatibility reasons with
/// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp
void makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* Obj,
const Part::GeomArcOfEllipse *aoe,
const Part::Geometry *geom2,
int geoId1,
int geoId2
);
const Part::GeomArcOfEllipse* aoe,
const Part::Geometry* geom2, int geoId1, int geoId2);
/// Makes a tangency constraint using external construction line between
/// aoh => an arc of hyperbola
@@ -72,36 +64,34 @@ void makeTangentToArcOfEllipseviaNewPoint(Sketcher::SketchObject* Obj,
/// commits or aborts as appropriate. The reason is for compatibility reasons with
/// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp
void makeTangentToArcOfHyperbolaviaNewPoint(Sketcher::SketchObject* Obj,
const Part::GeomArcOfHyperbola *aoh,
const Part::Geometry *geom2,
int geoId1,
int geoId2
);
const Part::GeomArcOfHyperbola* aoh,
const Part::Geometry* geom2, int geoId1, int geoId2);
/// Makes a simple tangency constraint using extra point + tangent via point
/// aop => an arc of parabola
/// geom2 => any of an arc of parabola, an arc of hyperbola an arc of ellipse, a circle, or an arc (of circle)
/// geom2 => any of an arc of parabola, an arc of hyperbola an arc of ellipse, a circle, or an arc
/// (of circle)
/// geoId1 => geoid of the arc of parabola
/// geoId2 => geoid of geom2
/// NOTE: A command must be opened before calling this function, which this function
/// commits or aborts as appropriate. The reason is for compatibility reasons with
/// other code e.g. "Autoconstraints" in DrawSketchHandler.cpp
/// NOTE: A command must
/// be opened before calling this function, which this function commits or aborts as appropriate.
/// The reason is for compatibility reasons with other code e.g. "Autoconstraints" in
/// DrawSketchHandler.cpp
void makeTangentToArcOfParabolaviaNewPoint(Sketcher::SketchObject* Obj,
const Part::GeomArcOfParabola *aop,
const Part::Geometry *geom2,
int geoId1,
int geoId2
);
const Part::GeomArcOfParabola* aop,
const Part::Geometry* geom2, int geoId1, int geoId2);
/// Does an endpoint-to-endpoint tangency
void doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, Sketcher::PointPos PosId1, Sketcher::PointPos PosId2);
void doEndpointTangency(Sketcher::SketchObject* Obj, int GeoId1, int GeoId2,
Sketcher::PointPos PosId1, Sketcher::PointPos PosId2);
/// Does an endpoint-edge tangency
void doEndpointToEdgeTangency( Sketcher::SketchObject* Obj, int GeoId1, Sketcher::PointPos PosId1, int GeoId2);
void doEndpointToEdgeTangency(Sketcher::SketchObject* Obj, int GeoId1, Sketcher::PointPos PosId1,
int GeoId2);
/// shows constraint substitution information dialog box, enabling the user to forgo further notifications
void notifyConstraintSubstitutions(const QString & message);
}
#endif // SKETCHERGUI_CommandConstraints_H
/// shows constraint substitution information dialog box, enabling the user to forgo further
/// notifications
void notifyConstraintSubstitutions(const QString& message);
}// namespace SketcherGui
#endif// SKETCHERGUI_CommandConstraints_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+93 -92
View File
@@ -90,8 +90,8 @@ void CmdSketcherSelectConstraints::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(doc->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -163,8 +163,9 @@ void CmdSketcherSelectOrigin::activated(int iMsg)
SketcherGui::ViewProviderSketch* vp =
static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
Sketcher::SketchObject* Obj = vp->getSketchObject();
// ViewProviderSketch * vp = static_cast<ViewProviderSketch *>(Gui::Application::Instance->getViewProvider(docobj));
// Sketcher::SketchObject* Obj = vp->getSketchObject();
// ViewProviderSketch * vp = static_cast<ViewProviderSketch
// *>(Gui::Application::Instance->getViewProvider(docobj)); Sketcher::SketchObject* Obj =
// vp->getSketchObject();
std::string doc_name = Obj->getDocument()->getName();
std::string obj_name = Obj->getNameInDocument();
@@ -626,8 +627,8 @@ void CmdSketcherSelectElementsAssociatedWithConstraints::activated(int iMsg)
if (elementSubNames.empty()) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("No constraint selected"),
QObject::tr("At least one constraint must be selected"));
QObject::tr("No constraint selected"),
QObject::tr("At least one constraint must be selected"));
}
else {
Gui::Selection().addSelections(doc_name.c_str(), obj_name.c_str(), elementSubNames);
@@ -705,8 +706,8 @@ void CmdSketcherSelectElementsWithDoFs::activated(int iMsg)
if (solvext->getGeometry()
== Sketcher::SolverGeometryExtension::NotFullyConstraint) {
// Coded for consistency with getGeometryWithDependentParameters, read the comments
// on that function
// Coded for consistency with getGeometryWithDependentParameters, read the
// comments on that function
if (solvext->getEdge() == SolverGeometryExtension::Dependent)
testselectedge(geoid);
if (solvext->getStart() == SolverGeometryExtension::Dependent)
@@ -765,8 +766,8 @@ void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(doc->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -828,9 +829,8 @@ void CmdSketcherRestoreInternalAlignmentGeometry::activated(int iMsg)
}
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(Obj,
QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"),
e.what());
Gui::NotifyUserError(
Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what());
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(Obj));
@@ -882,8 +882,8 @@ void CmdSketcherSymmetry::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -891,8 +891,8 @@ void CmdSketcherSymmetry::activated(int iMsg)
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -999,20 +999,20 @@ void CmdSketcherSymmetry::activated(int iMsg)
if (geoids == 0 || (geoids == 1 && LastGeoId >= 0 && !lastvertexoraxis)) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("A symmetric construction requires "
"at least two geometric elements, "
"the last geometric element being the reference "
"for the symmetry construction."));
QObject::tr("Wrong selection"),
QObject::tr("A symmetric construction requires "
"at least two geometric elements, "
"the last geometric element being the reference "
"for the symmetry construction."));
return;
}
if (lastgeotype == invalid) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("The last element must be a point "
"or a line serving as reference "
"for the symmetry construction."));
QObject::tr("Wrong selection"),
QObject::tr("The last element must be a point "
"or a line serving as reference "
"for the symmetry construction."));
return;
}
@@ -1049,9 +1049,8 @@ void CmdSketcherSymmetry::activated(int iMsg)
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(Obj,
QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"),
e.what());
Gui::NotifyUserError(
Obj, QT_TRANSLATE_NOOP("Notifications", "Invalid Constraint"), e.what());
Gui::Command::abortCommand();
}
tryAutoRecomputeIfNotSolve(Obj);
@@ -1121,15 +1120,15 @@ class DrawSketchHandlerCopy: public DrawSketchHandler
public:
DrawSketchHandlerCopy(string geoidlist, int origingeoid, Sketcher::PointPos originpos,
int nelements, SketcherCopy::Op op)
: Mode(STATUS_SEEK_First),
snapMode(SnapMode::Free),
geoIdList(geoidlist),
Origin(),
OriginGeoId(origingeoid),
OriginPos(originpos),
nElements(nelements),
Op(op),
EditCurve(2)
: Mode(STATUS_SEEK_First)
, snapMode(SnapMode::Free)
, geoIdList(geoidlist)
, Origin()
, OriginGeoId(origingeoid)
, OriginPos(originpos)
, nElements(nelements)
, Op(op)
, EditCurve(2)
{}
~DrawSketchHandlerCopy() override
@@ -1218,9 +1217,8 @@ public:
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(sketchgui->getObject(),
QT_TRANSLATE_NOOP("Notifications", "Error"),
e.what());
Gui::NotifyUserError(
sketchgui->getObject(), QT_TRANSLATE_NOOP("Notifications", "Error"), e.what());
Gui::Command::abortCommand();
}
@@ -1270,8 +1268,8 @@ void SketcherCopy::activate(SketcherCopy::Op op)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -1280,8 +1278,8 @@ void SketcherCopy::activate(SketcherCopy::Op op)
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -1340,9 +1338,10 @@ void SketcherCopy::activate(SketcherCopy::Op op)
}
if (geoids < 1) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("A copy requires at least one selected non-external geometric element"));
Gui::TranslatedUserWarning(
Obj,
QObject::tr("Wrong selection"),
QObject::tr("A copy requires at least one selected non-external geometric element"));
return;
}
@@ -1356,7 +1355,8 @@ void SketcherCopy::activate(SketcherCopy::Op op)
geoIdList.append(1, ']');
// if the last element is not a point serving as a reference for the copy process
// then make the start point of the last element the copy reference (if it exists, if not the center point)
// then make the start point of the last element the copy reference (if it exists, if not the
// center point)
if (LastPointPos == Sketcher::PointPos::none) {
if (LastGeo->getTypeId() == Part::GeomCircle::getClassTypeId()
|| LastGeo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
@@ -1369,9 +1369,10 @@ void SketcherCopy::activate(SketcherCopy::Op op)
// Ask the user if they want to clone or to simple copy
/*
int ret = QMessageBox::question(Gui::getMainWindow(), QObject::tr("Dimensional/Geometric constraints"),
QObject::tr("Do you want to clone the object, i.e. substitute dimensional constraints by geometric constraints?"),
QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
int ret = QMessageBox::question(Gui::getMainWindow(), QObject::tr("Dimensional/Geometric
constraints"), QObject::tr("Do you want to clone the object, i.e. substitute dimensional
constraints by geometric constraints?"), QMessageBox::Yes, QMessageBox::No,
QMessageBox::Cancel);
// use an equality constraint
if (ret == QMessageBox::Yes) {
clone = true;
@@ -1692,18 +1693,18 @@ public:
Sketcher::PointPos originpos, int nelements, bool clone,
int rows, int cols, bool constraintSeparation,
bool equalVerticalHorizontalSpacing)
: Mode(STATUS_SEEK_First),
snapMode(SnapMode::Free),
geoIdList(geoidlist),
OriginGeoId(origingeoid),
OriginPos(originpos),
nElements(nelements),
Clone(clone),
Rows(rows),
Cols(cols),
ConstraintSeparation(constraintSeparation),
EqualVerticalHorizontalSpacing(equalVerticalHorizontalSpacing),
EditCurve(2)
: Mode(STATUS_SEEK_First)
, snapMode(SnapMode::Free)
, geoIdList(geoidlist)
, OriginGeoId(origingeoid)
, OriginPos(originpos)
, nElements(nelements)
, Clone(clone)
, Rows(rows)
, Cols(cols)
, ConstraintSeparation(constraintSeparation)
, EqualVerticalHorizontalSpacing(equalVerticalHorizontalSpacing)
, EditCurve(2)
{}
~DrawSketchHandlerRectangularArray() override
@@ -1793,9 +1794,8 @@ public:
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
e.what());
Gui::NotifyUserError(
sketchgui, QT_TRANSLATE_NOOP("Notifications", "Error"), e.what());
Gui::Command::abortCommand();
}
@@ -1869,8 +1869,8 @@ void CmdSketcherRectangularArray::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -1879,8 +1879,8 @@ void CmdSketcherRectangularArray::activated(int iMsg)
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -1941,9 +1941,10 @@ void CmdSketcherRectangularArray::activated(int iMsg)
}
if (geoids < 1) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("A copy requires at least one selected non-external geometric element"));
Gui::TranslatedUserWarning(
Obj,
QObject::tr("Wrong selection"),
QObject::tr("A copy requires at least one selected non-external geometric element"));
return;
}
@@ -1957,7 +1958,8 @@ void CmdSketcherRectangularArray::activated(int iMsg)
geoIdList.append(1, ']');
// if the last element is not a point serving as a reference for the copy process
// then make the start point of the last element the copy reference (if it exists, if not the center point)
// then make the start point of the last element the copy reference (if it exists, if not the
// center point)
if (LastPointPos == Sketcher::PointPos::none) {
if (LastGeo->getTypeId() == Part::GeomCircle::getClassTypeId()
|| LastGeo->getTypeId() == Part::GeomEllipse::getClassTypeId()) {
@@ -2034,9 +2036,8 @@ void CmdSketcherDeleteAllGeometry::activated(int iMsg)
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(Obj,
QT_TRANSLATE_NOOP("Notifications", "Failed to delete all geometry"),
e.what());
Gui::NotifyUserError(
Obj, QT_TRANSLATE_NOOP("Notifications", "Failed to delete all geometry"), e.what());
Gui::Command::abortCommand();
}
@@ -2103,9 +2104,10 @@ void CmdSketcherDeleteAllConstraints::activated(int iMsg)
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(Obj,
QT_TRANSLATE_NOOP("Notifications", "Failed to delete all constraints"),
e.what());
Gui::NotifyUserError(
Obj,
QT_TRANSLATE_NOOP("Notifications", "Failed to delete all constraints"),
e.what());
Gui::Command::abortCommand();
}
@@ -2159,8 +2161,8 @@ void CmdSketcherRemoveAxesAlignment::activated(int iMsg)
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -2169,8 +2171,8 @@ void CmdSketcherRemoveAxesAlignment::activated(int iMsg)
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument()->getDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
@@ -2214,10 +2216,11 @@ void CmdSketcherRemoveAxesAlignment::activated(int iMsg)
}
if (geoids < 1) {
Gui::TranslatedUserWarning(Obj,
QObject::tr("Wrong selection"),
QObject::tr("Removal of axes alignment requires at least one selected "
"non-external geometric element"));
Gui::TranslatedUserWarning(
Obj,
QObject::tr("Wrong selection"),
QObject::tr("Removal of axes alignment requires at least one selected "
"non-external geometric element"));
return;
}
@@ -2237,9 +2240,7 @@ void CmdSketcherRemoveAxesAlignment::activated(int iMsg)
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(Obj,
QT_TRANSLATE_NOOP("Notifications", "Error"),
e.what());
Gui::NotifyUserError(Obj, QT_TRANSLATE_NOOP("Notifications", "Error"), e.what());
Gui::Command::abortCommand();
}
@@ -22,23 +22,23 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cfloat>
#include <cfloat>
#endif
#include <Base/Console.h>
#include <App/Application.h>
#include <Base/Console.h>
#include <Gui/Action.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/Selection.h>
#include <Gui/SelectionObject.h>
#include <Gui/BitmapFactory.h>
#include <Gui/CommandT.h>
#include <Gui/Document.h>
#include <Gui/MainWindow.h>
#include <Gui/Notifications.h>
#include <Gui/Action.h>
#include <Gui/BitmapFactory.h>
#include <Gui/Selection.h>
#include <Gui/SelectionObject.h>
#include "ViewProviderSketch.h"
#include "DrawSketchHandler.h"
#include "ViewProviderSketch.h"
#include <Mod/Part/App/Geometry.h>
#include <Mod/Sketcher/App/SketchObject.h>
@@ -50,15 +50,19 @@ using namespace std;
using namespace SketcherGui;
using namespace Sketcher;
bool isSketcherVirtualSpaceActive(Gui::Document *doc, bool actsOnSelection )
bool isSketcherVirtualSpaceActive(Gui::Document* doc, bool actsOnSelection)
{
if (doc) {
// checks if a Sketch Viewprovider is in Edit and is in no special mode
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
if (static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())->getSketchMode() == ViewProviderSketch::STATUS_NONE) {
if (doc->getInEdit()
&& doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
if (static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())->getSketchMode()
== ViewProviderSketch::STATUS_NONE) {
if (!actsOnSelection)
return true;
else if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) > 0)
else if (Gui::Selection().countObjectsOfType(
Sketcher::SketchObject::getClassTypeId())
> 0)
return true;
}
}
@@ -66,11 +70,13 @@ bool isSketcherVirtualSpaceActive(Gui::Document *doc, bool actsOnSelection )
return false;
}
void ActivateVirtualSpaceHandler(Gui::Document *doc, DrawSketchHandler *handler)
void ActivateVirtualSpaceHandler(Gui::Document* doc, DrawSketchHandler* handler)
{
if (doc) {
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
if (doc->getInEdit()
&& doc->getInEdit()->isDerivedFrom(SketcherGui::ViewProviderSketch::getClassTypeId())) {
SketcherGui::ViewProviderSketch* vp =
static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
vp->purgeHandler();
vp->activateHandler(handler);
}
@@ -83,15 +89,16 @@ DEF_STD_CMD_A(CmdSketcherSwitchVirtualSpace)
CmdSketcherSwitchVirtualSpace::CmdSketcherSwitchVirtualSpace()
: Command("Sketcher_SwitchVirtualSpace")
{
sAppModule = "Sketcher";
sGroup = "Sketcher";
sMenuText = QT_TR_NOOP("Switch virtual space");
sToolTipText = QT_TR_NOOP("Switches the selected constraints or the view to the other virtual space");
sWhatsThis = "Sketcher_SwitchVirtualSpace";
sStatusTip = sToolTipText;
sPixmap = "Sketcher_SwitchVirtualSpace";
sAccel = "Z, Z";
eType = ForEdit;
sAppModule = "Sketcher";
sGroup = "Sketcher";
sMenuText = QT_TR_NOOP("Switch virtual space");
sToolTipText =
QT_TR_NOOP("Switches the selected constraints or the view to the other virtual space");
sWhatsThis = "Sketcher_SwitchVirtualSpace";
sStatusTip = sToolTipText;
sPixmap = "Sketcher_SwitchVirtualSpace";
sAccel = "Z, Z";
eType = ForEdit;
}
void CmdSketcherSwitchVirtualSpace::activated(int iMsg)
@@ -106,23 +113,25 @@ void CmdSketcherSwitchVirtualSpace::activated(int iMsg)
selection = getSelection().getSelectionEx();
// only one sketch with its subelements are allowed to be selected
if (selection.size() != 1 || !selection[0].isObjectTypeOf(Sketcher::SketchObject::getClassTypeId())) {
if (selection.size() != 1
|| !selection[0].isObjectTypeOf(Sketcher::SketchObject::getClassTypeId())) {
Gui::TranslatedUserWarning(getActiveGuiDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
return;
}
// get the needed lists and objects
const std::vector<std::string> &SubNames = selection[0].getSubNames();
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
return;
}
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end();
++it) {
// see if we have constraints, if we do it is not a mode change, but a toggle.
if (it->size() > 10 && it->substr(0, 10) == "Constraint")
modeChange = false;
@@ -130,24 +139,26 @@ void CmdSketcherSwitchVirtualSpace::activated(int iMsg)
}
if (modeChange) {
Gui::Document * doc = getActiveGuiDocument();
Gui::Document* doc = getActiveGuiDocument();
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
SketcherGui::ViewProviderSketch* vp =
static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
vp->setIsShownVirtualSpace(!vp->getIsShownVirtualSpace());
}
// toggle the selected constraint(s)
else {
// get the needed lists and objects
const std::vector<std::string> &SubNames = selection[0].getSubNames();
const std::vector<std::string>& SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
Gui::TranslatedUserWarning(getActiveGuiDocument(),
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
return;
}
SketcherGui::ViewProviderSketch* sketchgui = static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
SketcherGui::ViewProviderSketch* sketchgui =
static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
// undo command open
@@ -155,11 +166,13 @@ void CmdSketcherSwitchVirtualSpace::activated(int iMsg)
int successful = SubNames.size();
// go through the selected subelements
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end();
++it) {
// only handle constraints
if (it->size() > 10 && it->substr(0,10) == "Constraint") {
if (it->size() > 10 && it->substr(0, 10) == "Constraint") {
int ConstrId = Sketcher::PropertyConstraintList::getIndexFromConstraintName(*it);
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space"));
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Update constraint's virtual space"));
try {
Gui::cmdAppObjectArgs(Obj, "toggleVirtualSpace(%d)", ConstrId);
}
@@ -187,7 +200,7 @@ bool CmdSketcherSwitchVirtualSpace::isActive()
void CreateSketcherCommandsVirtualSpace()
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdSketcherSwitchVirtualSpace());
}
+123 -105
View File
@@ -26,120 +26,138 @@
#include <array>
#include <bitset>
namespace SketcherGui {
namespace SketcherGui
{
namespace ConstraintFilter {
namespace ConstraintFilter
{
// FilterValue and SpecialFilterValue are the filters used for Constraint Filtering in the Constraint's Widget.
// FilterValue includes the filters used for the Multi-Filter dialog (SpecialFilterValue is not part of the multi-filter).
//
// The values are hardcoded to be the same as the indices in the combobox and viewlist. Addition of an element here requires
// the addition of the corresponding entry there and vice versa.
// FilterValue and SpecialFilterValue are the filters used for Constraint Filtering in the
// Constraint's Widget. FilterValue includes the filters used for the Multi-Filter dialog
// (SpecialFilterValue is not part of the multi-filter).
//
// The values are hardcoded to be the same as the indices in the combobox and viewlist. Addition of
// an element here requires the addition of the corresponding entry there and vice versa.
enum class FilterValue {
All = 0,
Geometric = 1,
Coincident = 2,
PointOnObject = 3,
Vertical = 4,
Horizontal = 5,
Parallel = 6,
Perpendicular = 7,
Tangent = 8,
Equality = 9,
Symmetric = 10,
Block = 11,
InternalAlignment = 12,
Datums = 13,
HorizontalDistance = 14,
VerticalDistance = 15,
Distance = 16,
Radius = 17,
Weight = 18,
Diameter = 19,
Angle = 20,
SnellsLaw = 21,
Named = 22,
NonDriving = 23,
NumFilterValue // SpecialFilterValue shall start at the same index as this
};
enum class FilterValue
{
All = 0,
Geometric = 1,
Coincident = 2,
PointOnObject = 3,
Vertical = 4,
Horizontal = 5,
Parallel = 6,
Perpendicular = 7,
Tangent = 8,
Equality = 9,
Symmetric = 10,
Block = 11,
InternalAlignment = 12,
Datums = 13,
HorizontalDistance = 14,
VerticalDistance = 15,
Distance = 16,
Radius = 17,
Weight = 18,
Diameter = 19,
Angle = 20,
SnellsLaw = 21,
Named = 22,
NonDriving = 23,
NumFilterValue// SpecialFilterValue shall start at the same index as this
};
constexpr auto FilterValueLength = static_cast<std::underlying_type_t<FilterValue>>(FilterValue::NumFilterValue);
constexpr auto FilterValueLength =
static_cast<std::underlying_type_t<FilterValue>>(FilterValue::NumFilterValue);
enum class SpecialFilterValue {
Selection = FilterValueLength, // = 24
AssociatedConstraints, // = 25
NumSpecialFilterValue
};
enum class SpecialFilterValue
{
Selection = FilterValueLength,// = 24
AssociatedConstraints, // = 25
NumSpecialFilterValue
};
constexpr auto SpecialFilterValue = static_cast<std::underlying_type_t<FilterValue>>(SpecialFilterValue::NumSpecialFilterValue);
constexpr auto SpecialFilterValue =
static_cast<std::underlying_type_t<FilterValue>>(SpecialFilterValue::NumSpecialFilterValue);
/// A std::bitset sized to provide one bit per FilterValue value
using FilterValueBitset = std::bitset<FilterValueLength>;
/// Helper function to retrieve the underlying integral type of a filter value
template <typename T>
inline auto getFilterIntegral(T filterValue) {
return static_cast<std::underlying_type_t<T>>(filterValue);
}
/// Helper function to test whether a FilterValue value is set in a FilterValueBitset
inline bool checkFilterBitset(FilterValueBitset set, FilterValue filter)
{
auto underlyingFilterValue = static_cast<std::underlying_type_t<FilterValue>>(filter);
return set[underlyingFilterValue];
}
/// Helper function expanding a parameter pack value of enum classes to create a integral underlying type having
/// the bits corresponding to the parameter pack set
template<typename... Args>
constexpr decltype(auto) buildBitset(Args... args) {
return (... | (1 << static_cast<std::underlying_type_t<Args>>(args)));
}
/// Array of FilterValue bit sets of size of the number of FilterValues indicating for each FilterValue, which other
/// FilterValues are comprised therein. It defines the dependencies between filters.
constexpr std::array< FilterValueBitset, FilterValueLength> filterAggregates {
buildBitset(FilterValue::All, FilterValue::Geometric, FilterValue::Horizontal,
FilterValue::Vertical, FilterValue::Coincident, FilterValue::PointOnObject, FilterValue::Parallel, FilterValue::Perpendicular,
FilterValue::Tangent, FilterValue::Equality, FilterValue::Symmetric, FilterValue::Block, FilterValue::Datums, FilterValue::Distance,
FilterValue::HorizontalDistance, FilterValue::VerticalDistance, FilterValue::Radius, FilterValue::Weight, FilterValue::Diameter,
FilterValue::Angle, FilterValue::SnellsLaw, FilterValue::Named, FilterValue::NonDriving, FilterValue::InternalAlignment), // All = All other groups are covered (0)
buildBitset(FilterValue::Geometric, FilterValue::Horizontal, FilterValue::Vertical, FilterValue::Coincident, FilterValue::PointOnObject,
FilterValue::Parallel, FilterValue::Perpendicular, FilterValue::Tangent, FilterValue::Equality, FilterValue::Symmetric,
FilterValue::Block, FilterValue::InternalAlignment), // Geometric = All others not being datums (1)
buildBitset(FilterValue::Coincident), // Coincident = Just this (2)
buildBitset(FilterValue::PointOnObject), // PointOnObject = Just this (3)
buildBitset(FilterValue::Vertical), // Vertical = Just this (4)
buildBitset(FilterValue::Horizontal), // Horizontal = Just this (5)
buildBitset(FilterValue::Parallel), // Parallel = Just this (6)
buildBitset(FilterValue::Perpendicular), // Perpendicular = Just this (7)
buildBitset(FilterValue::Tangent), // Tangent = Just this (8)
buildBitset(FilterValue::Equality), // Equality = Just this (9)
buildBitset(FilterValue::Symmetric), // Symmetric = Just this (10)
buildBitset(FilterValue::Block), // Block = Just this (11)
buildBitset(FilterValue::InternalAlignment), // InternalAlignment = Just this (12)
buildBitset(FilterValue::Datums, FilterValue::Distance, FilterValue::HorizontalDistance, FilterValue::VerticalDistance, FilterValue::Radius,
FilterValue::Weight, FilterValue::Diameter, FilterValue::Angle, FilterValue::SnellsLaw), // Datum = all others not being geometric (13)
buildBitset(FilterValue::HorizontalDistance), // HorizontalDistance = Just this (14)
buildBitset(FilterValue::VerticalDistance), // VerticalDistance = Just this (15)
buildBitset(FilterValue::Distance), // Distance = Just this (16)
buildBitset(FilterValue::Radius), // Radius = Just this (17)
buildBitset(FilterValue::Weight), // Weight = Just this (18)
buildBitset(FilterValue::Diameter), // Diameter = Just this (19)
buildBitset(FilterValue::Angle), // Angle = Just this (20)
buildBitset(FilterValue::SnellsLaw), // SnellsLaw = Just this (21)
buildBitset(FilterValue::Named), // Named = Just this (22)
buildBitset(FilterValue::NonDriving) // NonDriving = Just this (23)
};
/// A std::bitset sized to provide one bit per FilterValue value
using FilterValueBitset = std::bitset<FilterValueLength>;
/// Helper function to retrieve the underlying integral type of a filter value
template<typename T>
inline auto getFilterIntegral(T filterValue)
{
return static_cast<std::underlying_type_t<T>>(filterValue);
}
/// Helper function to test whether a FilterValue value is set in a FilterValueBitset
inline bool checkFilterBitset(FilterValueBitset set, FilterValue filter)
{
auto underlyingFilterValue = static_cast<std::underlying_type_t<FilterValue>>(filter);
return set[underlyingFilterValue];
}
#endif // SKETCHERGUI_ConstraintFilters_H
/// Helper function expanding a parameter pack value of enum classes to create a integral underlying
/// type having the bits corresponding to the parameter pack set
template<typename... Args>
constexpr decltype(auto) buildBitset(Args... args)
{
return (... | (1 << static_cast<std::underlying_type_t<Args>>(args)));
}
/// Array of FilterValue bit sets of size of the number of FilterValues indicating for each
/// FilterValue, which other FilterValues are comprised therein. It defines the dependencies between
/// filters.
constexpr std::array<FilterValueBitset, FilterValueLength> filterAggregates {
buildBitset(FilterValue::All, FilterValue::Geometric, FilterValue::Horizontal,
FilterValue::Vertical, FilterValue::Coincident, FilterValue::PointOnObject,
FilterValue::Parallel, FilterValue::Perpendicular, FilterValue::Tangent,
FilterValue::Equality, FilterValue::Symmetric, FilterValue::Block,
FilterValue::Datums, FilterValue::Distance, FilterValue::HorizontalDistance,
FilterValue::VerticalDistance, FilterValue::Radius, FilterValue::Weight,
FilterValue::Diameter, FilterValue::Angle, FilterValue::SnellsLaw,
FilterValue::Named, FilterValue::NonDriving,
FilterValue::InternalAlignment),// All = All other groups are covered (0)
buildBitset(FilterValue::Geometric, FilterValue::Horizontal, FilterValue::Vertical,
FilterValue::Coincident, FilterValue::PointOnObject, FilterValue::Parallel,
FilterValue::Perpendicular, FilterValue::Tangent, FilterValue::Equality,
FilterValue::Symmetric, FilterValue::Block,
FilterValue::InternalAlignment),// Geometric = All others not being datums (1)
buildBitset(FilterValue::Coincident), // Coincident = Just this (2)
buildBitset(FilterValue::PointOnObject), // PointOnObject = Just this (3)
buildBitset(FilterValue::Vertical), // Vertical = Just this (4)
buildBitset(FilterValue::Horizontal), // Horizontal = Just this (5)
buildBitset(FilterValue::Parallel), // Parallel = Just this (6)
buildBitset(FilterValue::Perpendicular), // Perpendicular = Just this (7)
buildBitset(FilterValue::Tangent), // Tangent = Just this (8)
buildBitset(FilterValue::Equality), // Equality = Just this (9)
buildBitset(FilterValue::Symmetric), // Symmetric = Just this (10)
buildBitset(FilterValue::Block), // Block = Just this (11)
buildBitset(FilterValue::InternalAlignment),// InternalAlignment = Just this (12)
buildBitset(FilterValue::Datums, FilterValue::Distance, FilterValue::HorizontalDistance,
FilterValue::VerticalDistance, FilterValue::Radius, FilterValue::Weight,
FilterValue::Diameter, FilterValue::Angle,
FilterValue::SnellsLaw),// Datum = all others not being geometric (13)
buildBitset(FilterValue::HorizontalDistance),// HorizontalDistance = Just this (14)
buildBitset(FilterValue::VerticalDistance), // VerticalDistance = Just this (15)
buildBitset(FilterValue::Distance), // Distance = Just this (16)
buildBitset(FilterValue::Radius), // Radius = Just this (17)
buildBitset(FilterValue::Weight), // Weight = Just this (18)
buildBitset(FilterValue::Diameter), // Diameter = Just this (19)
buildBitset(FilterValue::Angle), // Angle = Just this (20)
buildBitset(FilterValue::SnellsLaw), // SnellsLaw = Just this (21)
buildBitset(FilterValue::Named), // Named = Just this (22)
buildBitset(FilterValue::NonDriving)// NonDriving = Just this (23)
};
}// namespace ConstraintFilter
}// namespace SketcherGui
#endif// SKETCHERGUI_ConstraintFilters_H
File diff suppressed because it is too large Load Diff
+102 -79
View File
@@ -25,7 +25,9 @@
#include <Inventor/SbString.h>
#include <Base/Tools2D.h>
#include <Gui/Selection.h>
#include <Mod/Part/App/Geometry.h>
#include <Mod/Sketcher/App/Constraint.h>
#include "AutoConstraint.h"
@@ -33,36 +35,39 @@
class QPixmap;
namespace Sketcher {
class Sketch;
class SketchObject;
}
namespace Sketcher
{
class Sketch;
class SketchObject;
}// namespace Sketcher
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
/**
* Class to convert Part::Geometry to Vector2d based collections
*/
class CurveConverter final : public ParameterGrp::ObserverType {
class CurveConverter final: public ParameterGrp::ObserverType
{
public:
CurveConverter();
~CurveConverter();
std::vector<Base::Vector2d> toVector2D(const Part::Geometry * geometry);
std::vector<Base::Vector2d> toVector2D(const Part::Geometry* geometry);
std::list<std::vector<Base::Vector2d>> toVector2DList(const std::vector<Part::Geometry *> &geometries);
std::list<std::vector<Base::Vector2d>>
toVector2DList(const std::vector<Part::Geometry*>& geometries);
private:
void updateCurvedEdgeCountSegmentsParameter();
/** Observer for parameter group. */
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
void OnChange(Base::Subject<const char*>& rCaller, const char* sReason) override;
private:
int curvedEdgeCountSegments;
@@ -74,57 +79,68 @@ private:
* too tight coupling, while still allowing well defined collaboration,
* DrawSketchHandler accesses ViewProviderSketch via this Attorney class
*/
class ViewProviderSketchDrawSketchHandlerAttorney {
class ViewProviderSketchDrawSketchHandlerAttorney
{
private:
static inline void setConstraintSelectability(ViewProviderSketch &vp, bool enabled = true);
static inline void setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos, const SbString &txt);
static inline void setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos);
static inline void resetPositionText(ViewProviderSketch &vp);
static inline void drawEdit(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditCurve);
static inline void drawEdit(ViewProviderSketch &vp, const std::list<std::vector<Base::Vector2d>> &list);
static inline void drawEditMarkers(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
static inline void setAxisPickStyle(ViewProviderSketch &vp, bool on);
static inline void moveCursorToSketchPoint(ViewProviderSketch &vp, Base::Vector2d point);
static inline void preselectAtPoint(ViewProviderSketch &vp, Base::Vector2d point);
static inline void setAngleSnapping(ViewProviderSketch &vp, bool enable, Base::Vector2d referencePoint = Base::Vector2d(0., 0.));
static inline void setConstraintSelectability(ViewProviderSketch& vp, bool enabled = true);
static inline void setPositionText(ViewProviderSketch& vp, const Base::Vector2d& Pos,
const SbString& txt);
static inline void setPositionText(ViewProviderSketch& vp, const Base::Vector2d& Pos);
static inline void resetPositionText(ViewProviderSketch& vp);
static inline void drawEdit(ViewProviderSketch& vp,
const std::vector<Base::Vector2d>& EditCurve);
static inline void drawEdit(ViewProviderSketch& vp,
const std::list<std::vector<Base::Vector2d>>& list);
static inline void drawEditMarkers(ViewProviderSketch& vp,
const std::vector<Base::Vector2d>& EditMarkers,
unsigned int augmentationlevel = 0);
static inline void setAxisPickStyle(ViewProviderSketch& vp, bool on);
static inline void moveCursorToSketchPoint(ViewProviderSketch& vp, Base::Vector2d point);
static inline void preselectAtPoint(ViewProviderSketch& vp, Base::Vector2d point);
static inline void setAngleSnapping(ViewProviderSketch& vp, bool enable,
Base::Vector2d referencePoint = Base::Vector2d(0., 0.));
static inline int getPreselectPoint(const ViewProviderSketch &vp);
static inline int getPreselectCurve(const ViewProviderSketch &vp);
static inline int getPreselectCross(const ViewProviderSketch &vp);
static inline int getPreselectPoint(const ViewProviderSketch& vp);
static inline int getPreselectCurve(const ViewProviderSketch& vp);
static inline int getPreselectCross(const ViewProviderSketch& vp);
friend class DrawSketchHandler;
};
/** Handler to create new sketch geometry
* This class has to be reimplemented to create geometry in the
* sketcher while its in editing.
*
* DrawSketchHandler takes over the responsibility of drawing edit temporal curves and
* markers necessary to enable visual feedback to the user, as well as the UI interaction during
* such edits. This is its exclusive responsibility under the Single Responsibility Principle.
*
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing (see
* for example all the handlers for creation of new geometry). These derived classes do * not * have
* direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep coupling
* under control. However, generic functionality requiring access to the Attorney can be implemented
* in DrawSketchHandler and used from its derived classes by virtue of the inheritance. This promotes a
* concentrating the coupling in a single point (and code reuse).
*/
* This class has to be reimplemented to create geometry in the
* sketcher while its in editing.
*
* DrawSketchHandler takes over the responsibility of drawing edit temporal curves and
* markers necessary to enable visual feedback to the user, as well as the UI interaction during
* such edits. This is its exclusive responsibility under the Single Responsibility Principle.
*
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing
* (see for example all the handlers for creation of new geometry). These derived classes do * not *
* have direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep
* coupling under control. However, generic functionality requiring access to the Attorney can be
* implemented in DrawSketchHandler and used from its derived classes by virtue of the inheritance.
* This promotes a concentrating the coupling in a single point (and code reuse).
*/
class SketcherGuiExport DrawSketchHandler
{
public:
DrawSketchHandler();
virtual ~DrawSketchHandler();
void activate(ViewProviderSketch *);
void activate(ViewProviderSketch*);
void deactivate();
virtual void mouseMove(Base::Vector2d onSketchPos)=0;
virtual bool pressButton(Base::Vector2d onSketchPos)=0;
virtual bool releaseButton(Base::Vector2d onSketchPos)=0;
virtual bool onSelectionChanged(const Gui::SelectionChanges&) { return false; }
virtual void registerPressedKey(bool /*pressed*/, int /*key*/){}
virtual void mouseMove(Base::Vector2d onSketchPos) = 0;
virtual bool pressButton(Base::Vector2d onSketchPos) = 0;
virtual bool releaseButton(Base::Vector2d onSketchPos) = 0;
virtual bool onSelectionChanged(const Gui::SelectionChanges&)
{
return false;
}
virtual void registerPressedKey(bool /*pressed*/, int /*key*/)
{}
virtual void quit();
@@ -135,26 +151,31 @@ public:
// get the actual highest edge index, the next use will be +1
int getHighestCurveIndex();
int seekAutoConstraint(std::vector<AutoConstraint> &suggestedConstraints,
const Base::Vector2d &Pos, const Base::Vector2d &Dir,
int seekAutoConstraint(std::vector<AutoConstraint>& suggestedConstraints,
const Base::Vector2d& Pos, const Base::Vector2d& Dir,
AutoConstraint::TargetType type = AutoConstraint::VERTEX);
// createowncommand indicates whether a separate command shall be create and committed (for example for undo purposes) or not
// is not it is the responsibility of the developer to create and commit the command appropriately.
void createAutoConstraints(const std::vector<AutoConstraint> &autoConstrs,
int geoId, Sketcher::PointPos pointPos=Sketcher::PointPos::none, bool createowncommand = true);
// createowncommand indicates whether a separate command shall be create and committed (for
// example for undo purposes) or not is not it is the responsibility of the developer to create
// and commit the command appropriately.
void createAutoConstraints(const std::vector<AutoConstraint>& autoConstrs, int geoId,
Sketcher::PointPos pointPos = Sketcher::PointPos::none,
bool createowncommand = true);
void setPositionText(const Base::Vector2d &Pos, const SbString &text);
void setPositionText(const Base::Vector2d &Pos);
void setPositionText(const Base::Vector2d& Pos, const SbString& text);
void setPositionText(const Base::Vector2d& Pos);
void resetPositionText();
void renderSuggestConstraintsCursor(std::vector<AutoConstraint> &suggestedConstraints);
void renderSuggestConstraintsCursor(std::vector<AutoConstraint>& suggestedConstraints);
private: // NVI
private:// NVI
virtual void preActivated();
virtual void activated(){}
virtual void deactivated(){}
virtual void postDeactivated(){}
virtual void activated()
{}
virtual void deactivated()
{}
virtual void postDeactivated()
{}
protected: // NVI requiring base implementation
protected:// NVI requiring base implementation
virtual QString getCrosshairCursorSVGName() const;
protected:
@@ -168,13 +189,14 @@ protected:
/** @name Icon helpers */
//@{
void setCursor(const QPixmap &pixmap, int x,int y, bool autoScale=true);
void setCursor(const QPixmap& pixmap, int x, int y, bool autoScale = true);
/// updates the actCursor with the icon by calling getCrosshairCursorSVGName(),
/// enabling to set data member dependent icons (i.e. for different construction methods)
void updateCursor();
/// restitutes the cursor that was in use at the moment of starting the DrawSketchHandler (i.e. oldCursor)
/// restitutes the cursor that was in use at the moment of starting the DrawSketchHandler (i.e.
/// oldCursor)
void unsetCursor();
/// restitutes the DSH cached cursor (e.g. without any tail due to autoconstraints, ...)
@@ -188,52 +210,53 @@ protected:
qreal devicePixelRatio();
//@}
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
void drawEdit(const std::vector<Part::Geometry *> &geometries);
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
void drawEdit(const std::vector<Base::Vector2d>& EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>>& list);
void drawEdit(const std::vector<Part::Geometry*>& geometries);
void drawEditMarkers(const std::vector<Base::Vector2d>& EditMarkers,
unsigned int augmentationlevel = 0);
void setAxisPickStyle(bool on);
void moveCursorToSketchPoint(Base::Vector2d point);
void preselectAtPoint(Base::Vector2d point);
void drawPositionAtCursor(const Base::Vector2d & position);
void drawDirectionAtCursor(const Base::Vector2d & position, const Base::Vector2d & origin);
void drawPositionAtCursor(const Base::Vector2d& position);
void drawDirectionAtCursor(const Base::Vector2d& position, const Base::Vector2d& origin);
int getPreselectPoint() const;
int getPreselectCurve() const;
int getPreselectCross() const;
Sketcher::SketchObject * getSketchObject();
Sketcher::SketchObject* getSketchObject();
void setAngleSnapping(bool enable, Base::Vector2d referencePoint = Base::Vector2d(0., 0.));
private:
void setSvgCursor(const QString &svgName, int x, int y,
const std::map<unsigned long, unsigned long>& colorMapping = std::map<unsigned long, unsigned long>());
void setSvgCursor(const QString& svgName, int x, int y,
const std::map<unsigned long, unsigned long>& colorMapping =
std::map<unsigned long, unsigned long>());
void addCursorTail(std::vector<QPixmap> &pixmaps);
void addCursorTail(std::vector<QPixmap>& pixmaps);
void applyCursor(QCursor &newCursor);
void applyCursor(QCursor& newCursor);
void setCrosshairCursor(const QString & svgName);
void setCrosshairCursor(const QString& svgName);
void setCrosshairCursor(const char* svgName);
protected:
/**
* Returns constraints icons scaled to width.
**/
std::vector<QPixmap> suggestedConstraintsPixmaps(
std::vector<AutoConstraint> &suggestedConstraints);
std::vector<QPixmap>
suggestedConstraintsPixmaps(std::vector<AutoConstraint>& suggestedConstraints);
ViewProviderSketch *sketchgui;
ViewProviderSketch* sketchgui;
QCursor oldCursor;
QCursor actCursor;
QPixmap actCursorPixmap;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandler_H
#endif// SKETCHERGUI_DrawSketchHandler_H
+152 -121
View File
@@ -30,55 +30,58 @@
using namespace std;
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerArc : public DrawSketchHandler
class DrawSketchHandlerArc: public DrawSketchHandler
{
public:
DrawSketchHandlerArc()
: Mode(STATUS_SEEK_First)
, EditCurve(2)
, rx(0), ry(0)
, startAngle(0)
, endAngle(0)
, arcAngle(0)
{
}
virtual ~DrawSketchHandlerArc(){}
: Mode(STATUS_SEEK_First)
, EditCurve(2)
, rx(0)
, ry(0)
, startAngle(0)
, endAngle(0)
, arcAngle(0)
{}
virtual ~DrawSketchHandlerArc()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_End
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
double dx_ = onSketchPos.x - EditCurve[0].x;
double dy_ = onSketchPos.y - EditCurve[0].y;
for (int i=0; i < 16; i++) {
double angle = i*M_PI/16.0;
for (int i = 0; i < 16; i++) {
double angle = i * M_PI / 16.0;
double dx = dx_ * cos(angle) + dy_ * sin(angle);
double dy = -dx_ * sin(angle) + dy_ * cos(angle);
EditCurve[1+i] = Base::Vector2d(EditCurve[0].x + dx, EditCurve[0].y + dy);
EditCurve[17+i] = Base::Vector2d(EditCurve[0].x - dx, EditCurve[0].y - dy);
EditCurve[1 + i] = Base::Vector2d(EditCurve[0].x + dx, EditCurve[0].y + dy);
EditCurve[17 + i] = Base::Vector2d(EditCurve[0].x - dx, EditCurve[0].y - dy);
}
EditCurve[33] = EditCurve[1];
// Display radius and start angle
float radius = (onSketchPos - EditCurve[0]).Length();
float angle = atan2f(dy_ , dx_);
float angle = atan2f(dy_, dx_);
if (showCursorCoords()) {
SbString text;
@@ -89,18 +92,18 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else if (Mode==STATUS_SEEK_Third) {
double angle1 = atan2(onSketchPos.y - CenterPoint.y,
onSketchPos.x - CenterPoint.x) - startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
for (int i=1; i <= 29; i++) {
double angle = i*arcAngle/29.0;
else if (Mode == STATUS_SEEK_Third) {
double angle1 =
atan2(onSketchPos.y - CenterPoint.y, onSketchPos.x - CenterPoint.x) - startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI;
arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;
for (int i = 1; i <= 29; i++) {
double angle = i * arcAngle / 29.0;
double dx = rx * cos(angle) - ry * sin(angle);
double dy = rx * sin(angle) + ry * cos(angle);
EditCurve[i] = Base::Vector2d(CenterPoint.x + dx, CenterPoint.y + dy);
@@ -118,25 +121,24 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0))) {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0, 0.0))) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
CenterPoint = onSketchPos;
EditCurve.resize(34);
EditCurve[0] = onSketchPos;
setAngleSnapping(true, EditCurve[0]);
Mode = STATUS_SEEK_Second;
}
else if (Mode==STATUS_SEEK_Second){
else if (Mode == STATUS_SEEK_Second) {
EditCurve.resize(31);
EditCurve[0] = onSketchPos;
EditCurve[30] = CenterPoint;
@@ -148,10 +150,10 @@ public:
}
else {
EditCurve.resize(30);
double angle1 = atan2(onSketchPos.y - CenterPoint.y,
onSketchPos.x - CenterPoint.x) - startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
double angle1 =
atan2(onSketchPos.y - CenterPoint.y, onSketchPos.x - CenterPoint.x) - startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI;
arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;
if (arcAngle > 0)
endAngle = startAngle + arcAngle;
else {
@@ -171,24 +173,30 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_End) {
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch arc"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfCircle"
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.ArcOfCircle"
"(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%f,%f),%s)",
CenterPoint.x, CenterPoint.y, sqrt(rx*rx + ry*ry),
startAngle, endAngle,
geometryCreationMode==Construction?"True":"False"); //arcAngle > 0 ? 0 : 1);
CenterPoint.x,
CenterPoint.y,
sqrt(rx * rx + ry * ry),
startAngle,
endAngle,
geometryCreationMode == Construction ? "True"
: "False");// arcAngle > 0 ? 0 : 1);
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
Gui::Command::abortCommand();
}
@@ -200,35 +208,44 @@ public:
// Auto Constraint first picked point
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex(), (arcAngle > 0) ? Sketcher::PointPos::start : Sketcher::PointPos::end );
createAutoConstraints(sugConstr2,
getHighestCurveIndex(),
(arcAngle > 0) ? Sketcher::PointPos::start
: Sketcher::PointPos::end);
sugConstr2.clear();
}
// Auto Constraint second picked point
if (!sugConstr3.empty()) {
createAutoConstraints(sugConstr3, getHighestCurveIndex(), (arcAngle > 0) ? Sketcher::PointPos::end : Sketcher::PointPos::start);
createAutoConstraints(sugConstr3,
getHighestCurveIndex(),
(arcAngle > 0) ? Sketcher::PointPos::end
: Sketcher::PointPos::start);
sugConstr3.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -239,6 +256,7 @@ private:
{
return QString::fromLatin1("Sketcher_Pointer_Create_Arc");
}
protected:
SelectMode Mode;
std::vector<Base::Vector2d> EditCurve;
@@ -247,48 +265,53 @@ protected:
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3;
};
class DrawSketchHandler3PointArc : public DrawSketchHandler
class DrawSketchHandler3PointArc: public DrawSketchHandler
{
public:
DrawSketchHandler3PointArc()
: Mode(STATUS_SEEK_First), EditCurve(2)
, radius(0), startAngle(0)
, endAngle(0), arcAngle(0)
, arcPos1(Sketcher::PointPos::none)
, arcPos2(Sketcher::PointPos::none)
{
}
virtual ~DrawSketchHandler3PointArc(){}
: Mode(STATUS_SEEK_First)
, EditCurve(2)
, radius(0)
, startAngle(0)
, endAngle(0)
, arcAngle(0)
, arcPos1(Sketcher::PointPos::none)
, arcPos2(Sketcher::PointPos::none)
{}
virtual ~DrawSketchHandler3PointArc()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_End
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
CenterPoint = EditCurve[0] = (onSketchPos - FirstPoint)/2 + FirstPoint;
else if (Mode == STATUS_SEEK_Second) {
CenterPoint = EditCurve[0] = (onSketchPos - FirstPoint) / 2 + FirstPoint;
EditCurve[1] = EditCurve[33] = onSketchPos;
radius = (onSketchPos - CenterPoint).Length();
double lineAngle = GetPointAngle(CenterPoint, onSketchPos);
// Build a 32 point circle ignoring already constructed points
for (int i=1; i <= 32; i++) {
for (int i = 1; i <= 32; i++) {
// Start at current angle
double angle = (i-1)*2*M_PI/32.0 + lineAngle; // N point closed circle has N segments
if (i != 1 && i != 17 ) {
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
double angle =
(i - 1) * 2 * M_PI / 32.0 + lineAngle;// N point closed circle has N segments
if (i != 1 && i != 17) {
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius * cos(angle),
CenterPoint.y + radius * sin(angle));
}
}
@@ -303,19 +326,20 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else if (Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
/*
Centerline inverts when the arc flips sides. Easily taken care of by replacing
centerline with a point. It happens because the direction the curve is being drawn
reverses.
*/
try {
CenterPoint = EditCurve[30] = Part::Geom2dCircle::getCircleCenter(FirstPoint, SecondPoint, onSketchPos);
CenterPoint = EditCurve[30] =
Part::Geom2dCircle::getCircleCenter(FirstPoint, SecondPoint, onSketchPos);
radius = (SecondPoint - CenterPoint).Length();
@@ -325,47 +349,47 @@ public:
// Always build arc counter-clockwise
// Point 3 is between Point 1 and 2
if ( angle3 > min(angle1, angle2) && angle3 < max(angle1, angle2) ) {
if (angle3 > min(angle1, angle2) && angle3 < max(angle1, angle2)) {
if (angle2 > angle1) {
EditCurve[0] = FirstPoint;
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::PointPos::start;
arcPos2 = Sketcher::PointPos::end;
}
else {
EditCurve[0] = SecondPoint;
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::PointPos::end;
arcPos2 = Sketcher::PointPos::start;
}
startAngle = min(angle1, angle2);
endAngle = max(angle1, angle2);
endAngle = max(angle1, angle2);
arcAngle = endAngle - startAngle;
}
// Point 3 is not between Point 1 and 2
else {
if (angle2 > angle1) {
EditCurve[0] = SecondPoint;
EditCurve[0] = SecondPoint;
EditCurve[29] = FirstPoint;
arcPos1 = Sketcher::PointPos::end;
arcPos2 = Sketcher::PointPos::start;
}
else {
EditCurve[0] = FirstPoint;
EditCurve[0] = FirstPoint;
EditCurve[29] = SecondPoint;
arcPos1 = Sketcher::PointPos::start;
arcPos2 = Sketcher::PointPos::end;
}
startAngle = max(angle1, angle2);
endAngle = min(angle1, angle2);
arcAngle = 2*M_PI - (startAngle - endAngle);
endAngle = min(angle1, angle2);
arcAngle = 2 * M_PI - (startAngle - endAngle);
}
// Build a 30 point circle ignoring already constructed points
for (int i=1; i <= 28; i++) {
double angle = startAngle + i*arcAngle/29.0; // N point arc has N-1 segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
for (int i = 1; i <= 28; i++) {
double angle = startAngle + i * arcAngle / 29.0;// N point arc has N-1 segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius * cos(angle),
CenterPoint.y + radius * sin(angle));
}
if (showCursorCoords()) {
@@ -377,13 +401,13 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr3, onSketchPos, Base::Vector2d(0.0, 0.0), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
catch(Base::ValueError &e) {
catch (Base::ValueError& e) {
e.ReportException();
}
}
@@ -392,7 +416,7 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
// 32 point curve + center + endpoint
EditCurve.resize(34);
// 17 is circle halfway point (1+32/2)
@@ -400,7 +424,7 @@ public:
Mode = STATUS_SEEK_Second;
}
else if (Mode==STATUS_SEEK_Second){
else if (Mode == STATUS_SEEK_Second) {
// 30 point arc and center point
EditCurve.resize(31);
SecondPoint = onSketchPos;
@@ -422,24 +446,29 @@ public:
{
Q_UNUSED(onSketchPos);
// Need to look at. rx might need fixing.
if (Mode==STATUS_End) {
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch arc"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfCircle"
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.ArcOfCircle"
"(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%f,%f),%s)",
CenterPoint.x, CenterPoint.y, radius,
startAngle, endAngle,
geometryCreationMode==Construction?"True":"False");
CenterPoint.x,
CenterPoint.y,
radius,
startAngle,
endAngle,
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
Gui::Command::abortCommand();
}
@@ -461,24 +490,27 @@ public:
sugConstr3.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -499,8 +531,7 @@ protected:
Sketcher::PointPos arcPos1, arcPos2;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerArc_H
#endif// SKETCHERGUI_DrawSketchHandlerArc_H
@@ -27,47 +27,56 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerArcOfEllipse : public DrawSketchHandler
class DrawSketchHandlerArcOfEllipse: public DrawSketchHandler
{
public:
DrawSketchHandlerArcOfEllipse()
: Mode(STATUS_SEEK_First), EditCurve(34)
, rx(0), ry(0), startAngle(0), endAngle(0)
, arcAngle(0), arcAngle_t(0) {}
: Mode(STATUS_SEEK_First)
, EditCurve(34)
, rx(0)
, ry(0)
, startAngle(0)
, endAngle(0)
, arcAngle(0)
, arcAngle_t(0)
{}
virtual ~DrawSketchHandlerArcOfEllipse() = default;
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) { // TODO: ellipse prio 1
if (seekAutoConstraint(
sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {// TODO: ellipse prio 1
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
double rx0 = onSketchPos.x - EditCurve[0].x;
double ry0 = onSketchPos.y - EditCurve[0].y;
for (int i=0; i < 16; i++) {
double angle = i*M_PI/16.0;
for (int i = 0; i < 16; i++) {
double angle = i * M_PI / 16.0;
double rx1 = rx0 * cos(angle) + ry0 * sin(angle);
double ry1 = -rx0 * sin(angle) + ry0 * cos(angle);
EditCurve[1+i] = Base::Vector2d(EditCurve[0].x + rx1, EditCurve[0].y + ry1);
EditCurve[17+i] = Base::Vector2d(EditCurve[0].x - rx1, EditCurve[0].y - ry1);
EditCurve[1 + i] = Base::Vector2d(EditCurve[0].x + rx1, EditCurve[0].y + ry1);
EditCurve[17 + i] = Base::Vector2d(EditCurve[0].x - rx1, EditCurve[0].y - ry1);
}
EditCurve[33] = EditCurve[1];
@@ -82,27 +91,30 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - centerPoint,
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr2, onSketchPos, onSketchPos - centerPoint, AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else if (Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
// angle between the major axis of the ellipse and the X axis
double a = (EditCurve[1]-EditCurve[0]).Length();
double phi = atan2(EditCurve[1].y-EditCurve[0].y,EditCurve[1].x-EditCurve[0].x);
double a = (EditCurve[1] - EditCurve[0]).Length();
double phi = atan2(EditCurve[1].y - EditCurve[0].y, EditCurve[1].x - EditCurve[0].x);
// This is the angle at cursor point
double angleatpoint = acos((onSketchPos.x-EditCurve[0].x+(onSketchPos.y-EditCurve[0].y)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
double b=(onSketchPos.y-EditCurve[0].y-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi));
double angleatpoint =
acos((onSketchPos.x - EditCurve[0].x + (onSketchPos.y - EditCurve[0].y) * tan(phi))
/ (a * (cos(phi) + tan(phi) * sin(phi))));
double b = (onSketchPos.y - EditCurve[0].y - a * cos(angleatpoint) * sin(phi))
/ (sin(angleatpoint) * cos(phi));
for (int i=1; i < 16; i++) {
double angle = i*M_PI/16.0;
for (int i = 1; i < 16; i++) {
double angle = i * M_PI / 16.0;
double rx1 = a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi);
double ry1 = a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi);
EditCurve[1+i] = Base::Vector2d(EditCurve[0].x + rx1, EditCurve[0].y + ry1);
EditCurve[17+i] = Base::Vector2d(EditCurve[0].x - rx1, EditCurve[0].y - ry1);
EditCurve[1 + i] = Base::Vector2d(EditCurve[0].x + rx1, EditCurve[0].y + ry1);
EditCurve[17 + i] = Base::Vector2d(EditCurve[0].x - rx1, EditCurve[0].y - ry1);
}
EditCurve[33] = EditCurve[1];
EditCurve[17] = EditCurve[16];
@@ -117,38 +129,47 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
else if (Mode==STATUS_SEEK_Fourth) { // here we differ from ellipse creation
else if (Mode == STATUS_SEEK_Fourth) {// here we differ from ellipse creation
// angle between the major axis of the ellipse and the X axis
double a = (axisPoint-centerPoint).Length();
double phi = atan2(axisPoint.y-centerPoint.y,axisPoint.x-centerPoint.x);
double a = (axisPoint - centerPoint).Length();
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
// This is the angle at cursor point
double angleatpoint = acos((startingPoint.x-centerPoint.x+(startingPoint.y-centerPoint.y)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
double b=abs((startingPoint.y-centerPoint.y-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi)));
double angleatpoint = acos(
(startingPoint.x - centerPoint.x + (startingPoint.y - centerPoint.y) * tan(phi))
/ (a * (cos(phi) + tan(phi) * sin(phi))));
double b = abs((startingPoint.y - centerPoint.y - a * cos(angleatpoint) * sin(phi))
/ (sin(angleatpoint) * cos(phi)));
double rxs = startingPoint.x - centerPoint.x;
double rys = startingPoint.y - centerPoint.y;
startAngle = atan2(a*(rys*cos(phi)-rxs*sin(phi)), b*(rxs*cos(phi)+rys*sin(phi))); // eccentric anomaly angle
startAngle = atan2(a * (rys * cos(phi) - rxs * sin(phi)),
b * (rxs * cos(phi) + rys * sin(phi)));// eccentric anomaly angle
double angle1 = atan2(a*((onSketchPos.y - centerPoint.y)*cos(phi)-(onSketchPos.x - centerPoint.x)*sin(phi)),
b*((onSketchPos.x - centerPoint.x)*cos(phi)+(onSketchPos.y - centerPoint.y)*sin(phi)))- startAngle;
double angle1 = atan2(a
* ((onSketchPos.y - centerPoint.y) * cos(phi)
- (onSketchPos.x - centerPoint.x) * sin(phi)),
b
* ((onSketchPos.x - centerPoint.x) * cos(phi)
+ (onSketchPos.y - centerPoint.y) * sin(phi)))
- startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI;
arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;
for (int i=0; i < 34; i++) {
double angle = startAngle+i*arcAngle/34.0;
for (int i = 0; i < 34; i++) {
double angle = startAngle + i * arcAngle / 34.0;
double rx1 = a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi);
double ry1 = a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi);
EditCurve[i] = Base::Vector2d(centerPoint.x + rx1, centerPoint.y + ry1);
}
// EditCurve[33] = EditCurve[1];
// EditCurve[17] = EditCurve[16];
// EditCurve[33] = EditCurve[1];
// EditCurve[17] = EditCurve[16];
// Display radii and angle for user
if (showCursorCoords()) {
@@ -156,42 +177,42 @@ public:
std::string aString = lengthToDisplayFormat(a, 1);
std::string bString = lengthToDisplayFormat(b, 1);
std::string angleString = angleToDisplayFormat(arcAngle * 180.0 / M_PI, 1);
text.sprintf(" (R%s, R%s, %s)", aString.c_str(), bString.c_str(), angleString.c_str());
text.sprintf(
" (R%s, R%s, %s)", aString.c_str(), bString.c_str(), angleString.c_str());
setPositionText(onSketchPos, text);
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr4);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos;
centerPoint = onSketchPos;
setAngleSnapping(true, centerPoint);
Mode = STATUS_SEEK_Second;
}
else if(Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
axisPoint = onSketchPos;
Mode = STATUS_SEEK_Third;
}
else if(Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
startingPoint = onSketchPos;
arcAngle = 0.;
arcAngle_t= 0.;
arcAngle_t = 0.;
Mode = STATUS_SEEK_Fourth;
}
else { // Fourth
else {// Fourth
endPoint = onSketchPos;
setAngleSnapping(false);
@@ -203,86 +224,106 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_Close) {
if (Mode == STATUS_Close) {
unsetCursor();
resetPositionText();
// angle between the major axis of the ellipse and the X axisEllipse
double a = (axisPoint-centerPoint).Length();
double phi = atan2(axisPoint.y-centerPoint.y,axisPoint.x-centerPoint.x);
double a = (axisPoint - centerPoint).Length();
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
// This is the angle at cursor point
double angleatpoint = acos((startingPoint.x-centerPoint.x+(startingPoint.y-centerPoint.y)*tan(phi))/(a*(cos(phi)+tan(phi)*sin(phi))));
double b=abs((startingPoint.y-centerPoint.y-a*cos(angleatpoint)*sin(phi))/(sin(angleatpoint)*cos(phi)));
double angleatpoint = acos(
(startingPoint.x - centerPoint.x + (startingPoint.y - centerPoint.y) * tan(phi))
/ (a * (cos(phi) + tan(phi) * sin(phi))));
double b = abs((startingPoint.y - centerPoint.y - a * cos(angleatpoint) * sin(phi))
/ (sin(angleatpoint) * cos(phi)));
double angle1 = atan2(a*((endPoint.y - centerPoint.y)*cos(phi)-(endPoint.x - centerPoint.x)*sin(phi)),
b*((endPoint.x - centerPoint.x)*cos(phi)+(endPoint.y - centerPoint.y)*sin(phi)))- startAngle;
double angle1 = atan2(a
* ((endPoint.y - centerPoint.y) * cos(phi)
- (endPoint.x - centerPoint.x) * sin(phi)),
b
* ((endPoint.x - centerPoint.x) * cos(phi)
+ (endPoint.y - centerPoint.y) * sin(phi)))
- startAngle;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI ;
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * M_PI;
arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;
bool isOriginalArcCCW=true;
bool isOriginalArcCCW = true;
if (arcAngle > 0)
endAngle = startAngle + arcAngle;
else {
endAngle = startAngle;
startAngle += arcAngle;
isOriginalArcCCW=false;
isOriginalArcCCW = false;
}
Base::Vector2d majAxisDir,minAxisDir,minAxisPoint,majAxisPoint;
// We always create a CCW ellipse, because we want our XY reference system to be in the +X +Y direction
// Our normal will then always be in the +Z axis (local +Z axis of the sketcher)
Base::Vector2d majAxisDir, minAxisDir, minAxisPoint, majAxisPoint;
// We always create a CCW ellipse, because we want our XY reference system to be in the
// +X +Y direction Our normal will then always be in the +Z axis (local +Z axis of the
// sketcher)
if(a>b)
{
if (a > b) {
// force second semidiameter to be perpendicular to first semidiamater
majAxisDir = axisPoint - centerPoint;
Base::Vector2d perp(-majAxisDir.y,majAxisDir.x);
Base::Vector2d perp(-majAxisDir.y, majAxisDir.x);
perp.Normalize();
perp.Scale(abs(b));
minAxisPoint = centerPoint+perp;
majAxisPoint = centerPoint+majAxisDir;
minAxisPoint = centerPoint + perp;
majAxisPoint = centerPoint + majAxisDir;
}
else {
// force second semidiameter to be perpendicular to first semidiamater
minAxisDir = axisPoint - centerPoint;
Base::Vector2d perp(minAxisDir.y,-minAxisDir.x);
Base::Vector2d perp(minAxisDir.y, -minAxisDir.x);
perp.Normalize();
perp.Scale(abs(b));
majAxisPoint = centerPoint+perp;
minAxisPoint = centerPoint+minAxisDir;
endAngle += M_PI/2;
startAngle += M_PI/2;
phi-=M_PI/2;
double t=a; a=b; b=t;//swap a,b
majAxisPoint = centerPoint + perp;
minAxisPoint = centerPoint + minAxisDir;
endAngle += M_PI / 2;
startAngle += M_PI / 2;
phi -= M_PI / 2;
double t = a;
a = b;
b = t;// swap a,b
}
int currentgeoid = getHighestCurveIndex();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch arc of ellipse"));
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add sketch arc of ellipse"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfEllipse"
"(Part.Ellipse(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%f,%f),%s)",
majAxisPoint.x, majAxisPoint.y,
minAxisPoint.x, minAxisPoint.y,
centerPoint.x, centerPoint.y,
startAngle, endAngle,
geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.ArcOfEllipse"
"(Part.Ellipse(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App."
"Vector(%f,%f,0)),%f,%f),%s)",
majAxisPoint.x,
majAxisPoint.y,
minAxisPoint.x,
minAxisPoint.y,
centerPoint.x,
centerPoint.y,
startAngle,
endAngle,
geometryCreationMode == Construction ? "True" : "False");
currentgeoid++;
Gui::cmdAppObjectArgs(sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc of ellipse"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc of ellipse"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
return false;
}
@@ -303,41 +344,51 @@ public:
// add suggested constraints for start of arc
if (!sugConstr3.empty()) {
createAutoConstraints(sugConstr3, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::start:Sketcher::PointPos::end);
createAutoConstraints(sugConstr3,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::start
: Sketcher::PointPos::end);
sugConstr3.clear();
}
// add suggested constraints for start of arc
if (!sugConstr4.empty()) {
createAutoConstraints(sugConstr4, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::end:Sketcher::PointPos::start);
createAutoConstraints(sugConstr4,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::end
: Sketcher::PointPos::start);
sugConstr4.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(34);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_ArcOfEllipse");
}
@@ -349,8 +400,7 @@ protected:
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3, sugConstr4;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerArcOfEllipse_H
#endif// SKETCHERGUI_DrawSketchHandlerArcOfEllipse_H
@@ -30,26 +30,29 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerArcOfHyperbola : public DrawSketchHandler
class DrawSketchHandlerArcOfHyperbola: public DrawSketchHandler
{
public:
DrawSketchHandlerArcOfHyperbola()
: Mode(STATUS_SEEK_First)
, EditCurve(34)
, arcAngle(0)
, arcAngle_t(0) {}
: Mode(STATUS_SEEK_First)
, EditCurve(34)
, arcAngle(0)
, arcAngle_t(0)
{}
virtual ~DrawSketchHandlerArcOfHyperbola() = default;
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
STATUS_Close
};
@@ -62,8 +65,8 @@ public:
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
EditCurve[1]= onSketchPos;
else if (Mode == STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
// Display radius for user
float radius = (onSketchPos - centerPoint).Length();
@@ -75,29 +78,32 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else if (Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
// angle between the major axis of the hyperbola and the X axis
double a = (axisPoint-centerPoint).Length();
double phi = atan2(axisPoint.y-centerPoint.y,axisPoint.x-centerPoint.x);
double a = (axisPoint - centerPoint).Length();
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
// This is the angle at cursor point
double angleatpoint = acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
double b=(onSketchPos.y-centerPoint.y-a*cosh(angleatpoint)*sin(phi))/(sinh(angleatpoint)*cos(phi));
double angleatpoint = acosh(((onSketchPos.x - centerPoint.x) * cos(phi)
+ (onSketchPos.y - centerPoint.y) * sin(phi))
/ a);
double b = (onSketchPos.y - centerPoint.y - a * cosh(angleatpoint) * sin(phi))
/ (sinh(angleatpoint) * cos(phi));
if (!boost::math::isnan(b)) {
for (int i=15; i >= -15; i--) {
for (int i = 15; i >= -15; i--) {
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
//double angle = i*M_PI/16.0;
double angle=i*angleatpoint/15;
// double angle = i*M_PI/16.0;
double angle = i * angleatpoint / 15;
double rx = a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi);
double ry = a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi);
EditCurve[15+i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
EditCurve[15 + i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
}
// Display radius for user
@@ -116,21 +122,29 @@ public:
}
}
}
else if (Mode==STATUS_SEEK_Fourth) {
else if (Mode == STATUS_SEEK_Fourth) {
// angle between the major axis of the hyperbola and the X axis
double a = (axisPoint-centerPoint).Length();
double phi = atan2(axisPoint.y-centerPoint.y,axisPoint.x-centerPoint.x);
double a = (axisPoint - centerPoint).Length();
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
// This is the angle at cursor point
double angleatstartingpoint = acosh(((startingPoint.x-centerPoint.x)*cos(phi)+(startingPoint.y-centerPoint.y)*sin(phi))/a);
double b=(startingPoint.y-centerPoint.y-a*cosh(angleatstartingpoint)*sin(phi))/(sinh(angleatstartingpoint)*cos(phi));
double angleatstartingpoint = acosh(((startingPoint.x - centerPoint.x) * cos(phi)
+ (startingPoint.y - centerPoint.y) * sin(phi))
/ a);
double b = (startingPoint.y - centerPoint.y - a * cosh(angleatstartingpoint) * sin(phi))
/ (sinh(angleatstartingpoint) * cos(phi));
double startAngle = angleatstartingpoint;
//double angleatpoint = acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
// double angleatpoint =
// acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
double angleatpoint = atanh( (((onSketchPos.y-centerPoint.y)*cos(phi)-(onSketchPos.x-centerPoint.x)*sin(phi))*a) /
(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))*b) );
double angleatpoint = atanh((((onSketchPos.y - centerPoint.y) * cos(phi)
- (onSketchPos.x - centerPoint.x) * sin(phi))
* a)
/ (((onSketchPos.x - centerPoint.x) * cos(phi)
+ (onSketchPos.y - centerPoint.y) * sin(phi))
* b));
/*double angle1 = angleatpoint - startAngle;
@@ -139,13 +153,13 @@ public:
arcAngle = angleatpoint - startAngle;
//if(!boost::math::isnan(angle1) && !boost::math::isnan(angle2)){
// if(!boost::math::isnan(angle1) && !boost::math::isnan(angle2)){
if (!boost::math::isnan(arcAngle)) {
EditCurve.resize(33);
for (int i=0; i < 33; i++) {
for (int i = 0; i < 33; i++) {
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
//double angle=i*angleatpoint/16;
double angle = startAngle+i*arcAngle/32.0;
// double angle=i*angleatpoint/16;
double angle = startAngle + i * arcAngle / 32.0;
double rx = a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi);
double ry = a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi);
EditCurve[i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
@@ -161,11 +175,11 @@ public:
}
}
else {
arcAngle=0.;
arcAngle = 0.;
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr4);
return;
}
@@ -176,25 +190,25 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos;
centerPoint = onSketchPos;
EditCurve.resize(2);
Mode = STATUS_SEEK_Second;
}
else if(Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
axisPoint = onSketchPos;
EditCurve.resize(31);
Mode = STATUS_SEEK_Third;
}
else if(Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
startingPoint = onSketchPos;
arcAngle = 0.;
arcAngle_t= 0.;
arcAngle_t = 0.;
Mode = STATUS_SEEK_Fourth;
}
else { // Fourth
else {// Fourth
endPoint = onSketchPos;
Mode = STATUS_Close;
@@ -204,99 +218,120 @@ public:
bool releaseButton(Base::Vector2d /*onSketchPos*/) override
{
if (Mode==STATUS_Close) {
if (Mode == STATUS_Close) {
unsetCursor();
resetPositionText();
// angle between the major axis of the hyperbola and the X axis
double a = (axisPoint-centerPoint).Length();
double phi = atan2(axisPoint.y-centerPoint.y,axisPoint.x-centerPoint.x);
double a = (axisPoint - centerPoint).Length();
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
// This is the angle at cursor point
double angleatstartingpoint = acosh(((startingPoint.x-centerPoint.x)*cos(phi)+(startingPoint.y-centerPoint.y)*sin(phi))/a);
double b=(startingPoint.y-centerPoint.y-a*cosh(angleatstartingpoint)*sin(phi))/(sinh(angleatstartingpoint)*cos(phi));
double angleatstartingpoint = acosh(((startingPoint.x - centerPoint.x) * cos(phi)
+ (startingPoint.y - centerPoint.y) * sin(phi))
/ a);
double b = (startingPoint.y - centerPoint.y - a * cosh(angleatstartingpoint) * sin(phi))
/ (sinh(angleatstartingpoint) * cos(phi));
double startAngle = angleatstartingpoint;
//double angleatpoint = acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
// double angleatpoint =
// acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
double endAngle = atanh( (((endPoint.y-centerPoint.y)*cos(phi)-(endPoint.x-centerPoint.x)*sin(phi))*a) /
(((endPoint.x-centerPoint.x)*cos(phi)+(endPoint.y-centerPoint.y)*sin(phi))*b) );
double endAngle = atanh(
(((endPoint.y - centerPoint.y) * cos(phi) - (endPoint.x - centerPoint.x) * sin(phi))
* a)
/ (((endPoint.x - centerPoint.x) * cos(phi)
+ (endPoint.y - centerPoint.y) * sin(phi))
* b));
if (boost::math::isnan(startAngle) || boost::math::isnan(endAngle)) {
sketchgui->purgeHandler();
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot create arc of hyperbola from invalid angles, try again!"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP(
"Notifications",
"Cannot create arc of hyperbola from invalid angles, try again!"));
return false;
}
bool isOriginalArcCCW=true;
bool isOriginalArcCCW = true;
if (arcAngle > 0)
endAngle = startAngle + arcAngle;
else {
endAngle = startAngle;
startAngle += arcAngle;
isOriginalArcCCW=false;
isOriginalArcCCW = false;
}
Base::Vector2d majAxisDir,minAxisDir,minAxisPoint,majAxisPoint;
// We always create a CCW hyperbola, because we want our XY reference system to be in the +X +Y direction
// Our normal will then always be in the +Z axis (local +Z axis of the sketcher)
Base::Vector2d majAxisDir, minAxisDir, minAxisPoint, majAxisPoint;
// We always create a CCW hyperbola, because we want our XY reference system to be in
// the +X +Y direction Our normal will then always be in the +Z axis (local +Z axis of
// the sketcher)
if(a>b)
{
if (a > b) {
// force second semidiameter to be perpendicular to first semidiamater
majAxisDir = axisPoint - centerPoint;
Base::Vector2d perp(-majAxisDir.y,majAxisDir.x);
Base::Vector2d perp(-majAxisDir.y, majAxisDir.x);
perp.Normalize();
perp.Scale(abs(b));
minAxisPoint = centerPoint+perp;
majAxisPoint = centerPoint+majAxisDir;
minAxisPoint = centerPoint + perp;
majAxisPoint = centerPoint + majAxisDir;
}
else {
// force second semidiameter to be perpendicular to first semidiamater
minAxisDir = axisPoint - centerPoint;
Base::Vector2d perp(minAxisDir.y,-minAxisDir.x);
Base::Vector2d perp(minAxisDir.y, -minAxisDir.x);
perp.Normalize();
perp.Scale(abs(b));
majAxisPoint = centerPoint+perp;
minAxisPoint = centerPoint+minAxisDir;
endAngle += M_PI/2;
startAngle += M_PI/2;
majAxisPoint = centerPoint + perp;
minAxisPoint = centerPoint + minAxisDir;
endAngle += M_PI / 2;
startAngle += M_PI / 2;
}
int currentgeoid = getHighestCurveIndex();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch arc of hyperbola"));
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add sketch arc of hyperbola"));
//Add arc of hyperbola, point and constrain point as focus2. We add focus2 for it to balance
//the intrinsic focus1, in order to balance out the intrinsic invisible focus1 when AOE is
//dragged by its center
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfHyperbola"
"(Part.Hyperbola(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%f,%f),%s)",
majAxisPoint.x, majAxisPoint.y,
minAxisPoint.x, minAxisPoint.y,
centerPoint.x, centerPoint.y,
startAngle, endAngle,
geometryCreationMode==Construction?"True":"False");
// Add arc of hyperbola, point and constrain point as focus2. We add focus2 for it
// to balance the intrinsic focus1, in order to balance out the intrinsic invisible
// focus1 when AOE is dragged by its center
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.ArcOfHyperbola"
"(Part.Hyperbola(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App."
"Vector(%f,%f,0)),%f,%f),%s)",
majAxisPoint.x,
majAxisPoint.y,
minAxisPoint.x,
minAxisPoint.y,
centerPoint.x,
centerPoint.y,
startAngle,
endAngle,
geometryCreationMode == Construction ? "True" : "False");
currentgeoid++;
Gui::cmdAppObjectArgs(sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot create arc of hyperbola"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot create arc of hyperbola"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
return false;
}
@@ -317,22 +352,30 @@ public:
// add suggested constraints for start of arc
if (!sugConstr3.empty()) {
createAutoConstraints(sugConstr3, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::start:Sketcher::PointPos::end);
createAutoConstraints(sugConstr3,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::start
: Sketcher::PointPos::end);
sugConstr3.clear();
}
// add suggested constraints for start of arc
if (!sugConstr4.empty()) {
createAutoConstraints(sugConstr4, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::end:Sketcher::PointPos::start);
createAutoConstraints(sugConstr4,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::end
: Sketcher::PointPos::start);
sugConstr4.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
Mode = STATUS_SEEK_First;
EditCurve.clear();
@@ -344,15 +387,17 @@ public:
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_ArcOfHyperbola");
}
@@ -363,12 +408,10 @@ protected:
Base::Vector2d centerPoint, axisPoint, startingPoint, endPoint;
double arcAngle, arcAngle_t;
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3, sugConstr4;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerArcOfHyperbola_H
#endif// SKETCHERGUI_DrawSketchHandlerArcOfHyperbola_H
@@ -27,11 +27,12 @@
#include <Gui/Notifications.h>
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerArcOfParabola : public DrawSketchHandler
class DrawSketchHandlerArcOfParabola: public DrawSketchHandler
{
public:
DrawSketchHandlerArcOfParabola()
@@ -40,30 +41,32 @@ public:
, startAngle(0)
, endAngle(0)
, arcAngle(0)
, arcAngle_t(0) {}
, arcAngle_t(0)
{}
virtual ~DrawSketchHandlerArcOfParabola() = default;
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_SEEK_Fourth, /**< enum value ----. */
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
EditCurve[1]= onSketchPos;
else if (Mode == STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
// Display radius for user
float radius = (onSketchPos - focusPoint).Length();
@@ -75,30 +78,31 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else if (Mode==STATUS_SEEK_Third) {
double focal = (axisPoint-focusPoint).Length();
double phi = atan2(focusPoint.y-axisPoint.y,focusPoint.x-axisPoint.x);
else if (Mode == STATUS_SEEK_Third) {
double focal = (axisPoint - focusPoint).Length();
double phi = atan2(focusPoint.y - axisPoint.y, focusPoint.x - axisPoint.x);
// P(U) = O + U*U/(4.*F)*XDir + U*YDir
//
// pnt = Base::Vector3d(pnt0.x + angle * angle / 4 / focal * cos(phi) - angle * sin(phi),
// pnt0.y + angle * angle / 4 / focal * sin(phi) + angle * cos(phi),
// 0.f);
// pnt = Base::Vector3d(pnt0.x + angle * angle / 4 / focal * cos(phi) - angle *
// sin(phi),
// pnt0.y + angle * angle / 4 / focal * sin(phi) + angle *
// cos(phi), 0.f);
// This is the angle at cursor point
double u =
( cos(phi) * (onSketchPos.y - axisPoint.y) - (onSketchPos.x - axisPoint.x) * sin(phi));
double u = (cos(phi) * (onSketchPos.y - axisPoint.y)
- (onSketchPos.x - axisPoint.x) * sin(phi));
for (int i=15; i >= -15; i--) {
double angle=i*u/15;
for (int i = 15; i >= -15; i--) {
double angle = i * u / 15;
double rx = angle * angle / 4 / focal * cos(phi) - angle * sin(phi);
double ry = angle * angle / 4 / focal * sin(phi) + angle * cos(phi);
EditCurve[15+i] = Base::Vector2d(axisPoint.x + rx, axisPoint.y + ry);
EditCurve[15 + i] = Base::Vector2d(axisPoint.x + rx, axisPoint.y + ry);
}
// Display radius for user
@@ -111,37 +115,38 @@ public:
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
else if (Mode==STATUS_SEEK_Fourth) {
double focal = (axisPoint-focusPoint).Length();
double phi = atan2(focusPoint.y-axisPoint.y,focusPoint.x-axisPoint.x);
else if (Mode == STATUS_SEEK_Fourth) {
double focal = (axisPoint - focusPoint).Length();
double phi = atan2(focusPoint.y - axisPoint.y, focusPoint.x - axisPoint.x);
// P(U) = O + U*U/(4.*F)*XDir + U*YDir
//
// pnt = Base::Vector3d(pnt0.x + angle * angle / 4 / focal * cos(phi) - angle * sin(phi),
// pnt0.y + angle * angle / 4 / focal * sin(phi) + angle * cos(phi),
// 0.f);
// pnt = Base::Vector3d(pnt0.x + angle * angle / 4 / focal * cos(phi) - angle *
// sin(phi),
// pnt0.y + angle * angle / 4 / focal * sin(phi) + angle *
// cos(phi), 0.f);
// This is the angle at starting point
double ustartpoint =
( cos(phi) * (startingPoint.y - axisPoint.y) - (startingPoint.x - axisPoint.x) * sin(phi));
double ustartpoint = (cos(phi) * (startingPoint.y - axisPoint.y)
- (startingPoint.x - axisPoint.x) * sin(phi));
double startValue = ustartpoint;
double u =
( cos(phi) * (onSketchPos.y - axisPoint.y) - (onSketchPos.x - axisPoint.x) * sin(phi));
double u = (cos(phi) * (onSketchPos.y - axisPoint.y)
- (onSketchPos.x - axisPoint.x) * sin(phi));
arcAngle = u - startValue;
if (!boost::math::isnan(arcAngle)) {
EditCurve.resize(33);
for (std::size_t i=0; i < 33; i++) {
double angle = startValue+i*arcAngle/32.0;
for (std::size_t i = 0; i < 33; i++) {
double angle = startValue + i * arcAngle / 32.0;
double rx = angle * angle / 4 / focal * cos(phi) - angle * sin(phi);
double ry = angle * angle / 4 / focal * sin(phi) + angle * cos(phi);
EditCurve[i] = Base::Vector2d(axisPoint.x + rx, axisPoint.y + ry);
@@ -155,11 +160,11 @@ public:
}
}
else {
arcAngle=0.;
arcAngle = 0.;
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr4);
return;
}
@@ -170,25 +175,25 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos;
focusPoint = onSketchPos;
EditCurve.resize(2);
Mode = STATUS_SEEK_Second;
}
else if(Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
EditCurve[1] = onSketchPos;
axisPoint = onSketchPos;
EditCurve.resize(31);
Mode = STATUS_SEEK_Third;
}
else if(Mode==STATUS_SEEK_Third) {
else if (Mode == STATUS_SEEK_Third) {
startingPoint = onSketchPos;
arcAngle = 0.;
arcAngle_t= 0.;
arcAngle_t = 0.;
Mode = STATUS_SEEK_Fourth;
}
else { // Fourth
else {// Fourth
endPoint = onSketchPos;
Mode = STATUS_Close;
}
@@ -197,23 +202,23 @@ public:
bool releaseButton(Base::Vector2d /*onSketchPos*/) override
{
if (Mode==STATUS_Close) {
if (Mode == STATUS_Close) {
unsetCursor();
resetPositionText();
double phi = atan2(focusPoint.y-axisPoint.y,focusPoint.x-axisPoint.x);
double phi = atan2(focusPoint.y - axisPoint.y, focusPoint.x - axisPoint.x);
double ustartpoint =
( cos(phi) * (startingPoint.y - axisPoint.y) - (startingPoint.x - axisPoint.x) * sin(phi));
double ustartpoint = (cos(phi) * (startingPoint.y - axisPoint.y)
- (startingPoint.x - axisPoint.x) * sin(phi));
double uendpoint =
( cos(phi) * (endPoint.y - axisPoint.y) - (endPoint.x - axisPoint.x) * sin(phi));
(cos(phi) * (endPoint.y - axisPoint.y) - (endPoint.x - axisPoint.x) * sin(phi));
double startAngle = ustartpoint;
double endAngle = uendpoint;
bool isOriginalArcCCW=true;
bool isOriginalArcCCW = true;
if (arcAngle > 0) {
endAngle = startAngle + arcAngle;
@@ -221,33 +226,42 @@ public:
else {
endAngle = startAngle;
startAngle += arcAngle;
isOriginalArcCCW=false;
isOriginalArcCCW = false;
}
int currentgeoid = getHighestCurveIndex();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch arc of Parabola"));
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add sketch arc of Parabola"));
//Add arc of parabola
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfParabola"
"(Part.Parabola(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(0,0,1)),%f,%f),%s)",
focusPoint.x, focusPoint.y,
axisPoint.x, axisPoint.y,
startAngle, endAngle,
geometryCreationMode==Construction?"True":"False");
// Add arc of parabola
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.ArcOfParabola"
"(Part.Parabola(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App."
"Vector(0,0,1)),%f,%f),%s)",
focusPoint.x,
focusPoint.y,
axisPoint.x,
axisPoint.y,
startAngle,
endAngle,
geometryCreationMode == Construction ? "True" : "False");
currentgeoid++;
Gui::cmdAppObjectArgs(sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot create arc of parabola"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot create arc of parabola"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
return false;
}
@@ -256,7 +270,7 @@ public:
// add auto constraints for the focus point
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, currentgeoid+1, Sketcher::PointPos::start);
createAutoConstraints(sugConstr1, currentgeoid + 1, Sketcher::PointPos::start);
sugConstr1.clear();
}
@@ -268,20 +282,28 @@ public:
// add suggested constraints for start of arc
if (!sugConstr3.empty()) {
createAutoConstraints(sugConstr3, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::start:Sketcher::PointPos::end);
createAutoConstraints(sugConstr3,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::start
: Sketcher::PointPos::end);
sugConstr3.clear();
}
// add suggested constraints for start of arc
if (!sugConstr4.empty()) {
createAutoConstraints(sugConstr4, currentgeoid, isOriginalArcCCW?Sketcher::PointPos::end:Sketcher::PointPos::start);
createAutoConstraints(sugConstr4,
currentgeoid,
isOriginalArcCCW ? Sketcher::PointPos::end
: Sketcher::PointPos::start);
sugConstr4.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode = STATUS_SEEK_First;
@@ -295,14 +317,16 @@ public:
* right button of the mouse */
}
else {
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_ArcOfParabola");
}
@@ -314,8 +338,7 @@ protected:
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3, sugConstr4;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerArcOfParabola_H
#endif// SKETCHERGUI_DrawSketchHandlerArcOfParabola_H
+160 -117
View File
@@ -23,27 +23,28 @@
#ifndef SKETCHERGUI_DrawSketchHandlerBSpline_H
#define SKETCHERGUI_DrawSketchHandlerBSpline_H
#include <QInputDialog>
#include <Inventor/events/SoKeyboardEvent.h>
#include <QInputDialog>
#include <Gui/Notifications.h>
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerBSpline: public DrawSketchHandler
{
public:
explicit DrawSketchHandlerBSpline(int constructionMethod)
: Mode(STATUS_SEEK_FIRST_CONTROLPOINT)
, MousePressMode(MOUSE_NOT_PRESSED)
, ConstrMethod(constructionMethod)
, SplineDegree(3)
, IsClosed(false)
: Mode(STATUS_SEEK_FIRST_CONTROLPOINT)
, MousePressMode(MOUSE_NOT_PRESSED)
, ConstrMethod(constructionMethod)
, SplineDegree(3)
, IsClosed(false)
{
addSugConstraint();
applyCursor();
@@ -52,7 +53,8 @@ public:
virtual ~DrawSketchHandlerBSpline() = default;
/// modes
enum SELECT_MODE {
enum SELECT_MODE
{
STATUS_SEEK_FIRST_CONTROLPOINT,
STATUS_SEEK_ADDITIONAL_CONTROLPOINTS,
STATUS_CLOSE
@@ -61,7 +63,8 @@ public:
// TODO: this kind of behavior will be useful in a superclass
// when LMB is pressed it's a transitional state so some undos can't be done
// (like delete last pole)
enum MOUSE_PRESS_MODE {
enum MOUSE_PRESS_MODE
{
MOUSE_PRESSED,
MOUSE_NOT_PRESSED
};
@@ -70,21 +73,21 @@ public:
{
prevCursorPosition = onSketchPos;
if (Mode==STATUS_SEEK_FIRST_CONTROLPOINT) {
if (Mode == STATUS_SEEK_FIRST_CONTROLPOINT) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr.back(), onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr.back(), onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr.back());
return;
}
}
else if (Mode==STATUS_SEEK_ADDITIONAL_CONTROLPOINTS) {
else if (Mode == STATUS_SEEK_ADDITIONAL_CONTROLPOINTS) {
drawControlPolygonToPosition(onSketchPos);
drawCursorToPosition(onSketchPos);
if (seekAutoConstraint(sugConstr.back(), onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr.back(), onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr.back());
return;
}
@@ -106,46 +109,51 @@ public:
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add Pole circle"));
//Add pole
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
BSplinePoles.back().x, BSplinePoles.back().y);
// Add pole
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
BSplinePoles.back().x,
BSplinePoles.back().y);
poleGeoIds.push_back(getHighestCurveIndex());
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
poleGeoIds.back(), 1.0 ); // First pole defaults to 1.0 weight
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addConstraint(Sketcher.Constraint('Weight',%d,%f)) ",
poleGeoIds.back(),
1.0);// First pole defaults to 1.0 weight
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error adding B-Spline pole"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error adding B-Spline pole"));
Gui::Command::abortCommand();
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
return false;
}
//Gui::Command::commitCommand();
// Gui::Command::commitCommand();
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
// static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
// add auto constraints on pole
if (!sugConstr.back().empty()) {
createAutoConstraints(sugConstr.back(), poleGeoIds.back(), Sketcher::PointPos::mid, false);
createAutoConstraints(
sugConstr.back(), poleGeoIds.back(), Sketcher::PointPos::mid, false);
}
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
addSugConstraint();
}
else if (Mode == STATUS_SEEK_ADDITIONAL_CONTROLPOINTS) {
BSplinePoles.push_back(onSketchPos);
// check if coincident with first pole
for(auto & ac : sugConstr.back()) {
for (auto& ac : sugConstr.back()) {
if (ac.Type == Sketcher::Coincident) {
if (ac.GeoId == poleGeoIds[0] && ac.PosId == Sketcher::PointPos::mid)
IsClosed = true;
@@ -153,9 +161,9 @@ public:
// The coincidence with first point may be indirect
const auto coincidents =
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(poleGeoIds[0]) != coincidents.end() &&
coincidents.at(poleGeoIds[0]) == Sketcher::PointPos::mid)
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(poleGeoIds[0]) != coincidents.end()
&& coincidents.at(poleGeoIds[0]) == Sketcher::PointPos::mid)
IsClosed = true;
}
}
@@ -164,7 +172,7 @@ public:
if (IsClosed) {
Mode = STATUS_CLOSE;
if (ConstrMethod == 1) { // if periodic we do not need the last pole
if (ConstrMethod == 1) {// if periodic we do not need the last pole
BSplinePoles.pop_back();
sugConstr.pop_back();
@@ -175,44 +183,48 @@ public:
// insert circle point for pole, defer internal alignment constraining.
try {
//Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add Pole circle"));
// Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add Pole circle"));
//Add pole
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
BSplinePoles.back().x,BSplinePoles.back().y);
// Add pole
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),10),True)",
BSplinePoles.back().x,
BSplinePoles.back().y);
poleGeoIds.push_back(getHighestCurveIndex());
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
poleGeoIds[0], poleGeoIds.back());
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addConstraint(Sketcher.Constraint('Equal',%d,%d)) ",
poleGeoIds[0],
poleGeoIds.back());
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating BSpline pole"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating BSpline pole"));
Gui::Command::abortCommand();
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
return false;
}
//Gui::Command::commitCommand();
// Gui::Command::commitCommand();
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
// static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
// add auto constraints on pole
if (!sugConstr.back().empty()) {
createAutoConstraints(sugConstr.back(), poleGeoIds.back(), Sketcher::PointPos::mid, false);
createAutoConstraints(
sugConstr.back(), poleGeoIds.back(), Sketcher::PointPos::mid, false);
}
//static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
// static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
if (!IsClosed) {
addSugConstraint();
}
}
return true;
}
@@ -228,12 +240,15 @@ public:
void registerPressedKey(bool pressed, int key) override
{
if (SoKeyboardEvent::D == key && pressed) {
SplineDegree = QInputDialog::getInt(
Gui::getMainWindow(),
QObject::tr("B-Spline Degree"),
QObject::tr("Define B-Spline Degree, between 1 and %1:")
.arg(QString::number(Geom_BSplineCurve::MaxDegree())),
SplineDegree, 1, Geom_BSplineCurve::MaxDegree(), 1);
SplineDegree =
QInputDialog::getInt(Gui::getMainWindow(),
QObject::tr("B-Spline Degree"),
QObject::tr("Define B-Spline Degree, between 1 and %1:")
.arg(QString::number(Geom_BSplineCurve::MaxDegree())),
SplineDegree,
1,
Geom_BSplineCurve::MaxDegree(),
1);
// FIXME: Pressing Esc here also finishes the B-Spline creation.
// The user may only want to exit the dialog.
}
@@ -244,8 +259,7 @@ public:
return;
// can only delete last pole if it exists
if (STATUS_SEEK_FIRST_CONTROLPOINT == Mode ||
STATUS_CLOSE == Mode)
if (STATUS_SEEK_FIRST_CONTROLPOINT == Mode || STATUS_CLOSE == Mode)
return;
// if only first pole exists it's equivalent to canceling current spline
@@ -259,23 +273,25 @@ public:
try {
// already ensured that CurrentConstraint == EditCurve.size() > 1
const int delGeoId = poleGeoIds.back();
const auto& constraints = static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->Constraints.getValues();
const auto& constraints =
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->Constraints.getValues();
for (int i = constraints.size() - 1; i >= 0; --i) {
if (delGeoId == constraints[i]->First ||
delGeoId == constraints[i]->Second ||
delGeoId == constraints[i]->Third)
if (delGeoId == constraints[i]->First || delGeoId == constraints[i]->Second
|| delGeoId == constraints[i]->Third)
Gui::cmdAppObjectArgs(sketchgui->getObject(), "delConstraint(%d)", i);
}
// Remove pole
Gui::cmdAppObjectArgs(sketchgui->getObject(), "delGeometry(%d)", delGeoId);
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
poleGeoIds.pop_back();
BSplinePoles.pop_back();
// last entry is kept, as it corresponds to the current pole, but the one corresponding to the erased pole is removed
// last entry is kept, as it corresponds to the current pole, but the one
// corresponding to the erased pole is removed
sugConstr.erase(std::prev(std::prev(sugConstr.end())));
@@ -285,12 +301,13 @@ public:
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error deleting last pole"));
// some commands might have already deleted some constraints/geometries but not others
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error deleting last pole"));
// some commands might have already deleted some constraints/geometries but not
// others
Gui::Command::abortCommand();
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
return;
}
@@ -306,24 +323,27 @@ public:
// We must see if we need to create a B-spline before cancelling everything
// and now just like any other Handler,
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (poleGeoIds.size() > 1) {
// create B-spline from existing poles
Mode=STATUS_CLOSE;
finishCommand(Base::Vector2d(0.f,0.f));
Mode = STATUS_CLOSE;
finishCommand(Base::Vector2d(0.f, 0.f));
}
else if(poleGeoIds.size() == 1) {
// if we just have one point and we can not close anything, then cancel this creation but continue according to continuous mode
//sketchgui->getDocument()->undo(1);
else if (poleGeoIds.size() == 1) {
// if we just have one point and we can not close anything, then cancel this creation
// but continue according to continuous mode
// sketchgui->getDocument()->undo(1);
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
if(!continuousMode){
if (!continuousMode) {
DrawSketchHandler::quit();
}
else {
@@ -331,7 +351,8 @@ public:
resetHandlerState();
}
}
else { // we have no data (CurrentConstraint == 0) so user when right-clicking really wants to exit
else {// we have no data (CurrentConstraint == 0) so user when right-clicking really wants
// to exit
DrawSketchHandler::quit();
}
}
@@ -355,16 +376,19 @@ private:
IsClosed = false;
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_BSpline");
}
void addSugConstraint() {
void addSugConstraint()
{
std::vector<AutoConstraint> sugConstr1;
sugConstr.push_back(std::move(sugConstr1));
}
void drawControlPolygonToPosition(Base::Vector2d position) {
void drawControlPolygonToPosition(Base::Vector2d position)
{
std::vector<Base::Vector2d> editcurve(BSplinePoles);
editcurve.push_back(position);
@@ -372,33 +396,37 @@ private:
drawEdit(editcurve);
}
void drawCursorToPosition(Base::Vector2d position) {
void drawCursorToPosition(Base::Vector2d position)
{
if (!BSplinePoles.empty()) {
float length = (position - BSplinePoles.back()).Length();
float angle = (position - BSplinePoles.back()).GetAngle(Base::Vector2d(1.f,0.f));
float angle = (position - BSplinePoles.back()).GetAngle(Base::Vector2d(1.f, 0.f));
if (showCursorCoords()) {
SbString text;
std::string lengthString = lengthToDisplayFormat(length, 1);
std::string angleString = angleToDisplayFormat((angle != -FLOAT_MAX) ? angle * 180 / M_PI : 0, 1);
std::string angleString =
angleToDisplayFormat((angle != -FLOAT_MAX) ? angle * 180 / M_PI : 0, 1);
text.sprintf(" (%s, %s)", lengthString.c_str(), angleString.c_str());
setPositionText(position, text);
}
}
}
void eraseEditCurve() {
void eraseEditCurve()
{
drawEdit(std::vector<Base::Vector2d>());
}
bool finishCommand(Base::Vector2d position) {
if (Mode==STATUS_CLOSE) {
bool finishCommand(Base::Vector2d position)
{
if (Mode == STATUS_CLOSE) {
unsetCursor();
resetPositionText();
std::stringstream stream;
for (auto & pole : BSplinePoles) {
for (auto& pole : BSplinePoles) {
stream << "App.Vector(" << pole.x << "," << pole.y << "),";
}
@@ -408,15 +436,16 @@ private:
int index = controlpoints.rfind(',');
controlpoints.resize(index);
controlpoints.insert(0,1,'[');
controlpoints.append(1,']');
controlpoints.insert(0, 1, '[');
controlpoints.append(1, ']');
int currentgeoid = getHighestCurveIndex();
unsigned int maxDegree = ConstrMethod == 0 ? (BSplinePoles.size()-1) : (BSplinePoles.size());
unsigned int maxDegree =
ConstrMethod == 0 ? (BSplinePoles.size() - 1) : (BSplinePoles.size());
try {
//Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add B-spline curve"));
// Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add B-spline curve"));
/*Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.BSplineCurve"
"(%s,%s),"
@@ -425,28 +454,35 @@ private:
ConstrMethod == 0 ?"False":"True",
geometryCreationMode==Construction?"True":"False"); */
// {"poles", "mults", "knots", "periodic", "degree", "weights", "CheckRational", NULL};
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.BSplineCurve"
// {"poles", "mults", "knots", "periodic", "degree", "weights", "CheckRational",
// NULL};
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.BSplineCurve"
"(%s,None,None,%s,%d,None,False),%s)",
controlpoints.c_str(),
ConstrMethod == 0 ?"False":"True",
ConstrMethod == 0 ? "False" : "True",
std::min(maxDegree, SplineDegree),
geometryCreationMode==Construction?"True":"False");
geometryCreationMode == Construction ? "True" : "False");
currentgeoid++;
// autoconstraints were added to the circles of the poles, which is ok because they must go to the
// right position, or the user will freak-out if they appear out of the autoconstrained position.
// However, autoconstraints on the first and last pole, in normal non-periodic b-splines (with appropriate endpoint knot multiplicity)
// as the ones created by this tool are intended for the b-spline endpoints, and not for the poles,
// so here we retrieve any autoconstraint on those poles' center and mangle it to the endpoint.
// autoconstraints were added to the circles of the poles, which is ok because they
// must go to the right position, or the user will freak-out if they appear out of
// the autoconstrained position. However, autoconstraints on the first and last
// pole, in normal non-periodic b-splines (with appropriate endpoint knot
// multiplicity) as the ones created by this tool are intended for the b-spline
// endpoints, and not for the poles, so here we retrieve any autoconstraint on those
// poles' center and mangle it to the endpoint.
if (ConstrMethod == 0) {
for(auto & constr : static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->Constraints.getValues()) {
if(constr->First == poleGeoIds[0] && constr->FirstPos == Sketcher::PointPos::mid) {
for (auto& constr : static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->Constraints.getValues()) {
if (constr->First == poleGeoIds[0]
&& constr->FirstPos == Sketcher::PointPos::mid) {
constr->First = currentgeoid;
constr->FirstPos = Sketcher::PointPos::start;
}
else if(constr->First == poleGeoIds.back() && constr->FirstPos == Sketcher::PointPos::mid) {
else if (constr->First == poleGeoIds.back()
&& constr->FirstPos == Sketcher::PointPos::mid) {
constr->First = currentgeoid;
constr->FirstPos = Sketcher::PointPos::end;
}
@@ -459,37 +495,44 @@ private:
cstream << "conList = []\n";
for (size_t i = 0; i < poleGeoIds.size(); i++) {
cstream << "conList.append(Sketcher.Constraint('InternalAlignment:Sketcher::BSplineControlPoint'," << poleGeoIds[0] + i
<< "," << static_cast<int>(Sketcher::PointPos::mid) << "," << currentgeoid << "," << i << "))\n";
cstream << "conList.append(Sketcher.Constraint('InternalAlignment:Sketcher::"
"BSplineControlPoint',"
<< poleGeoIds[0] + i << "," << static_cast<int>(Sketcher::PointPos::mid)
<< "," << currentgeoid << "," << i << "))\n";
}
cstream << Gui::Command::getObjectCmd(sketchgui->getObject()) << ".addConstraint(conList)\n";
cstream << Gui::Command::getObjectCmd(sketchgui->getObject())
<< ".addConstraint(conList)\n";
cstream << "del conList\n";
Gui::Command::doCommand(Gui::Command::Doc, cstream.str().c_str());
// for showing the knots on creation
Gui::cmdAppObjectArgs(sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating B-Spline"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating B-Spline"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
return false;
}
Gui::Command::commitCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
resetHandlerState();
@@ -500,8 +543,9 @@ private:
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
else {
@@ -530,8 +574,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerBSpline_H
#endif// SKETCHERGUI_DrawSketchHandlerBSpline_H
@@ -40,11 +40,11 @@ class DrawSketchHandlerBSplineByInterpolation: public DrawSketchHandler
{
public:
explicit DrawSketchHandlerBSplineByInterpolation(int constructionMethod)
: Mode(STATUS_SEEK_FIRST_POINT),
MousePressMode(MOUSE_NOT_PRESSED),
ConstrMethod(constructionMethod),
SplineDegree(3),
IsClosed(false)
: Mode(STATUS_SEEK_FIRST_POINT)
, MousePressMode(MOUSE_NOT_PRESSED)
, ConstrMethod(constructionMethod)
, SplineDegree(3)
, IsClosed(false)
{
addSugConstraint();
applyCursor();
@@ -120,8 +120,8 @@ public:
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot add knot point"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot add knot point"));
Gui::Command::abortCommand();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
@@ -149,15 +149,15 @@ public:
// The coincidence with first point may be indirect
const auto coincidents =
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(knotGeoIds[0]) != coincidents.end() &&
coincidents.at(knotGeoIds[0]) == Sketcher::PointPos::start)
->getAllCoincidentPoints(ac.GeoId, ac.PosId);
if (coincidents.find(knotGeoIds[0]) != coincidents.end()
&& coincidents.at(knotGeoIds[0]) == Sketcher::PointPos::start)
IsClosed = true;
else if (coincidents.find(knotGeoIds.back()) != coincidents.end() &&
coincidents.at(knotGeoIds.back()) == Sketcher::PointPos::start) {
else if (coincidents.find(knotGeoIds.back()) != coincidents.end()
&& coincidents.at(knotGeoIds.back())
== Sketcher::PointPos::start) {
return true;// OCCT doesn't allow consecutive points being coincident
}
}
}
}
@@ -189,9 +189,10 @@ public:
knotGeoIds.push_back(getHighestCurveIndex());
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot add internal alignment points"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Cannot add internal alignment points"));
Gui::Command::abortCommand();
static_cast<Sketcher::SketchObject*>(sketchgui->getObject())->solve();
@@ -299,8 +300,8 @@ public:
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error removing knot"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error removing knot"));
// some commands might have already deleted some constraints/geometries but not
// others
Gui::Command::abortCommand();
@@ -609,8 +610,8 @@ private:
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating B-Spline"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Error creating B-Spline"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(
@@ -632,8 +633,8 @@ private:
* right button of the mouse */
}
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
sketchgui->purgeHandler();// no code after this line, Handler get deleted in
// ViewProvider
}
return false;
@@ -28,63 +28,80 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class CarbonCopySelection : public Gui::SelectionFilterGate
class CarbonCopySelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit CarbonCopySelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer()), object(obj)
: Gui::SelectionFilterGate(nullPointer())
, object(obj)
{}
bool allow(App::Document *pDoc, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName)
{
Q_UNUSED(sSubName);
Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(object);
sketch->setAllowOtherBody(QApplication::keyboardModifiers() == Qt::ControlModifier || QApplication::keyboardModifiers() == (Qt::ControlModifier | Qt::AltModifier));
sketch->setAllowUnaligned(QApplication::keyboardModifiers() == (Qt::ControlModifier | Qt::AltModifier));
Sketcher::SketchObject* sketch = static_cast<Sketcher::SketchObject*>(object);
sketch->setAllowOtherBody(QApplication::keyboardModifiers() == Qt::ControlModifier
|| QApplication::keyboardModifiers()
== (Qt::ControlModifier | Qt::AltModifier));
sketch->setAllowUnaligned(QApplication::keyboardModifiers()
== (Qt::ControlModifier | Qt::AltModifier));
this->notAllowedReason = "";
Sketcher::SketchObject::eReasonList msg;
// Reusing code: All good reasons not to allow a carbon copy
bool xinv = false, yinv = false;
if (!sketch->isCarbonCopyAllowed(pDoc, pObj, xinv, yinv, &msg)){
switch(msg){
if (!sketch->isCarbonCopyAllowed(pDoc, pObj, xinv, yinv, &msg)) {
switch (msg) {
case Sketcher::SketchObject::rlCircularReference:
this->notAllowedReason = QT_TR_NOOP("Carbon copy would cause a circular dependency.");
this->notAllowedReason =
QT_TR_NOOP("Carbon copy would cause a circular dependency.");
break;
case Sketcher::SketchObject::rlOtherDoc:
this->notAllowedReason = QT_TR_NOOP("This object is in another document.");
break;
case Sketcher::SketchObject::rlOtherBody:
this->notAllowedReason = QT_TR_NOOP("This object belongs to another body. Hold Ctrl to allow cross-references.");
this->notAllowedReason = QT_TR_NOOP("This object belongs to another body. Hold "
"Ctrl to allow cross-references.");
break;
case Sketcher::SketchObject::rlOtherBodyWithLinks:
this->notAllowedReason = QT_TR_NOOP("This object belongs to another body and it contains external geometry. Cross-reference not allowed.");
this->notAllowedReason =
QT_TR_NOOP("This object belongs to another body and it contains external "
"geometry. Cross-reference not allowed.");
break;
case Sketcher::SketchObject::rlOtherPart:
this->notAllowedReason = QT_TR_NOOP("This object belongs to another part.");
break;
case Sketcher::SketchObject::rlNonParallel:
this->notAllowedReason = QT_TR_NOOP("The selected sketch is not parallel to this sketch. Hold Ctrl+Alt to allow non-parallel sketches.");
this->notAllowedReason =
QT_TR_NOOP("The selected sketch is not parallel to this sketch. Hold "
"Ctrl+Alt to allow non-parallel sketches.");
break;
case Sketcher::SketchObject::rlAxesMisaligned:
this->notAllowedReason = QT_TR_NOOP("The XY axes of the selected sketch do not have the same direction as this sketch. Hold Ctrl+Alt to disregard it.");
this->notAllowedReason =
QT_TR_NOOP("The XY axes of the selected sketch do not have the same "
"direction as this sketch. Hold Ctrl+Alt to disregard it.");
break;
case Sketcher::SketchObject::rlOriginsMisaligned:
this->notAllowedReason = QT_TR_NOOP("The origin of the selected sketch is not aligned with the origin of this sketch. Hold Ctrl+Alt to disregard it.");
this->notAllowedReason =
QT_TR_NOOP("The origin of the selected sketch is not aligned with the "
"origin of this sketch. Hold Ctrl+Alt to disregard it.");
break;
default:
break;
}
return false;
}
// Carbon copy only works on sketches that are not disallowed (e.g. would produce a circular reference)
return true;
// Carbon copy only works on sketches that are not disallowed (e.g. would produce a circular
// reference)
return true;
}
};
@@ -114,16 +131,17 @@ public:
{
Q_UNUSED(onSketchPos);
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
return true;
}
bool onSelectionChanged(const Gui::SelectionChanges& msg) override
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
App::DocumentObject* obj = sketchgui->getObject()->getDocument()->getObject(msg.pObjectName);
App::DocumentObject* obj =
sketchgui->getObject()->getDocument()->getObject(msg.pObjectName);
if (!obj)
throw Base::ValueError("Sketcher: Carbon Copy: Invalid object in selection");
@@ -131,27 +149,31 @@ public:
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create a carbon copy"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "carbonCopy(\"%s\",%s)",
msg.pObjectName, geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"carbonCopy(\"%s\",%s)",
msg.pObjectName,
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
Gui::Selection().clearSelection();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add carbon copy"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add carbon copy"));
Gui::Command::abortCommand();
}
return true;
}
}
}
return false;
}
@@ -160,9 +182,9 @@ private:
void activated() override
{
setAxisPickStyle(false);
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
Gui::View3DInventorViewer *viewer;
viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
Gui::View3DInventorViewer* viewer;
viewer = static_cast<Gui::View3DInventor*>(mdi)->getViewer();
viewer->setSelectionEnabled(true);
Gui::Selection().clearSelection();
@@ -170,7 +192,8 @@ private:
Gui::Selection().addSelectionGate(new CarbonCopySelection(sketchgui->getObject()));
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_CarbonCopy");
}
@@ -181,8 +204,7 @@ private:
}
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerCarbonCopy_H
#endif// SKETCHERGUI_DrawSketchHandlerCarbonCopy_H
+108 -82
View File
@@ -26,40 +26,46 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerCircle : public DrawSketchHandler
class DrawSketchHandlerCircle: public DrawSketchHandler
{
public:
DrawSketchHandlerCircle() : Mode(STATUS_SEEK_First),EditCurve(34){}
virtual ~DrawSketchHandlerCircle(){}
DrawSketchHandlerCircle()
: Mode(STATUS_SEEK_First)
, EditCurve(34)
{}
virtual ~DrawSketchHandlerCircle()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_Close
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
double rx0 = onSketchPos.x - EditCurve[0].x;
double ry0 = onSketchPos.y - EditCurve[0].y;
for (int i=0; i < 16; i++) {
double angle = i*M_PI/16.0;
for (int i = 0; i < 16; i++) {
double angle = i * M_PI / 16.0;
double rx = rx0 * cos(angle) + ry0 * sin(angle);
double ry = -rx0 * sin(angle) + ry0 * cos(angle);
EditCurve[1+i] = Base::Vector2d(EditCurve[0].x + rx, EditCurve[0].y + ry);
EditCurve[17+i] = Base::Vector2d(EditCurve[0].x - rx, EditCurve[0].y - ry);
EditCurve[1 + i] = Base::Vector2d(EditCurve[0].x + rx, EditCurve[0].y + ry);
EditCurve[17 + i] = Base::Vector2d(EditCurve[0].x - rx, EditCurve[0].y - ry);
}
EditCurve[33] = EditCurve[1];
@@ -73,8 +79,8 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0],
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr2, onSketchPos, onSketchPos - EditCurve[0], AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
@@ -84,10 +90,11 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos;
Mode = STATUS_SEEK_Second;
} else {
}
else {
EditCurve[1] = onSketchPos;
Mode = STATUS_Close;
}
@@ -97,7 +104,7 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_Close) {
if (Mode == STATUS_Close) {
double rx = EditCurve[1].x - EditCurve[0].x;
double ry = EditCurve[1].y - EditCurve[0].y;
unsetCursor();
@@ -105,11 +112,13 @@ public:
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch circle"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Circle"
"(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%s)",
EditCurve[0].x, EditCurve[0].y,
sqrt(rx*rx + ry*ry),
geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.Circle"
"(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%s)",
EditCurve[0].x,
EditCurve[0].y,
sqrt(rx * rx + ry * ry),
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
}
@@ -132,24 +141,27 @@ public:
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(34);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -165,20 +177,25 @@ protected:
SelectMode Mode;
std::vector<Base::Vector2d> EditCurve;
std::vector<AutoConstraint> sugConstr1, sugConstr2;
};
class DrawSketchHandler3PointCircle : public DrawSketchHandler
class DrawSketchHandler3PointCircle: public DrawSketchHandler
{
public:
DrawSketchHandler3PointCircle()
: Mode(STATUS_SEEK_First),EditCurve(2),radius(1),N(32.0){}
virtual ~DrawSketchHandler3PointCircle(){}
: Mode(STATUS_SEEK_First)
, EditCurve(2)
, radius(1)
, N(32.0)
{}
virtual ~DrawSketchHandler3PointCircle()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_SEEK_Third, /**< enum value ----. */
STATUS_End
};
@@ -186,28 +203,29 @@ public:
{
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode == STATUS_SEEK_Second || Mode == STATUS_SEEK_Third) {
try
{
try {
if (Mode == STATUS_SEEK_Second)
CenterPoint = EditCurve[N+1] = (onSketchPos - FirstPoint)/2 + FirstPoint;
CenterPoint = EditCurve[N + 1] = (onSketchPos - FirstPoint) / 2 + FirstPoint;
else
CenterPoint = EditCurve[N+1] = Part::Geom2dCircle::getCircleCenter(FirstPoint, SecondPoint, onSketchPos);
CenterPoint = EditCurve[N + 1] =
Part::Geom2dCircle::getCircleCenter(FirstPoint, SecondPoint, onSketchPos);
radius = (onSketchPos - CenterPoint).Length();
double lineAngle = GetPointAngle(CenterPoint, onSketchPos);
// Build a N point circle
for (int i=1; i < N; i++) {
for (int i = 1; i < N; i++) {
// Start at current angle
double angle = i*2*M_PI/N + lineAngle; // N point closed circle has N segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius*cos(angle),
CenterPoint.y + radius*sin(angle));
double angle =
i * 2 * M_PI / N + lineAngle;// N point closed circle has N segments
EditCurve[i] = Base::Vector2d(CenterPoint.x + radius * cos(angle),
CenterPoint.y + radius * sin(angle));
}
// Beginning and end of curve should be exact
EditCurve[0] = EditCurve[N] = onSketchPos;
@@ -217,28 +235,32 @@ public:
if (showCursorCoords()) {
SbString text;
std::string radiusString = lengthToDisplayFormat(radius, 1);
std::string angleString = angleToDisplayFormat( lineAngle * 180.0 / M_PI, 1);
std::string angleString = angleToDisplayFormat(lineAngle * 180.0 / M_PI, 1);
text.sprintf(" (R%s, %s)", radiusString.c_str(), angleString.c_str());
setPositionText(onSketchPos, text);
}
drawEdit(EditCurve);
if (Mode == STATUS_SEEK_Second) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(sugConstr2,
onSketchPos,
Base::Vector2d(0.f, 0.f),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
else {
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(sugConstr3,
onSketchPos,
Base::Vector2d(0.f, 0.f),
AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
}
catch(Base::ValueError &e) {
catch (Base::ValueError& e) {
e.ReportException();
}
}
@@ -249,7 +271,7 @@ public:
{
if (Mode == STATUS_SEEK_First) {
// N point curve + center + endpoint
EditCurve.resize(N+2);
EditCurve.resize(N + 2);
FirstPoint = onSketchPos;
Mode = STATUS_SEEK_Second;
@@ -274,24 +296,26 @@ public:
{
Q_UNUSED(onSketchPos);
// Need to look at. rx might need fixing.
if (Mode==STATUS_End) {
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch circle"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Circle"
"(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%s)",
CenterPoint.x, CenterPoint.y,
radius,
geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.Circle"
"(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%s)",
CenterPoint.x,
CenterPoint.y,
radius,
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add circle"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add circle"));
Gui::Command::abortCommand();
}
@@ -313,24 +337,27 @@ public:
sugConstr3.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -346,13 +373,12 @@ protected:
SelectMode Mode;
std::vector<Base::Vector2d> EditCurve;
Base::Vector2d CenterPoint, FirstPoint, SecondPoint;
double radius, N; // N should be even
double radius, N;// N should be even
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerCircle_H
#endif// SKETCHERGUI_DrawSketchHandlerCircle_H
+176 -127
View File
@@ -23,18 +23,19 @@
#ifndef SKETCHERGUI_DrawSketchHandlerEllipse_H
#define SKETCHERGUI_DrawSketchHandlerEllipse_H
#include <cmath>
#include <QDebug>
#include <GC_MakeEllipse.hxx>
#include <QDebug>
#include <cmath>
#include <Gui/Notifications.h>
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
/* Ellipse ==============================================================================*/
/**
@@ -63,9 +64,11 @@ extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo
* a &\equiv& \textrm{ length of the semi-major axis, colloquially 'radius'}\\
* b &\equiv& \textrm{ length of the semi-minor axis, colloquially 'radius'}\\
* e &\equiv& \textrm{ eccentricity of the ellipse}\\
* \theta_b &\equiv& \textrm{ angle to the intersection of the semi-minor axis and the ellipse, relative to the focus}\\
* \theta_b &\equiv& \textrm{ angle to the intersection of the semi-minor axis and the
* ellipse, relative to the focus}\\
* ae &\equiv& \textrm{ distance from the focus to the centroid}\\
* r &=& \frac{a(1-e^2)}{1+e\cos(\theta)} = \frac{r_a(1-e)}{1+e\cos(\theta)} = \frac{r_p(1+e)}{1+e\cos(\theta)}\\
* r &=& \frac{a(1-e^2)}{1+e\cos(\theta)} = \frac{r_a(1-e)}{1+e\cos(\theta)} =
* \frac{r_p(1+e)}{1+e\cos(\theta)}\\
* r_a &=& a(1-e)\\
* r_p &=& a(1+e)\\
* a &=& \frac{r_p+r_a}{2}\\
@@ -75,32 +78,42 @@ extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo
* \f}
*
*/
class DrawSketchHandlerEllipse : public DrawSketchHandler
class DrawSketchHandlerEllipse: public DrawSketchHandler
{
public:
explicit DrawSketchHandlerEllipse(int constructionMethod)
: mode(STATUS_Close)
, method(CENTER_PERIAPSIS_B)
, constrMethod(constructionMethod)
, a(0), b(0), e(0), ratio(0), ae(0)
, num(0), r(0), theta(0), phi(0)
, editCurve(33), fixedAxisLength(0)
{
}
virtual ~DrawSketchHandlerEllipse(){}
: mode(STATUS_Close)
, method(CENTER_PERIAPSIS_B)
, constrMethod(constructionMethod)
, a(0)
, b(0)
, e(0)
, ratio(0)
, ae(0)
, num(0)
, r(0)
, theta(0)
, phi(0)
, editCurve(33)
, fixedAxisLength(0)
{}
virtual ~DrawSketchHandlerEllipse()
{}
/// Mode table, describes what step of the process we are in
enum SelectMode {
STATUS_SEEK_PERIAPSIS, /**< enum value, looking for click to set periapsis. */
STATUS_SEEK_APOAPSIS, /**< enum value, looking for click to set apoapsis. */
STATUS_SEEK_CENTROID, /**< enum value, looking for click to set centroid. */
STATUS_SEEK_A, /**< enum value, looking for click to set a. */
STATUS_SEEK_B, /**< enum value, looking for click to set b. */
STATUS_Close /**< enum value, finalizing and saving ellipse. */
enum SelectMode
{
STATUS_SEEK_PERIAPSIS, /**< enum value, looking for click to set periapsis. */
STATUS_SEEK_APOAPSIS, /**< enum value, looking for click to set apoapsis. */
STATUS_SEEK_CENTROID, /**< enum value, looking for click to set centroid. */
STATUS_SEEK_A, /**< enum value, looking for click to set a. */
STATUS_SEEK_B, /**< enum value, looking for click to set b. */
STATUS_Close /**< enum value, finalizing and saving ellipse. */
};
/// Construction methods, describes the method used to construct the ellipse
enum ConstructionMethod {
CENTER_PERIAPSIS_B, /**< enum value, click on center, then periapsis, then b point. */
PERIAPSIS_APOAPSIS_B /**< enum value, click on periapsis, then apoapsis, then b point. */
enum ConstructionMethod
{
CENTER_PERIAPSIS_B, /**< enum value, click on center, then periapsis, then b point. */
PERIAPSIS_APOAPSIS_B /**< enum value, click on periapsis, then apoapsis, then b point. */
};
/**
@@ -112,12 +125,13 @@ public:
if (method == PERIAPSIS_APOAPSIS_B) {
if (mode == STATUS_SEEK_PERIAPSIS) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
} else if (mode == STATUS_SEEK_APOAPSIS) {
}
else if (mode == STATUS_SEEK_APOAPSIS) {
solveEllipse(onSketchPos);
approximateEllipse();
@@ -133,12 +147,13 @@ public:
drawEdit(editCurve);
// Suggestions for ellipse and curves are disabled because many tangent constraints
// need an intermediate point or line.
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
} else if (mode == STATUS_SEEK_B) {
}
else if (mode == STATUS_SEEK_B) {
solveEllipse(onSketchPos);
approximateEllipse();
@@ -152,20 +167,23 @@ public:
}
drawEdit(editCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f),
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f), AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
}
} else { // method is CENTER_PERIAPSIS_B
}
else {// method is CENTER_PERIAPSIS_B
if (mode == STATUS_SEEK_CENTROID) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) { // TODO: ellipse prio 1
if (seekAutoConstraint(
sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {// TODO: ellipse prio 1
renderSuggestConstraintsCursor(sugConstr1);
return;
}
} else if (mode == STATUS_SEEK_PERIAPSIS) {
}
else if (mode == STATUS_SEEK_PERIAPSIS) {
solveEllipse(onSketchPos);
approximateEllipse();
@@ -179,12 +197,13 @@ public:
}
drawEdit(editCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - centroid,
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr2, onSketchPos, onSketchPos - centroid, AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
} else if ((mode == STATUS_SEEK_A) || (mode == STATUS_SEEK_B)) {
}
else if ((mode == STATUS_SEEK_A) || (mode == STATUS_SEEK_B)) {
solveEllipse(onSketchPos);
approximateEllipse();
@@ -198,8 +217,8 @@ public:
}
drawEdit(editCurve);
if (seekAutoConstraint(sugConstr3, onSketchPos, onSketchPos - centroid,
AutoConstraint::CURVE)) {
if (seekAutoConstraint(
sugConstr3, onSketchPos, onSketchPos - centroid, AutoConstraint::CURVE)) {
renderSuggestConstraintsCursor(sugConstr3);
return;
}
@@ -229,7 +248,8 @@ public:
else {
mode = STATUS_Close;
}
} else { // method is CENTER_PERIAPSIS_B
}
else {// method is CENTER_PERIAPSIS_B
if (mode == STATUS_SEEK_CENTROID) {
centroid = onSketchPos;
setAngleSnapping(true, centroid);
@@ -257,14 +277,16 @@ public:
Q_UNUSED(onSketchPos);
if (mode == STATUS_Close) {
saveEllipse();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
if (constrMethod == 0) {
method = CENTER_PERIAPSIS_B;
mode = STATUS_SEEK_CENTROID;
} else {
}
else {
method = PERIAPSIS_APOAPSIS_B;
mode = STATUS_SEEK_PERIAPSIS;
}
@@ -283,7 +305,8 @@ private:
if (constrMethod == 0) {
method = CENTER_PERIAPSIS_B;
mode = STATUS_SEEK_CENTROID;
} else {
}
else {
method = PERIAPSIS_APOAPSIS_B;
mode = STATUS_SEEK_PERIAPSIS;
}
@@ -295,6 +318,7 @@ private:
protected:
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3;
private:
SelectMode mode;
/// the method of constructing the ellipse
@@ -366,7 +390,7 @@ private:
void solveEllipse(Base::Vector2d onSketchPos)
{
const double GOLDEN_RATIO = 1.6180339887;
Base::Vector3d k(0,0,1);
Base::Vector3d k(0, 0, 1);
if (method == PERIAPSIS_APOAPSIS_B) {
if (mode == STATUS_SEEK_APOAPSIS) {
@@ -380,16 +404,19 @@ private:
centroid = periapsis + centroid;
if (mode == STATUS_SEEK_APOAPSIS) {
// for first step, we draw an ellipse inscribed in a golden rectangle
ratio = 1 / GOLDEN_RATIO; // ~= 0.6180339887
e = sqrt(ratio); // ~= 0.7861513777
ratio = 1 / GOLDEN_RATIO;// ~= 0.6180339887
e = sqrt(ratio); // ~= 0.7861513777
b = a * ratio;
}
else if (mode == STATUS_SEEK_B) {
// Get the closest distance from onSketchPos to apse line, as a 'requested' value for b
Base::Vector2d cursor = Base::Vector2d(onSketchPos - f); // vector from f to cursor pos
// Get the closest distance from onSketchPos to apse line, as a 'requested' value
// for b
Base::Vector2d cursor =
Base::Vector2d(onSketchPos - f);// vector from f to cursor pos
// decompose cursor with a projection, then length of w_2 will give us b
Base::Vector2d w_1 = cursor;
w_1.ProjectToLine(cursor, (periapsis - apoapsis)); // projection of cursor line onto apse line
w_1.ProjectToLine(
cursor, (periapsis - apoapsis));// projection of cursor line onto apse line
Base::Vector2d w_2 = (cursor - w_1);
b = w_2.Length();
@@ -399,7 +426,7 @@ private:
}
e = sqrt(1 - ((b * b) / (a * a)));
ratio = sqrt(1 - (e*e));
ratio = sqrt(1 - (e * e));
}
ae = a * e;
f = apseHat;
@@ -411,7 +438,8 @@ private:
phi = atan2(apseHat.y, apseHat.x);
num = a * (1 - (e * e));
// The ellipse is now solved
} else { // method == CENTER_PERIAPSIS_B
}
else {// method == CENTER_PERIAPSIS_B
if (mode == STATUS_SEEK_PERIAPSIS) {
// solve the ellipse inscribed in a golden rectangle
periapsis = onSketchPos;
@@ -419,11 +447,11 @@ private:
iPrime.x = periapsis.x - centroid.x;
iPrime.y = periapsis.y - centroid.y;
iPrime.z = 0;
jPrime = k % iPrime; // j = k cross i
jPrime = k % iPrime;// j = k cross i
// these are constant for any ellipse inscribed in a golden rectangle
ratio = 1 / GOLDEN_RATIO; // ~= 0.6180339887
e = sqrt(ratio); // ~= 0.7861513777
ratio = 1 / GOLDEN_RATIO;// ~= 0.6180339887
e = sqrt(ratio); // ~= 0.7861513777
b = a * ratio;
ae = a * e;
@@ -442,14 +470,18 @@ private:
num = a * (1 - (e * e));
fixedAxisLength = a;
fixedAxis = periapsis;
} else if ((mode == STATUS_SEEK_B) || (mode == STATUS_SEEK_A)) {
}
else if ((mode == STATUS_SEEK_B) || (mode == STATUS_SEEK_A)) {
// while looking for the last click, we may switch back and forth
// between looking for a b point and looking for periapsis, so ensure
// we are in the right mode
Base::Vector2d cursor = Base::Vector2d(onSketchPos - centroid); // vector from centroid to cursor pos
Base::Vector2d cursor =
Base::Vector2d(onSketchPos - centroid);// vector from centroid to cursor pos
// decompose cursor with a projection, then length of w_2 will give us b
Base::Vector2d w_1 = cursor;
w_1.ProjectToLine(cursor, (fixedAxis - centroid)); // projection of cursor line onto fixed axis line
w_1.ProjectToLine(
cursor,
(fixedAxis - centroid));// projection of cursor line onto fixed axis line
Base::Vector2d w_2 = (cursor - w_1);
if (w_2.Length() > fixedAxisLength) {
// b is fixed, we are seeking a
@@ -457,16 +489,17 @@ private:
jPrime.x = (fixedAxis - centroid).x;
jPrime.y = (fixedAxis - centroid).y;
jPrime.Normalize();
iPrime = jPrime % k; // cross
iPrime = jPrime % k;// cross
b = fixedAxisLength;
a = w_2.Length();
} else {
}
else {
// a is fixed, we are seeking b
mode = STATUS_SEEK_B;
iPrime.x = (fixedAxis - centroid).x;
iPrime.y = (fixedAxis - centroid).y;
iPrime.Normalize();
jPrime = k % iPrime; // cross
jPrime = k % iPrime;// cross
a = fixedAxisLength;
b = w_2.Length();
}
@@ -474,7 +507,7 @@ private:
periapsis.x = centroid.x + (iPrime * a).x;
periapsis.y = centroid.y + (iPrime * a).y;
e = sqrt(1 - ((b * b) / (a * a)));
ratio = sqrt(1 - (e*e));
ratio = sqrt(1 - (e * e));
ae = a * e;
apseHat = (periapsis - centroid);
apseHat.Normalize();
@@ -509,49 +542,53 @@ private:
// the semi-minor axis.
double partitionAngle = (M_PI - atan2(b, ae)) / n;
double radianShift = 0;
if (e > 0.8) {radianShift = (partitionAngle / 5) * 4;}
for (int i=0; i < n; i++) {
if (e > 0.8) {
radianShift = (partitionAngle / 5) * 4;
}
for (int i = 0; i < n; i++) {
theta = i * partitionAngle;
if (i > 0) {theta = theta + radianShift;}
if (i > 0) {
theta = theta + radianShift;
}
r = num / (1 + (e * cos(theta)));
// r(pi/2) is semi-latus rectum, if we need it
pos.x = r*cos(theta+phi); // phi rotates, sin/cos translate
pos.y = r*sin(theta+phi);
pos.x = r * cos(theta + phi);// phi rotates, sin/cos translate
pos.y = r * sin(theta + phi);
pos = pos + f;
posPrime.x = r*cos(theta+phi+M_PI);
posPrime.y = r*sin(theta+phi+M_PI);
posPrime.x = r * cos(theta + phi + M_PI);
posPrime.y = r * sin(theta + phi + M_PI);
posPrime = posPrime + fPrime;
// over the loop, loads Quadrant I points, by using f as origin
editCurve[i] = pos;
// over the loop, loads Quadrant III points, by using fPrime as origin
editCurve[(2*n) + i] = posPrime;
editCurve[(2 * n) + i] = posPrime;
// load points with negative theta angles (i.e. cw)
if (i>0) {
pos.x = r*cos(-1*theta+phi);
pos.y = r*sin(-1*theta+phi);
if (i > 0) {
pos.x = r * cos(-1 * theta + phi);
pos.y = r * sin(-1 * theta + phi);
pos = pos + f;
// loads Quadrant IV points
editCurve[(4*n) - i] = pos;
posPrime.x = r*cos(-1*theta+phi+M_PI);
posPrime.y = r*sin(-1*theta+phi+M_PI);
editCurve[(4 * n) - i] = pos;
posPrime.x = r * cos(-1 * theta + phi + M_PI);
posPrime.y = r * sin(-1 * theta + phi + M_PI);
posPrime = posPrime + fPrime;
// loads Quadrant II points
editCurve[(2*n) - i] = posPrime;
editCurve[(2 * n) - i] = posPrime;
}
}
// load pos & neg b points
theta = M_PI - atan2(b, ae); // the angle from f to the positive b point
theta = M_PI - atan2(b, ae);// the angle from f to the positive b point
r = num / (1 + (e * cos(theta)));
pos.x = r*cos(theta+phi);
pos.y = r*sin(theta+phi);
pos.x = r * cos(theta + phi);
pos.y = r * sin(theta + phi);
pos = pos + f;
editCurve[n] = pos; // positive
pos.x = r*cos(-1*theta+phi);
pos.y = r*sin(-1*theta+phi);
editCurve[n] = pos;// positive
pos.x = r * cos(-1 * theta + phi);
pos.y = r * sin(-1 * theta + phi);
pos = pos + f;
editCurve[(3*n)] = pos; // negative
editCurve[(3 * n)] = pos;// negative
// force the curve to be a closed shape
editCurve[(4*n)] = editCurve[0];
editCurve[(4 * n)] = editCurve[0];
}
/**
@@ -578,17 +615,17 @@ private:
octave << "fPrime = [" << fPrime.x << ", " << fPrime.y << "];\n";
octave << "phi = " << phi << ";\n\n";
octave << "x = [";
for (int i=0; i < 4*n + 1; i++) {
for (int i = 0; i < 4 * n + 1; i++) {
octave << editCurve[i].x;
if (i < 4*n) {
if (i < 4 * n) {
octave << ", ";
}
}
octave << "];\n";
octave << "y = [";
for (int i=0; i < 4*n + 1; i++) {
for (int i = 0; i < 4 * n + 1; i++) {
octave << editCurve[i].y;
if (i < 4*n) {
if (i < 4 * n) {
octave << ", ";
}
}
@@ -611,10 +648,14 @@ private:
octave << "set (centroidVec, \"maxheadsize\", 0.01, \"color\", \"black\");\n";
octave << "bVec = quiver(0,0,positiveB(1),positiveB(2), 0);\n";
octave << "set (bVec, \"maxheadsize\", 0.01, \"color\", \"black\");\n\n";
octave << "% Draw the local x & y basis vectors, scaled to a and b, in red and blue, respectively\n";
octave << "xLocalVec = quiver(centroid(1),centroid(2),periapsis(1)-centroid(1),periapsis(2)-centroid(2), 0);\n";
octave << "% Draw the local x & y basis vectors, scaled to a and b, in red and blue, "
"respectively\n";
octave << "xLocalVec = "
"quiver(centroid(1),centroid(2),periapsis(1)-centroid(1),periapsis(2)-centroid(2)"
", 0);\n";
octave << "set (xLocalVec, \"maxheadsize\", 0.01, \"color\", \"red\");\n";
octave << "yLocalVec = quiver(centroid(1),centroid(2), positiveB(1)-centroid(1), positiveB(2)-centroid(2), 0);\n";
octave << "yLocalVec = quiver(centroid(1),centroid(2), positiveB(1)-centroid(1), "
"positiveB(2)-centroid(2), 0);\n";
octave << "set (yLocalVec, \"maxheadsize\", 0.01, \"color\", \"blue\");\nhold off;\n";
qDebug() << QString::fromStdString(octave.str());
}
@@ -679,12 +720,12 @@ private:
/* GC_MakeEllipse requires a right-handed coordinate system, with +X
* from centroid to periapsis, +Z out of the page.
*/
Base::Vector3d k(0,0,1);
Base::Vector3d k(0, 0, 1);
Base::Vector3d i(periapsis.x - centroid.x, periapsis.y - centroid.y, 0);
Base::Vector3d j = k % i; // j = k cross i
Base::Vector3d j = k % i;// j = k cross i
double beta = 1e-7;
int count = 0;
int limit = 25; // no infinite loops!
int limit = 25;// no infinite loops!
bool success = false;
double tempB = b;
@@ -710,9 +751,9 @@ private:
positiveB.y = atof(bpy);
negativeB.x = atof(bnx);
negativeB.y = atof(bny);
GC_MakeEllipse me(gp_Pnt(periapsis.x,periapsis.y,0),
gp_Pnt(positiveB.x,positiveB.y,0),
gp_Pnt(centroid.x,centroid.y,0));
GC_MakeEllipse me(gp_Pnt(periapsis.x, periapsis.y, 0),
gp_Pnt(positiveB.x, positiveB.y, 0),
gp_Pnt(centroid.x, centroid.y, 0));
minorLength = (negativeB - positiveB).Length();
count++;
success = me.IsDone() && (minorLength + beta < majorLength);
@@ -732,28 +773,35 @@ private:
fPrime.Scale(-1 * ae);
fPrime = centroid + fPrime;
int currentgeoid = getHighestCurveIndex(); // index of the ellipse we just created
int currentgeoid = getHighestCurveIndex();// index of the ellipse we just created
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch ellipse"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Ellipse"
"(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
periapsis.x, periapsis.y,
positiveB.x, positiveB.y,
centroid.x, centroid.y,
geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.Ellipse"
"(App.Vector(%f,%f,0),App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
periapsis.x,
periapsis.y,
positiveB.x,
positiveB.y,
centroid.x,
centroid.y,
geometryCreationMode == Construction ? "True" : "False");
currentgeoid++;
Gui::cmdAppObjectArgs(sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "exposeInternalGeometry(%d)", currentgeoid);
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add an ellipse"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add an ellipse"));
Gui::Command::abortCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
return;
}
@@ -791,41 +839,42 @@ private:
}
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
// This code enables the continuous creation mode.
if (constrMethod == 0) {
method = CENTER_PERIAPSIS_B;
mode = STATUS_SEEK_CENTROID;
} else {
}
else {
method = PERIAPSIS_APOAPSIS_B;
mode = STATUS_SEEK_PERIAPSIS;
}
editCurve.clear();
drawEdit(editCurve);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
editCurve.resize(33);
applyCursor();
/* It is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerEllipse_H
#endif// SKETCHERGUI_DrawSketchHandlerEllipse_H
+119 -73
View File
@@ -28,13 +28,15 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class ExtendSelection : public Gui::SelectionFilterGate
class ExtendSelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit ExtendSelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer())
@@ -42,7 +44,7 @@ public:
, disabled(false)
{}
bool allow(App::Document * /*pDoc*/, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName)
{
if (pObj != this->object)
return false;
@@ -53,18 +55,20 @@ public:
std::string element(sSubName);
if (element.substr(0, 4) == "Edge") {
int GeoId = std::atoi(element.substr(4, 4000).c_str()) - 1;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry* geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
return true;
}
return false;
}
void setDisabled(bool isDisabled) {
void setDisabled(bool isDisabled)
{
disabled = isDisabled;
}
protected:
bool disabled;
};
@@ -79,13 +83,15 @@ public:
, BaseGeoId(-1)
, ExtendFromStart(false)
, SavedExtendFromStart(false)
, Increment(0) {}
, Increment(0)
{}
virtual ~DrawSketchHandlerExtend()
{
Gui::Selection().rmvSelectionGate();
}
enum SelectMode {
enum SelectMode
{
STATUS_SEEK_First,
STATUS_SEEK_Second,
};
@@ -94,9 +100,10 @@ public:
{
Q_UNUSED(onSketchPos);
if (Mode == STATUS_SEEK_Second) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(BaseGeoId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(BaseGeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = static_cast<const Part::GeomLineSegment *>(geom);
const Part::GeomLineSegment* lineSeg =
static_cast<const Part::GeomLineSegment*>(geom);
// project point to the existing curve
Base::Vector3d start3d = lineSeg->getStartPoint();
Base::Vector3d end3d = lineSeg->getEndPoint();
@@ -110,7 +117,8 @@ public:
if (recenteredPoint.Length() < recenteredPoint.Distance(recenteredLine)) {
EditCurve[0] = startPoint + projection;
EditCurve[1] = endPoint;
} else {
}
else {
EditCurve[0] = startPoint;
EditCurve[1] = startPoint + projection;
}
@@ -122,18 +130,25 @@ public:
* expand.
*/
bool inCurve = (projection.Length() < recenteredLine.Length()
&& projection.GetAngle(recenteredLine) < 0.1); // Two possible values here, M_PI and 0, but 0.1 is to avoid floating point problems.
&& projection.GetAngle(recenteredLine)
< 0.1);// Two possible values here, M_PI and 0, but 0.1 is to
// avoid floating point problems.
if (inCurve) {
Increment = SavedExtendFromStart ? -1 * projection.Length() : projection.Length() - recenteredLine.Length();
Increment = SavedExtendFromStart
? -1 * projection.Length()
: projection.Length() - recenteredLine.Length();
ExtendFromStart = SavedExtendFromStart;
} else {
ExtendFromStart = onSketchPos.Distance(startPoint) < onSketchPos.Distance(endPoint);
Increment = ExtendFromStart ? projection.Length() : projection.Length() - recenteredLine.Length();
}
else {
ExtendFromStart =
onSketchPos.Distance(startPoint) < onSketchPos.Distance(endPoint);
Increment = ExtendFromStart ? projection.Length()
: projection.Length() - recenteredLine.Length();
}
drawEdit(EditCurve);
} else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arc = static_cast<const Part::GeomArcOfCircle *>(geom);
}
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>(geom);
Base::Vector3d center = arc->getCenter();
double radius = arc->getRadius();
@@ -141,11 +156,13 @@ public:
arc->getRange(start, end, true);
double arcAngle = end - start;
Base::Vector2d angle = Base::Vector2d(onSketchPos.x - center.x, onSketchPos.y - center.y);
Base::Vector2d angle =
Base::Vector2d(onSketchPos.x - center.x, onSketchPos.y - center.y);
Base::Vector2d startAngle = Base::Vector2d(cos(start), sin(start));
Base::Vector2d endAngle = Base::Vector2d(cos(end), sin(end));
Base::Vector2d arcHalf = Base::Vector2d(cos(start + arcAngle/ 2.0), sin(start+ arcAngle / 2.0));
Base::Vector2d arcHalf =
Base::Vector2d(cos(start + arcAngle / 2.0), sin(start + arcAngle / 2.0));
double angleToEndAngle = angle.GetAngle(endAngle);
double angleToStartAngle = angle.GetAngle(startAngle);
@@ -157,46 +174,55 @@ public:
bool isCCWFromStart = crossProduct(angle, startAngle) < 0;
if (outOfArc) {
if (isCCWFromStart) {
modStartAngle -= 2*M_PI - angleToStartAngle;
modArcAngle += 2*M_PI - angleToStartAngle;
} else {
modStartAngle -= 2 * M_PI - angleToStartAngle;
modArcAngle += 2 * M_PI - angleToStartAngle;
}
else {
modStartAngle -= angleToStartAngle;
modArcAngle += angleToStartAngle;
}
} else {
}
else {
if (isCCWFromStart) {
modStartAngle += angleToStartAngle;
modArcAngle -= angleToStartAngle;
} else {
modStartAngle += 2*M_PI - angleToStartAngle;
modArcAngle -= 2*M_PI - angleToStartAngle;
}
else {
modStartAngle += 2 * M_PI - angleToStartAngle;
modArcAngle -= 2 * M_PI - angleToStartAngle;
}
}
} else {
}
else {
bool isCWFromEnd = crossProduct(angle, endAngle) >= 0;
if (outOfArc) {
if (isCWFromEnd) {
modArcAngle += 2*M_PI - angleToEndAngle;
} else {
modArcAngle += 2 * M_PI - angleToEndAngle;
}
else {
modArcAngle += angleToEndAngle;
}
} else {
}
else {
if (isCWFromEnd) {
modArcAngle -= angleToEndAngle;
} else {
modArcAngle -= 2*M_PI - angleToEndAngle;
}
else {
modArcAngle -= 2 * M_PI - angleToEndAngle;
}
}
}
Increment = modArcAngle - (end - start);
for (int i = 0; i < 31; i++) {
double angle = modStartAngle + i * modArcAngle/30.0;
EditCurve[i] = Base::Vector2d(center.x + radius * cos(angle), center.y + radius * sin(angle));
double angle = modStartAngle + i * modArcAngle / 30.0;
EditCurve[i] = Base::Vector2d(center.x + radius * cos(angle),
center.y + radius * sin(angle));
}
drawEdit(EditCurve);
}
int curveId = getPreselectCurve();
if (BaseGeoId != curveId && seekAutoConstraint(SugConstr, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (BaseGeoId != curveId
&& seekAutoConstraint(SugConstr, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(SugConstr);
return;
}
@@ -215,76 +241,95 @@ public:
if (Mode == STATUS_SEEK_First) {
BaseGeoId = getPreselectCurve();
if (BaseGeoId > -1) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(BaseGeoId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(BaseGeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *seg = static_cast<const Part::GeomLineSegment *>(geom);
const Part::GeomLineSegment* seg =
static_cast<const Part::GeomLineSegment*>(geom);
Base::Vector3d start3d = seg->getStartPoint();
Base::Vector3d end3d = seg->getEndPoint();
Base::Vector2d start = Base::Vector2d(start3d.x, start3d.y);
Base::Vector2d end = Base::Vector2d(end3d.x, end3d.y);
SavedExtendFromStart = (onSketchPos.Distance(start) < onSketchPos.Distance(end));
SavedExtendFromStart =
(onSketchPos.Distance(start) < onSketchPos.Distance(end));
ExtendFromStart = SavedExtendFromStart;
Mode = STATUS_SEEK_Second;
} else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arc = static_cast<const Part::GeomArcOfCircle *>(geom);
}
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle* arc =
static_cast<const Part::GeomArcOfCircle*>(geom);
double start, end;
arc->getRange(start, end, true);
Base::Vector3d center = arc->getCenter();
Base::Vector2d angle = Base::Vector2d(onSketchPos.x - center.x, onSketchPos.y - center.y);
Base::Vector2d angle =
Base::Vector2d(onSketchPos.x - center.x, onSketchPos.y - center.y);
double angleToStart = angle.GetAngle(Base::Vector2d(cos(start), sin(start)));
double angleToEnd = angle.GetAngle(Base::Vector2d(cos(end), sin(end)));
ExtendFromStart = (angleToStart < angleToEnd); // move start point if closer to angle than end point
ExtendFromStart =
(angleToStart
< angleToEnd);// move start point if closer to angle than end point
EditCurve.resize(31);
Mode = STATUS_SEEK_Second;
}
filterGate->setDisabled(true);
}
} else if (Mode == STATUS_SEEK_Second) {
}
else if (Mode == STATUS_SEEK_Second) {
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Extend edge"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "extend(%d, %f, %d)\n", // GeoId, increment, PointPos
BaseGeoId, Increment, ExtendFromStart ? static_cast<int>(Sketcher::PointPos::start) : static_cast<int>(Sketcher::PointPos::end));
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"extend(%d, %f, %d)\n",// GeoId, increment, PointPos
BaseGeoId,
Increment,
ExtendFromStart ? static_cast<int>(Sketcher::PointPos::start)
: static_cast<int>(Sketcher::PointPos::end));
Gui::Command::commitCommand();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
if(autoRecompute)
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool autoRecompute = hGrp->GetBool("AutoRecompute", false);
if (autoRecompute)
Gui::Command::updateActive();
// constrain chosen point
if (!SugConstr.empty()) {
createAutoConstraints(SugConstr, BaseGeoId, (ExtendFromStart) ? Sketcher::PointPos::start : Sketcher::PointPos::end);
createAutoConstraints(SugConstr,
BaseGeoId,
(ExtendFromStart) ? Sketcher::PointPos::start
: Sketcher::PointPos::end);
SugConstr.clear();
}
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
filterGate->setDisabled(false);
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
} else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else {
sketchgui->purgeHandler();// no code after this line, Handler get deleted in
// ViewProvider
}
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to extend edge"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to extend edge"));
Gui::Command::abortCommand();
}
} else { // exit extension tool if user clicked on empty space
}
else {// exit extension tool if user clicked on empty space
BaseGeoId = -1;
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
return true;
}
@@ -298,7 +343,8 @@ private:
Gui::Selection().addSelectionGate(filterGate);
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Extension");
}
@@ -307,20 +353,20 @@ protected:
std::vector<Base::Vector2d> EditCurve;
int BaseGeoId;
ExtendSelection* filterGate = nullptr;
bool ExtendFromStart; // if true, extend from start, else extend from end (circle only)
bool ExtendFromStart;// if true, extend from start, else extend from end (circle only)
bool SavedExtendFromStart;
double Increment;
std::vector<AutoConstraint> SugConstr;
private:
int crossProduct(Base::Vector2d &vec1, Base::Vector2d &vec2) {
int crossProduct(Base::Vector2d& vec1, Base::Vector2d& vec2)
{
return vec1.x * vec2.y - vec1.y * vec2.x;
}
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerExtend_H
#endif// SKETCHERGUI_DrawSketchHandlerExtend_H
@@ -28,65 +28,73 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class ExternalSelection : public Gui::SelectionFilterGate
class ExternalSelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit ExternalSelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer()), object(obj)
: Gui::SelectionFilterGate(nullPointer())
, object(obj)
{}
bool allow(App::Document *pDoc, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName)
{
Sketcher::SketchObject *sketch = static_cast<Sketcher::SketchObject*>(object);
Sketcher::SketchObject* sketch = static_cast<Sketcher::SketchObject*>(object);
this->notAllowedReason = "";
Sketcher::SketchObject::eReasonList msg;
if (!sketch->isExternalAllowed(pDoc, pObj, &msg)){
switch(msg){
case Sketcher::SketchObject::rlCircularReference:
this->notAllowedReason = QT_TR_NOOP("Linking this will cause circular dependency.");
break;
case Sketcher::SketchObject::rlOtherDoc:
this->notAllowedReason = QT_TR_NOOP("This object is in another document.");
break;
case Sketcher::SketchObject::rlOtherBody:
this->notAllowedReason = QT_TR_NOOP("This object belongs to another body, can't link.");
break;
case Sketcher::SketchObject::rlOtherPart:
this->notAllowedReason = QT_TR_NOOP("This object belongs to another part, can't link.");
break;
default:
break;
if (!sketch->isExternalAllowed(pDoc, pObj, &msg)) {
switch (msg) {
case Sketcher::SketchObject::rlCircularReference:
this->notAllowedReason =
QT_TR_NOOP("Linking this will cause circular dependency.");
break;
case Sketcher::SketchObject::rlOtherDoc:
this->notAllowedReason = QT_TR_NOOP("This object is in another document.");
break;
case Sketcher::SketchObject::rlOtherBody:
this->notAllowedReason =
QT_TR_NOOP("This object belongs to another body, can't link.");
break;
case Sketcher::SketchObject::rlOtherPart:
this->notAllowedReason =
QT_TR_NOOP("This object belongs to another part, can't link.");
break;
default:
break;
}
return false;
}
// Note: its better to search the support of the sketch in case the sketch support is a base plane
//Part::BodyBase* body = Part::BodyBase::findBodyOf(sketch);
//if ( body && body->hasFeature ( pObj ) && body->isAfter ( pObj, sketch ) ) {
// Don't allow selection after the sketch in the same body
// NOTE: allowness of features in other bodies is handled by SketchObject::isExternalAllowed()
// TODO may be this should be in SketchObject::isExternalAllowed() (2015-08-07, Fat-Zer)
//return false;
// Note: its better to search the support of the sketch in case the sketch support is a base
// plane
// Part::BodyBase* body = Part::BodyBase::findBodyOf(sketch);
// if ( body && body->hasFeature ( pObj ) && body->isAfter ( pObj, sketch ) ) {
// Don't allow selection after the sketch in the same body
// NOTE: allowness of features in other bodies is handled by
// SketchObject::isExternalAllowed()
// TODO may be this should be in SketchObject::isExternalAllowed() (2015-08-07, Fat-Zer)
// return false;
//}
if (!sSubName || sSubName[0] == '\0')
return false;
std::string element(sSubName);
if ((element.size() > 4 && element.substr(0,4) == "Edge") ||
(element.size() > 6 && element.substr(0,6) == "Vertex") ||
(element.size() > 4 && element.substr(0,4) == "Face")) {
if ((element.size() > 4 && element.substr(0, 4) == "Edge")
|| (element.size() > 6 && element.substr(0, 6) == "Vertex")
|| (element.size() > 4 && element.substr(0, 4) == "Face")) {
return true;
}
if (pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ||
pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()))
if (pObj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())
|| pObj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()))
return true;
return false;
return false;
}
};
@@ -116,47 +124,53 @@ public:
{
Q_UNUSED(onSketchPos);
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
return true;
}
bool onSelectionChanged(const Gui::SelectionChanges& msg) override
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
App::DocumentObject* obj = sketchgui->getObject()->getDocument()->getObject(msg.pObjectName);
App::DocumentObject* obj =
sketchgui->getObject()->getDocument()->getObject(msg.pObjectName);
if (!obj)
throw Base::ValueError("Sketcher: External geometry: Invalid object in selection");
std::string subName(msg.pSubName);
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ||
obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()) ||
(subName.size() > 4 && subName.substr(0,4) == "Edge") ||
(subName.size() > 6 && subName.substr(0,6) == "Vertex") ||
(subName.size() > 4 && subName.substr(0,4) == "Face")) {
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())
|| obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())
|| (subName.size() > 4 && subName.substr(0, 4) == "Edge")
|| (subName.size() > 6 && subName.substr(0, 6) == "Vertex")
|| (subName.size() > 4 && subName.substr(0, 4) == "Face")) {
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add external geometry"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addExternal(\"%s\",\"%s\")",
msg.pObjectName, msg.pSubName);
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add external geometry"));
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addExternal(\"%s\",\"%s\")",
msg.pObjectName,
msg.pSubName);
Gui::Command::commitCommand();
// adding external geometry does not require a solve() per se (the DoF is the same),
// however a solve is required to update the amount of solver geometry, because we only
// redraw a changed Sketch if the solver geometry amount is the same as the SkethObject
// geometry amount (as this avoids other issues).
// This solver is a very low cost one anyway (there is actually nothing to solve).
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
// adding external geometry does not require a solve() per se (the DoF is the
// same), however a solve is required to update the amount of solver geometry,
// because we only redraw a changed Sketch if the solver geometry amount is the
// same as the SkethObject geometry amount (as this avoids other issues). This
// solver is a very low cost one anyway (there is actually nothing to solve).
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
Gui::Selection().clearSelection();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add external geometry"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add external geometry"));
Gui::Selection().clearSelection();
Gui::Command::abortCommand();
}
@@ -170,9 +184,9 @@ private:
void activated() override
{
setAxisPickStyle(false);
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
Gui::View3DInventorViewer *viewer;
viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView();
Gui::View3DInventorViewer* viewer;
viewer = static_cast<Gui::View3DInventor*>(mdi)->getViewer();
viewer->setSelectionEnabled(true);
Gui::Selection().clearSelection();
@@ -180,7 +194,8 @@ private:
Gui::Selection().addSelectionGate(new ExternalSelection(sketchgui->getObject()));
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_External");
}
@@ -192,8 +207,7 @@ private:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerExternal_H
#endif// SKETCHERGUI_DrawSketchHandlerExternal_H
+125 -89
View File
@@ -28,47 +28,50 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class FilletSelection : public Gui::SelectionFilterGate
class FilletSelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit FilletSelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer()), object(obj)
: Gui::SelectionFilterGate(nullPointer())
, object(obj)
{}
bool allow(App::Document * /*pDoc*/, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName)
{
if (pObj != this->object)
return false;
if (!sSubName || sSubName[0] == '\0')
return false;
std::string element(sSubName);
if (element.substr(0,4) == "Edge") {
int GeoId = std::atoi(element.substr(4,4000).c_str()) - 1;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
if (element.substr(0, 4) == "Edge") {
int GeoId = std::atoi(element.substr(4, 4000).c_str()) - 1;
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry* geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomBoundedCurve::getClassTypeId()))
return true;
}
if (element.substr(0,6) == "Vertex") {
int VtId = std::atoi(element.substr(6,4000).c_str()) - 1;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
if (element.substr(0, 6) == "Vertex") {
int VtId = std::atoi(element.substr(6, 4000).c_str()) - 1;
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
std::vector<int> GeoIdList;
std::vector<Sketcher::PointPos> PosIdList;
Sketch->getDirectlyCoincidentPoints(VtId, GeoIdList, PosIdList);
if (GeoIdList.size() == 2 && GeoIdList[0] >= 0 && GeoIdList[1] >= 0) {
const Part::Geometry *geom1 = Sketch->getGeometry(GeoIdList[0]);
const Part::Geometry *geom2 = Sketch->getGeometry(GeoIdList[1]);
if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId())
if (GeoIdList.size() == 2 && GeoIdList[0] >= 0 && GeoIdList[1] >= 0) {
const Part::Geometry* geom1 = Sketch->getGeometry(GeoIdList[0]);
const Part::Geometry* geom2 = Sketch->getGeometry(GeoIdList[1]);
if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId()
&& geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId())
return true;
}
}
return false;
return false;
}
};
@@ -76,18 +79,24 @@ public:
class DrawSketchHandlerFillet: public DrawSketchHandler
{
public:
enum FilletType {
enum FilletType
{
SimpleFillet,
ConstraintPreservingFillet
};
explicit DrawSketchHandlerFillet(FilletType filletType) : filletType(filletType), Mode(STATUS_SEEK_First), firstCurve(0) {}
explicit DrawSketchHandlerFillet(FilletType filletType)
: filletType(filletType)
, Mode(STATUS_SEEK_First)
, firstCurve(0)
{}
virtual ~DrawSketchHandlerFillet()
{
Gui::Selection().rmvSelectionGate();
}
enum SelectMode{
enum SelectMode
{
STATUS_SEEK_First,
STATUS_SEEK_Second
};
@@ -105,29 +114,35 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
bool construction=false;
bool construction = false;
int VtId = getPreselectPoint();
if (Mode == STATUS_SEEK_First && VtId != -1) {
int GeoId;
Sketcher::PointPos PosId=Sketcher::PointPos::none;
sketchgui->getSketchObject()->getGeoVertexIndex(VtId,GeoId,PosId);
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
(PosId == Sketcher::PointPos::start || PosId == Sketcher::PointPos::end)) {
Sketcher::PointPos PosId = Sketcher::PointPos::none;
sketchgui->getSketchObject()->getGeoVertexIndex(VtId, GeoId, PosId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
&& (PosId == Sketcher::PointPos::start || PosId == Sketcher::PointPos::end)) {
// guess fillet radius
double radius=-1;
double radius = -1;
std::vector<int> GeoIdList;
std::vector<Sketcher::PointPos> PosIdList;
sketchgui->getSketchObject()->getDirectlyCoincidentPoints(GeoId, PosId, GeoIdList, PosIdList);
if (GeoIdList.size() == 2 && GeoIdList[0] >= 0 && GeoIdList[1] >= 0) {
const Part::Geometry *geom1 = sketchgui->getSketchObject()->getGeometry(GeoIdList[0]);
const Part::Geometry *geom2 = sketchgui->getSketchObject()->getGeometry(GeoIdList[1]);
construction=Sketcher::GeometryFacade::getConstruction(geom1) && Sketcher::GeometryFacade::getConstruction(geom2);
if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg1 = static_cast<const Part::GeomLineSegment *>(geom1);
const Part::GeomLineSegment *lineSeg2 = static_cast<const Part::GeomLineSegment *>(geom2);
sketchgui->getSketchObject()->getDirectlyCoincidentPoints(
GeoId, PosId, GeoIdList, PosIdList);
if (GeoIdList.size() == 2 && GeoIdList[0] >= 0 && GeoIdList[1] >= 0) {
const Part::Geometry* geom1 =
sketchgui->getSketchObject()->getGeometry(GeoIdList[0]);
const Part::Geometry* geom2 =
sketchgui->getSketchObject()->getGeometry(GeoIdList[1]);
construction = Sketcher::GeometryFacade::getConstruction(geom1)
&& Sketcher::GeometryFacade::getConstruction(geom2);
if (geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId()
&& geom2->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment* lineSeg1 =
static_cast<const Part::GeomLineSegment*>(geom1);
const Part::GeomLineSegment* lineSeg2 =
static_cast<const Part::GeomLineSegment*>(geom2);
Base::Vector3d dir1 = lineSeg1->getEndPoint() - lineSeg1->getStartPoint();
Base::Vector3d dir2 = lineSeg2->getEndPoint() - lineSeg2->getStartPoint();
if (PosIdList[0] == Sketcher::PointPos::end)
@@ -137,109 +152,130 @@ public:
double l1 = dir1.Length();
double l2 = dir2.Length();
double angle = dir1.GetAngle(dir2);
radius = (l1 < l2 ? l1 : l2) * 0.2 * sin(angle/2);
radius = (l1 < l2 ? l1 : l2) * 0.2 * sin(angle / 2);
}
}
if (radius < 0)
return false;
int currentgeoid= getHighestCurveIndex();
int currentgeoid = getHighestCurveIndex();
// create fillet at point
try {
bool pointFillet = (filletType == 1);
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create fillet"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "fillet(%d,%d,%f,%s,%s)", GeoId, static_cast<int>(PosId), radius, "True",
pointFillet ? "True":"False");
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"fillet(%d,%d,%f,%s,%s)",
GeoId,
static_cast<int>(PosId),
radius,
"True",
pointFillet ? "True" : "False");
if (construction) {
Gui::cmdAppObjectArgs(sketchgui->getObject(), "toggleConstruction(%d) ", currentgeoid+1);
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "toggleConstruction(%d) ", currentgeoid + 1);
}
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(sketchgui->getObject(),
QT_TRANSLATE_NOOP("Notifications", "Failed to create fillet"),
e.what());
Gui::NotifyUserError(
sketchgui->getObject(),
QT_TRANSLATE_NOOP("Notifications", "Failed to create fillet"),
e.what());
Gui::Command::abortCommand();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
return true;
}
int GeoId = getPreselectCurve();
if (GeoId > -1) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomBoundedCurve::getClassTypeId())) {
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
firstCurve = GeoId;
firstPos = onSketchPos;
Mode = STATUS_SEEK_Second;
// add the line to the selection
std::stringstream ss;
ss << "Edge" << firstCurve + 1;
Gui::Selection().addSelection(sketchgui->getSketchObject()->getDocument()->getName()
,sketchgui->getSketchObject()->getNameInDocument()
,ss.str().c_str()
,onSketchPos.x
,onSketchPos.y
,0.f);
Gui::Selection().addSelection(
sketchgui->getSketchObject()->getDocument()->getName(),
sketchgui->getSketchObject()->getNameInDocument(),
ss.str().c_str(),
onSketchPos.x,
onSketchPos.y,
0.f);
}
else if (Mode==STATUS_SEEK_Second) {
else if (Mode == STATUS_SEEK_Second) {
int secondCurve = GeoId;
Base::Vector2d secondPos = onSketchPos;
Base::Vector3d refPnt1(firstPos.x, firstPos.y, 0.f);
Base::Vector3d refPnt2(secondPos.x, secondPos.y, 0.f);
const Part::Geometry *geom1 = sketchgui->getSketchObject()->getGeometry(firstCurve);
const Part::Geometry* geom1 =
sketchgui->getSketchObject()->getGeometry(firstCurve);
double radius = 0;
if( geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() &&
geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
&& geom1->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
// guess fillet radius
const Part::GeomLineSegment *lineSeg1 = static_cast<const Part::GeomLineSegment *>
(sketchgui->getSketchObject()->getGeometry(firstCurve));
const Part::GeomLineSegment *lineSeg2 = static_cast<const Part::GeomLineSegment *>
(sketchgui->getSketchObject()->getGeometry(secondCurve));
const Part::GeomLineSegment* lineSeg1 =
static_cast<const Part::GeomLineSegment*>(
sketchgui->getSketchObject()->getGeometry(firstCurve));
const Part::GeomLineSegment* lineSeg2 =
static_cast<const Part::GeomLineSegment*>(
sketchgui->getSketchObject()->getGeometry(secondCurve));
radius = Part::suggestFilletRadius(lineSeg1, lineSeg2, refPnt1, refPnt2);
if (radius < 0)
return false;
construction=Sketcher::GeometryFacade::getConstruction(lineSeg1) && Sketcher::GeometryFacade::getConstruction(lineSeg2);
construction = Sketcher::GeometryFacade::getConstruction(lineSeg1)
&& Sketcher::GeometryFacade::getConstruction(lineSeg2);
}
else { // other supported curves
const Part::Geometry *geo1 = static_cast<const Part::Geometry *>
(sketchgui->getSketchObject()->getGeometry(firstCurve));
const Part::Geometry *geo2 = static_cast<const Part::Geometry *>
(sketchgui->getSketchObject()->getGeometry(secondCurve));
else {// other supported curves
const Part::Geometry* geo1 = static_cast<const Part::Geometry*>(
sketchgui->getSketchObject()->getGeometry(firstCurve));
const Part::Geometry* geo2 = static_cast<const Part::Geometry*>(
sketchgui->getSketchObject()->getGeometry(secondCurve));
construction=Sketcher::GeometryFacade::getConstruction(geo1) && Sketcher::GeometryFacade::getConstruction(geo2);
construction = Sketcher::GeometryFacade::getConstruction(geo1)
&& Sketcher::GeometryFacade::getConstruction(geo2);
}
int currentgeoid= getHighestCurveIndex();
int currentgeoid = getHighestCurveIndex();
// create fillet between lines
try {
bool pointFillet = (filletType == 1);
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create fillet"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "fillet(%d,%d,App.Vector(%f,%f,0),App.Vector(%f,%f,0),%f,%s,%s)",
firstCurve, secondCurve,
firstPos.x, firstPos.y,
secondPos.x, secondPos.y, radius,
"True", pointFillet ? "True":"False");
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"fillet(%d,%d,App.Vector(%f,%f,0),App.Vector(%f,%f,0),%f,%s,%s)",
firstCurve,
secondCurve,
firstPos.x,
firstPos.y,
secondPos.x,
secondPos.y,
radius,
"True",
pointFillet ? "True" : "False");
Gui::Command::commitCommand();
}
catch (const Base::CADKernelError& e) {
if(e.getTranslatable()) {
if (e.getTranslatable()) {
Gui::TranslatedUserError(sketchgui,
QObject::tr("CAD Kernel Error"),
QObject::tr(e.getMessage().c_str()));
QObject::tr("CAD Kernel Error"),
QObject::tr(e.getMessage().c_str()));
}
Gui::Selection().clearSelection();
Gui::Command::abortCommand();
@@ -247,18 +283,18 @@ public:
}
catch (const Base::ValueError& e) {
Gui::TranslatedUserError(sketchgui,
QObject::tr("Value Error"),
QObject::tr(e.getMessage().c_str()));
QObject::tr("Value Error"),
QObject::tr(e.getMessage().c_str()));
Gui::Selection().clearSelection();
Gui::Command::abortCommand();
Mode = STATUS_SEEK_First;
}
tryAutoRecompute(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
if(construction) {
Gui::cmdAppObjectArgs(sketchgui->getObject(), "toggleConstruction(%d) ",
currentgeoid+1);
if (construction) {
Gui::cmdAppObjectArgs(
sketchgui->getObject(), "toggleConstruction(%d) ", currentgeoid + 1);
}
@@ -268,8 +304,9 @@ public:
}
}
if (VtId < 0 && GeoId < 0) // exit the fillet tool if the user clicked on empty space
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
if (VtId < 0 && GeoId < 0)// exit the fillet tool if the user clicked on empty space
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
return true;
}
@@ -289,8 +326,7 @@ protected:
Base::Vector2d firstPos;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerFillet_H
#endif// SKETCHERGUI_DrawSketchHandlerFillet_H
+53 -36
View File
@@ -27,34 +27,40 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerLine: public DrawSketchHandler
{
public:
DrawSketchHandlerLine():Mode(STATUS_SEEK_First),EditCurve(2){}
virtual ~DrawSketchHandlerLine(){}
DrawSketchHandlerLine()
: Mode(STATUS_SEEK_First)
, EditCurve(2)
{}
virtual ~DrawSketchHandlerLine()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second){
else if (Mode == STATUS_SEEK_Second) {
float length = (onSketchPos - EditCurve[0]).Length();
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2d(1.f,0.f));
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2d(1.f, 0.f));
if (showCursorCoords()) {
SbString text;
std::string lengthString = lengthToDisplayFormat(length, 1);
@@ -75,7 +81,7 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos;
setAngleSnapping(true, EditCurve[0]);
@@ -93,35 +99,46 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_End){
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch line"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y,
geometryCreationMode==Construction?"True":"False");
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
EditCurve[0].x,
EditCurve[0].y,
EditCurve[1].x,
EditCurve[1].y,
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add line"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add line"));
Gui::Command::abortCommand();
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool avoidredundant = sketchgui->AvoidRedundant.getValue() && sketchgui->Autoconstraints.getValue();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool avoidredundant =
sketchgui->AvoidRedundant.getValue() && sketchgui->Autoconstraints.getValue();
if(avoidredundant)
removeRedundantHorizontalVertical(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()),sugConstr1,sugConstr2);
if (avoidredundant)
removeRedundantHorizontalVertical(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()),
sugConstr1,
sugConstr2);
// add auto constraints for the line segment start
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
createAutoConstraints(
sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr1.clear();
}
@@ -131,31 +148,32 @@ public:
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
EditCurve.clear();
drawEdit(EditCurve);
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.resize(2);
applyCursor();
/* It is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_Line");
@@ -167,8 +185,7 @@ protected:
std::vector<AutoConstraint> sugConstr1, sugConstr2;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerLine_H
#endif// SKETCHERGUI_DrawSketchHandlerLine_H
+271 -190
View File
@@ -23,42 +23,46 @@
#ifndef SKETCHERGUI_DrawSketchHandlerLineSet_H
#define SKETCHERGUI_DrawSketchHandlerLineSet_H
#include <boost/math/special_functions/fpclassify.hpp>
#include <Inventor/events/SoKeyboardEvent.h>
#include <boost/math/special_functions/fpclassify.hpp>
#include <Gui/Notifications.h>
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerLineSet: public DrawSketchHandler
{
public:
DrawSketchHandlerLineSet()
: Mode(STATUS_SEEK_First), SegmentMode(SEGMENT_MODE_Line)
, TransitionMode(TRANSITION_MODE_Free)
, SnapMode(SNAP_MODE_Free)
, suppressTransition(false)
, EditCurve(2)
, firstCurve(-1)
, previousCurve(-1)
, firstPosId(Sketcher::PointPos::none)
, previousPosId(Sketcher::PointPos::none)
, startAngle(0)
, endAngle(0)
, arcRadius(0)
, firstsegment(true) {}
: Mode(STATUS_SEEK_First)
, SegmentMode(SEGMENT_MODE_Line)
, TransitionMode(TRANSITION_MODE_Free)
, SnapMode(SNAP_MODE_Free)
, suppressTransition(false)
, EditCurve(2)
, firstCurve(-1)
, previousCurve(-1)
, firstPosId(Sketcher::PointPos::none)
, previousPosId(Sketcher::PointPos::none)
, startAngle(0)
, endAngle(0)
, arcRadius(0)
, firstsegment(true)
{}
virtual ~DrawSketchHandlerLineSet() = default;
/// mode table
enum SELECT_MODE {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum SELECT_MODE
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_Do,
STATUS_Close
};
@@ -86,7 +90,7 @@ public:
void registerPressedKey(bool pressed, int key) override
{
if (Mode != STATUS_SEEK_Second)
return; // SegmentMode can be changed only in STATUS_SEEK_Second mode
return;// SegmentMode can be changed only in STATUS_SEEK_Second mode
if (key == SoKeyboardEvent::M && pressed && previousCurve != -1) {
// loop through the following modes:
@@ -101,50 +105,51 @@ public:
Base::Vector2d onSketchPos;
if (SegmentMode == SEGMENT_MODE_Line)
onSketchPos = EditCurve[EditCurve.size()-1];
onSketchPos = EditCurve[EditCurve.size() - 1];
else
onSketchPos = EditCurve[29];
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(previousCurve);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(previousCurve);
if (SegmentMode == SEGMENT_MODE_Line) {
switch (TransitionMode) {
case TRANSITION_MODE_Free:
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { // 3rd mode
if (geom->getTypeId()
== Part::GeomArcOfCircle::getClassTypeId()) {// 3rd mode
SegmentMode = SEGMENT_MODE_Arc;
TransitionMode = TRANSITION_MODE_Tangent;
}
else // 1st mode
else// 1st mode
TransitionMode = TRANSITION_MODE_Perpendicular_L;
break;
case TRANSITION_MODE_Perpendicular_L: // 2nd mode
case TRANSITION_MODE_Perpendicular_L:// 2nd mode
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
TransitionMode = TRANSITION_MODE_Free;
else
TransitionMode = TRANSITION_MODE_Tangent;
break;
case TRANSITION_MODE_Tangent:
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) // 1st mode
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())// 1st mode
TransitionMode = TRANSITION_MODE_Perpendicular_L;
else { // 3rd mode
else {// 3rd mode
SegmentMode = SEGMENT_MODE_Arc;
TransitionMode = TRANSITION_MODE_Tangent;
}
break;
default: // unexpected mode
default:// unexpected mode
TransitionMode = TRANSITION_MODE_Free;
break;
}
}
else {
switch (TransitionMode) {
case TRANSITION_MODE_Tangent: // 4th mode
case TRANSITION_MODE_Tangent:// 4th mode
TransitionMode = TRANSITION_MODE_Perpendicular_L;
break;
case TRANSITION_MODE_Perpendicular_L: // 5th mode
case TRANSITION_MODE_Perpendicular_L:// 5th mode
TransitionMode = TRANSITION_MODE_Perpendicular_R;
break;
default: // 6th mode (Perpendicular_R) + unexpected mode
default:// 6th mode (Perpendicular_R) + unexpected mode
SegmentMode = SEGMENT_MODE_Line;
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
TransitionMode = TRANSITION_MODE_Tangent;
@@ -158,25 +163,25 @@ public:
EditCurve.resize(TransitionMode == TRANSITION_MODE_Free ? 2 : 3);
else
EditCurve.resize(32);
mouseMove(onSketchPos); // trigger an update of EditCurve
mouseMove(onSketchPos);// trigger an update of EditCurve
}
}
void mouseMove(Base::Vector2d onSketchPos) override
{
suppressTransition = false;
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second){
else if (Mode == STATUS_SEEK_Second) {
if (SegmentMode == SEGMENT_MODE_Line) {
EditCurve[EditCurve.size()-1] = onSketchPos;
EditCurve[EditCurve.size() - 1] = onSketchPos;
if (TransitionMode == TRANSITION_MODE_Tangent) {
Base::Vector2d Tangent(dirVec.x,dirVec.y);
Base::Vector2d Tangent(dirVec.x, dirVec.y);
EditCurve[1].ProjectToLine(EditCurve[2] - EditCurve[0], Tangent);
if (EditCurve[1] * Tangent < 0) {
EditCurve[1] = EditCurve[2];
@@ -185,9 +190,9 @@ public:
else
EditCurve[1] = EditCurve[0] + EditCurve[1];
}
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L ||
TransitionMode == TRANSITION_MODE_Perpendicular_R) {
Base::Vector2d Perpendicular(-dirVec.y,dirVec.x);
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L
|| TransitionMode == TRANSITION_MODE_Perpendicular_R) {
Base::Vector2d Perpendicular(-dirVec.y, dirVec.x);
EditCurve[1].ProjectToLine(EditCurve[2] - EditCurve[0], Perpendicular);
EditCurve[1] = EditCurve[0] + EditCurve[1];
}
@@ -195,7 +200,7 @@ public:
drawEdit(EditCurve);
float length = (EditCurve[1] - EditCurve[0]).Length();
float angle = (EditCurve[1] - EditCurve[0]).GetAngle(Base::Vector2d(1.f,0.f));
float angle = (EditCurve[1] - EditCurve[0]).GetAngle(Base::Vector2d(1.f, 0.f));
if (showCursorCoords()) {
SbString text;
@@ -214,61 +219,63 @@ public:
}
else if (SegmentMode == SEGMENT_MODE_Arc) {
if(QApplication::keyboardModifiers() == Qt::ControlModifier)
if (QApplication::keyboardModifiers() == Qt::ControlModifier)
SnapMode = SNAP_MODE_45Degree;
else
SnapMode = SNAP_MODE_Free;
Base::Vector2d Tangent;
if (TransitionMode == TRANSITION_MODE_Tangent)
Tangent = Base::Vector2d(dirVec.x,dirVec.y);
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L)
Tangent = Base::Vector2d(-dirVec.y,dirVec.x);
else if (TransitionMode == TRANSITION_MODE_Perpendicular_R)
Tangent = Base::Vector2d(dirVec.y,-dirVec.x);
if (TransitionMode == TRANSITION_MODE_Tangent)
Tangent = Base::Vector2d(dirVec.x, dirVec.y);
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L)
Tangent = Base::Vector2d(-dirVec.y, dirVec.x);
else if (TransitionMode == TRANSITION_MODE_Perpendicular_R)
Tangent = Base::Vector2d(dirVec.y, -dirVec.x);
double theta = Tangent.GetAngle(onSketchPos - EditCurve[0]);
arcRadius = (onSketchPos - EditCurve[0]).Length()/(2.0*sin(theta));
arcRadius = (onSketchPos - EditCurve[0]).Length() / (2.0 * sin(theta));
// At this point we need a unit normal vector pointing towards
// the center of the arc we are drawing. Derivation of the formula
// used here can be found at http://people.richland.edu/james/lecture/m116/matrices/area.html
// used here can be found at
// http://people.richland.edu/james/lecture/m116/matrices/area.html
double x1 = EditCurve[0].x;
double y1 = EditCurve[0].y;
double x2 = x1 + Tangent.x;
double y2 = y1 + Tangent.y;
double x3 = onSketchPos.x;
double y3 = onSketchPos.y;
if ((x2*y3-x3*y2)-(x1*y3-x3*y1)+(x1*y2-x2*y1) > 0)
if ((x2 * y3 - x3 * y2) - (x1 * y3 - x3 * y1) + (x1 * y2 - x2 * y1) > 0)
arcRadius *= -1;
if (boost::math::isnan(arcRadius) || boost::math::isinf(arcRadius))
arcRadius = 0.f;
CenterPoint = EditCurve[0] + Base::Vector2d(arcRadius * Tangent.y, -arcRadius * Tangent.x);
CenterPoint =
EditCurve[0] + Base::Vector2d(arcRadius * Tangent.y, -arcRadius * Tangent.x);
double rx = EditCurve[0].x - CenterPoint.x;
double ry = EditCurve[0].y - CenterPoint.y;
startAngle = atan2(ry,rx);
startAngle = atan2(ry, rx);
double rxe = onSketchPos.x - CenterPoint.x;
double rye = onSketchPos.y - CenterPoint.y;
double arcAngle = atan2(-rxe*ry + rye*rx, rxe*rx + rye*ry);
double arcAngle = atan2(-rxe * ry + rye * rx, rxe * rx + rye * ry);
if (boost::math::isnan(arcAngle) || boost::math::isinf(arcAngle))
arcAngle = 0.f;
if (arcRadius >= 0 && arcAngle > 0)
arcAngle -= 2*M_PI;
arcAngle -= 2 * M_PI;
if (arcRadius < 0 && arcAngle < 0)
arcAngle += 2*M_PI;
arcAngle += 2 * M_PI;
if (SnapMode == SNAP_MODE_45Degree)
arcAngle = round(arcAngle / (M_PI/4)) * M_PI/4;
arcAngle = round(arcAngle / (M_PI / 4)) * M_PI / 4;
endAngle = startAngle + arcAngle;
for (int i=1; i <= 29; i++) {
double angle = i*arcAngle/29.0;
for (int i = 1; i <= 29; i++) {
double angle = i * arcAngle / 29.0;
double dx = rx * cos(angle) - ry * sin(angle);
double dy = rx * sin(angle) + ry * cos(angle);
EditCurve[i] = Base::Vector2d(CenterPoint.x + dx, CenterPoint.y + dy);
@@ -287,7 +294,7 @@ public:
setPositionText(onSketchPos, text);
}
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
@@ -300,28 +307,31 @@ public:
{
if (Mode == STATUS_SEEK_First) {
EditCurve[0] = onSketchPos; // this may be overwritten if previousCurve is found
EditCurve[0] = onSketchPos;// this may be overwritten if previousCurve is found
virtualsugConstr1 = sugConstr1; // store original autoconstraints.
virtualsugConstr1 = sugConstr1;// store original autoconstraints.
// here we check if there is a preselected point and
// we set up a transition from the neighbouring segment.
// (peviousCurve, previousPosId, dirVec, TransitionMode)
for (unsigned int i=0; i < sugConstr1.size(); i++)
for (unsigned int i = 0; i < sugConstr1.size(); i++)
if (sugConstr1[i].Type == Sketcher::Coincident) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(sugConstr1[i].GeoId);
if ((geom->getTypeId() == Part::GeomLineSegment::getClassTypeId() ||
geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) &&
(sugConstr1[i].PosId == Sketcher::PointPos::start ||
sugConstr1[i].PosId == Sketcher::PointPos::end)) {
const Part::Geometry* geom =
sketchgui->getSketchObject()->getGeometry(sugConstr1[i].GeoId);
if ((geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId())
&& (sugConstr1[i].PosId == Sketcher::PointPos::start
|| sugConstr1[i].PosId == Sketcher::PointPos::end)) {
previousCurve = sugConstr1[i].GeoId;
previousPosId = sugConstr1[i].PosId;
updateTransitionData(previousCurve,previousPosId); // -> dirVec, EditCurve[0]
updateTransitionData(previousCurve,
previousPosId);// -> dirVec, EditCurve[0]
if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
TransitionMode = TRANSITION_MODE_Tangent;
SnapMode = SNAP_MODE_Free;
}
sugConstr1.erase(sugConstr1.begin()+i); // actually we should clear the vector completely
sugConstr1.erase(sugConstr1.begin()
+ i);// actually we should clear the vector completely
break;
}
}
@@ -344,32 +354,34 @@ public:
EditCurve.clear();
drawEdit(EditCurve);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
SegmentMode=SEGMENT_MODE_Line;
TransitionMode=TRANSITION_MODE_Free;
Mode = STATUS_SEEK_First;
SegmentMode = SEGMENT_MODE_Line;
TransitionMode = TRANSITION_MODE_Free;
SnapMode = SNAP_MODE_Free;
suppressTransition=false;
firstCurve=-1;
previousCurve=-1;
firstPosId=Sketcher::PointPos::none;
previousPosId=Sketcher::PointPos::none;
suppressTransition = false;
firstCurve = -1;
previousCurve = -1;
firstPosId = Sketcher::PointPos::none;
previousPosId = Sketcher::PointPos::none;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
return true;
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui->purgeHandler();// no code after this line, Handler get deleted in
// ViewProvider
return true;
}
}
@@ -379,13 +391,15 @@ public:
if (getPreselectPoint() != -1 && firstPosId != Sketcher::PointPos::none) {
int GeoId;
Sketcher::PointPos PosId;
sketchgui->getSketchObject()->getGeoVertexIndex(getPreselectPoint(),GeoId,PosId);
if (sketchgui->getSketchObject()->arePointsCoincident(GeoId,PosId,firstCurve,firstPosId))
sketchgui->getSketchObject()->getGeoVertexIndex(getPreselectPoint(), GeoId, PosId);
if (sketchgui->getSketchObject()->arePointsCoincident(
GeoId, PosId, firstCurve, firstPosId))
Mode = STATUS_Close;
}
else if (getPreselectCross() == 0 && firstPosId != Sketcher::PointPos::none) {
// close line started at root point
if (sketchgui->getSketchObject()->arePointsCoincident(-1,Sketcher::PointPos::start,firstCurve,firstPosId))
if (sketchgui->getSketchObject()->arePointsCoincident(
-1, Sketcher::PointPos::start, firstCurve, firstPosId))
Mode = STATUS_Close;
}
}
@@ -400,112 +414,156 @@ public:
// issue the geometry
try {
// open the transaction
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add line to sketch wire"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y,
geometryCreationMode==Construction?"True":"False");
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add line to sketch wire"));
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)),%s)",
EditCurve[0].x,
EditCurve[0].y,
EditCurve[1].x,
EditCurve[1].y,
geometryCreationMode == Construction ? "True" : "False");
}
catch (const Base::Exception& e) {
addedGeometry = false;
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add line"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add line"));
Gui::Command::abortCommand();
}
firstsegment=false;
firstsegment = false;
}
else if (SegmentMode == SEGMENT_MODE_Arc) { // We're dealing with an Arc
else if (SegmentMode == SEGMENT_MODE_Arc) {// We're dealing with an Arc
if (!boost::math::isnormal(arcRadius)) {
Mode = STATUS_SEEK_Second;
return true;
}
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add arc to sketch wire"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.ArcOfCircle"
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add arc to sketch wire"));
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addGeometry(Part.ArcOfCircle"
"(Part.Circle(App.Vector(%f,%f,0),App.Vector(0,0,1),%f),%f,%f),%s)",
CenterPoint.x, CenterPoint.y, std::abs(arcRadius),
std::min(startAngle,endAngle), std::max(startAngle,endAngle),
geometryCreationMode==Construction?"True":"False");
CenterPoint.x,
CenterPoint.y,
std::abs(arcRadius),
std::min(startAngle, endAngle),
std::max(startAngle, endAngle),
geometryCreationMode == Construction ? "True" : "False");
}
catch (const Base::Exception& e) {
addedGeometry = false;
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add arc"));
Gui::Command::abortCommand();
}
firstsegment=false;
firstsegment = false;
}
int lastCurve = getHighestCurveIndex();
// issue the constraint
if (addedGeometry && (previousPosId != Sketcher::PointPos::none)) {
Sketcher::PointPos lastStartPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ?
Sketcher::PointPos::end : Sketcher::PointPos::start;
Sketcher::PointPos lastEndPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ?
Sketcher::PointPos::start : Sketcher::PointPos::end;
Sketcher::PointPos lastStartPosId =
(SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle)
? Sketcher::PointPos::end
: Sketcher::PointPos::start;
Sketcher::PointPos lastEndPosId =
(SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle)
? Sketcher::PointPos::start
: Sketcher::PointPos::end;
// in case of a tangency constraint, the coincident constraint is redundant
std::string constrType = "Coincident";
if (!suppressTransition && previousCurve != -1) {
if (TransitionMode == TRANSITION_MODE_Tangent)
constrType = "Tangent";
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L ||
TransitionMode == TRANSITION_MODE_Perpendicular_R)
else if (TransitionMode == TRANSITION_MODE_Perpendicular_L
|| TransitionMode == TRANSITION_MODE_Perpendicular_R)
constrType = "Perpendicular";
}
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('%s',%i,%i,%i,%i)) ",
constrType.c_str(), previousCurve, static_cast<int>(previousPosId), lastCurve, static_cast<int>(lastStartPosId));
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addConstraint(Sketcher.Constraint('%s',%i,%i,%i,%i)) ",
constrType.c_str(),
previousCurve,
static_cast<int>(previousPosId),
lastCurve,
static_cast<int>(lastStartPosId));
if(SnapMode == SNAP_MODE_45Degree && Mode != STATUS_Close) {
// -360, -315, -270, -225, -180, -135, -90, -45, 0, 45, 90, 135, 180, 225, 270, 315, 360
// N/A, a, perp, a, par, a,perp, a,N/A, a,perp, a, par, a,perp, a, N/A
if (SnapMode == SNAP_MODE_45Degree && Mode != STATUS_Close) {
// -360, -315, -270, -225, -180, -135, -90, -45, 0, 45, 90, 135, 180, 225,
// 270, 315, 360
// N/A, a, perp, a, par, a,perp, a,N/A, a,perp, a, par, a,perp,
// a, N/A
// #3974: if in radians, the printf %f defaults to six decimals, which leads to loss of precision
double arcAngle = abs(round( (endAngle - startAngle) / (M_PI/4)) * 45); // in degrees
// #3974: if in radians, the printf %f defaults to six decimals, which leads to
// loss of precision
double arcAngle =
abs(round((endAngle - startAngle) / (M_PI / 4)) * 45);// in degrees
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Angle',%i,App.Units.Quantity('%f deg'))) ",
lastCurve, arcAngle);
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addConstraint(Sketcher.Constraint('Angle',%i,App.Units."
"Quantity('%f deg'))) ",
lastCurve,
arcAngle);
}
if (Mode == STATUS_Close) {
// close the loop by constrain to the first curve point
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) ",
lastCurve,static_cast<int>(lastEndPosId),firstCurve,static_cast<int>(firstPosId));
Gui::cmdAppObjectArgs(
sketchgui->getObject(),
"addConstraint(Sketcher.Constraint('Coincident',%i,%i,%i,%i)) ",
lastCurve,
static_cast<int>(lastEndPosId),
firstCurve,
static_cast<int>(firstPosId));
}
Gui::Command::commitCommand();
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool avoidredundant = sketchgui->AvoidRedundant.getValue() && sketchgui->Autoconstraints.getValue();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool avoidredundant =
sketchgui->AvoidRedundant.getValue() && sketchgui->Autoconstraints.getValue();
if (Mode == STATUS_Close) {
if(avoidredundant) {
if (SegmentMode == SEGMENT_MODE_Line) { // avoid redundant constraints.
if (avoidredundant) {
if (SegmentMode == SEGMENT_MODE_Line) {// avoid redundant constraints.
if (sugConstr1.size() > 0)
removeRedundantHorizontalVertical(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()),sugConstr1,sugConstr2);
removeRedundantHorizontalVertical(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()),
sugConstr1,
sugConstr2);
else
removeRedundantHorizontalVertical(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()),virtualsugConstr1,sugConstr2);
removeRedundantHorizontalVertical(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()),
virtualsugConstr1,
sugConstr2);
}
}
if (!sugConstr2.empty()) {
// exclude any coincidence constraints
std::vector<AutoConstraint> sugConstr;
for (unsigned int i=0; i < sugConstr2.size(); i++) {
for (unsigned int i = 0; i < sugConstr2.size(); i++) {
if (sugConstr2[i].Type != Sketcher::Coincident)
sugConstr.push_back(sugConstr2[i]);
}
createAutoConstraints(sugConstr, getHighestCurveIndex(), Sketcher::PointPos::end);
createAutoConstraints(
sugConstr, getHighestCurveIndex(), Sketcher::PointPos::end);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
unsetCursor();
@@ -513,71 +571,85 @@ public:
EditCurve.clear();
drawEdit(EditCurve);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
SegmentMode=SEGMENT_MODE_Line;
TransitionMode=TRANSITION_MODE_Free;
Mode = STATUS_SEEK_First;
SegmentMode = SEGMENT_MODE_Line;
TransitionMode = TRANSITION_MODE_Free;
SnapMode = SNAP_MODE_Free;
suppressTransition=false;
firstCurve=-1;
previousCurve=-1;
firstPosId=Sketcher::PointPos::none;
previousPosId=Sketcher::PointPos::none;
suppressTransition = false;
firstCurve = -1;
previousCurve = -1;
firstPosId = Sketcher::PointPos::none;
previousPosId = Sketcher::PointPos::none;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui->purgeHandler();// no code after this line, Handler get deleted in
// ViewProvider
}
}
else {
Gui::Command::commitCommand();
// Add auto constraints
if (!sugConstr1.empty()) { // this is relevant only to the very first point
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
if (!sugConstr1.empty()) {// this is relevant only to the very first point
createAutoConstraints(
sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr1.clear();
}
if(avoidredundant) {
if (SegmentMode == SEGMENT_MODE_Line) { // avoid redundant constraints.
if (avoidredundant) {
if (SegmentMode == SEGMENT_MODE_Line) {// avoid redundant constraints.
if (sugConstr1.size() > 0)
removeRedundantHorizontalVertical(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()),sugConstr1,sugConstr2);
removeRedundantHorizontalVertical(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()),
sugConstr1,
sugConstr2);
else
removeRedundantHorizontalVertical(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()),virtualsugConstr1,sugConstr2);
removeRedundantHorizontalVertical(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()),
virtualsugConstr1,
sugConstr2);
}
}
virtualsugConstr1 = sugConstr2; // these are the initial constraints for the next iteration.
virtualsugConstr1 =
sugConstr2;// these are the initial constraints for the next iteration.
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex(),
(SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ?
Sketcher::PointPos::start : Sketcher::PointPos::end);
createAutoConstraints(sugConstr2,
getHighestCurveIndex(),
(SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle)
? Sketcher::PointPos::start
: Sketcher::PointPos::end);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
// remember the vertex for the next rounds constraint..
previousCurve = getHighestCurveIndex();
previousPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle) ?
Sketcher::PointPos::start : Sketcher::PointPos::end; // cw arcs are rendered in reverse
previousPosId = (SegmentMode == SEGMENT_MODE_Arc && startAngle > endAngle)
? Sketcher::PointPos::start
: Sketcher::PointPos::end;// cw arcs are rendered in reverse
// setup for the next line segment
// calculate dirVec and EditCurve[0]
updateTransitionData(previousCurve,previousPosId);
updateTransitionData(previousCurve, previousPosId);
applyCursor();
Mode = STATUS_SEEK_Second;
@@ -593,19 +665,21 @@ public:
SegmentMode = SEGMENT_MODE_Line;
SnapMode = SNAP_MODE_Free;
EditCurve[1] = EditCurve[0];
mouseMove(onSketchPos); // trigger an update of EditCurve
mouseMove(onSketchPos);// trigger an update of EditCurve
}
}
return true;
}
void quit() override {
void quit() override
{
// We must see if we need to create a B-spline before cancelling everything
// and now just like any other Handler,
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (firstsegment) {
// user when right-clicking with no segment in really wants to exit
@@ -613,21 +687,21 @@ public:
}
else {
if(!continuousMode){
if (!continuousMode) {
DrawSketchHandler::quit();
}
else {
// This code disregards existing data and enables the continuous creation mode.
Mode=STATUS_SEEK_First;
SegmentMode=SEGMENT_MODE_Line;
TransitionMode=TRANSITION_MODE_Free;
Mode = STATUS_SEEK_First;
SegmentMode = SEGMENT_MODE_Line;
TransitionMode = TRANSITION_MODE_Free;
SnapMode = SNAP_MODE_Free;
suppressTransition=false;
firstCurve=-1;
previousCurve=-1;
firstPosId=Sketcher::PointPos::none;
previousPosId=Sketcher::PointPos::none;
firstsegment=true;
suppressTransition = false;
firstCurve = -1;
previousCurve = -1;
firstPosId = Sketcher::PointPos::none;
previousPosId = Sketcher::PointPos::none;
firstsegment = true;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(2);
@@ -637,7 +711,8 @@ public:
}
private:
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_Lineset");
}
@@ -653,7 +728,8 @@ protected:
int previousCurve;
Sketcher::PointPos firstPosId;
Sketcher::PointPos previousPosId;
// the latter stores those constraints that a first point would have been given in absence of the transition mechanism
// the latter stores those constraints that a first point would have been given in absence of
// the transition mechanism
std::vector<AutoConstraint> sugConstr1, sugConstr2, virtualsugConstr1;
Base::Vector2d CenterPoint;
@@ -662,31 +738,37 @@ protected:
bool firstsegment;
void updateTransitionData(int GeoId, Sketcher::PointPos PosId) {
void updateTransitionData(int GeoId, Sketcher::PointPos PosId)
{
// Use updated startPoint/endPoint as autoconstraints can modify the position
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment *lineSeg = static_cast<const Part::GeomLineSegment *>(geom);
const Part::GeomLineSegment* lineSeg = static_cast<const Part::GeomLineSegment*>(geom);
dirVec.Set(lineSeg->getEndPoint().x - lineSeg->getStartPoint().x,
lineSeg->getEndPoint().y - lineSeg->getStartPoint().y,
0.f);
if (PosId == Sketcher::PointPos::start) {
dirVec *= -1;
EditCurve[0] = Base::Vector2d(lineSeg->getStartPoint().x, lineSeg->getStartPoint().y);
EditCurve[0] =
Base::Vector2d(lineSeg->getStartPoint().x, lineSeg->getStartPoint().y);
}
else
EditCurve[0] = Base::Vector2d(lineSeg->getEndPoint().x, lineSeg->getEndPoint().y);
}
else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *arcSeg = static_cast<const Part::GeomArcOfCircle *>(geom);
const Part::GeomArcOfCircle* arcSeg = static_cast<const Part::GeomArcOfCircle*>(geom);
if (PosId == Sketcher::PointPos::start) {
EditCurve[0] = Base::Vector2d(arcSeg->getStartPoint(/*emulateCCW=*/true).x,arcSeg->getStartPoint(/*emulateCCW=*/true).y);
dirVec = Base::Vector3d(0.f,0.f,-1.0) % (arcSeg->getStartPoint(/*emulateCCW=*/true)-arcSeg->getCenter());
EditCurve[0] = Base::Vector2d(arcSeg->getStartPoint(/*emulateCCW=*/true).x,
arcSeg->getStartPoint(/*emulateCCW=*/true).y);
dirVec = Base::Vector3d(0.f, 0.f, -1.0)
% (arcSeg->getStartPoint(/*emulateCCW=*/true) - arcSeg->getCenter());
}
else {
EditCurve[0] = Base::Vector2d(arcSeg->getEndPoint(/*emulateCCW=*/true).x,arcSeg->getEndPoint(/*emulateCCW=*/true).y);
dirVec = Base::Vector3d(0.f,0.f,1.0) % (arcSeg->getEndPoint(/*emulateCCW=*/true)-arcSeg->getCenter());
EditCurve[0] = Base::Vector2d(arcSeg->getEndPoint(/*emulateCCW=*/true).x,
arcSeg->getEndPoint(/*emulateCCW=*/true).y);
dirVec = Base::Vector3d(0.f, 0.f, 1.0)
% (arcSeg->getEndPoint(/*emulateCCW=*/true) - arcSeg->getCenter());
}
}
dirVec.Normalize();
@@ -694,8 +776,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerLineSet_H
#endif// SKETCHERGUI_DrawSketchHandlerLineSet_H
+30 -22
View File
@@ -28,20 +28,24 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerPoint: public DrawSketchHandler
{
public:
DrawSketchHandlerPoint() : selectionDone(false) {}
virtual ~DrawSketchHandlerPoint() {}
DrawSketchHandlerPoint()
: selectionDone(false)
{}
virtual ~DrawSketchHandlerPoint()
{}
void mouseMove(Base::Vector2d onSketchPos) override
{
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr);
return;
}
@@ -58,21 +62,23 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (selectionDone){
if (selectionDone) {
unsetCursor();
resetPositionText();
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch point"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "addGeometry(Part.Point(App.Vector(%f,%f,0)))",
EditPoint.x,EditPoint.y);
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"addGeometry(Part.Point(App.Vector(%f,%f,0)))",
EditPoint.x,
EditPoint.y);
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add point"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add point"));
Gui::Command::abortCommand();
}
@@ -83,20 +89,23 @@ public:
sugConstr.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
applyCursor();
/* It is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -115,8 +124,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerPoint_H
#endif// SKETCHERGUI_DrawSketchHandlerPoint_H
+63 -52
View File
@@ -29,48 +29,50 @@
#include "SketcherRegularPolygonDialog.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerRegularPolygon: public DrawSketchHandler
{
public:
explicit DrawSketchHandlerRegularPolygon( size_t nof_corners ):
Corners( nof_corners ),
AngleOfSeparation( 2.0*M_PI/static_cast<double>(Corners) ),
cos_v( cos( AngleOfSeparation ) ),
sin_v( sin( AngleOfSeparation ) ),
Mode(STATUS_SEEK_First),
EditCurve(Corners+1)
{
}
virtual ~DrawSketchHandlerRegularPolygon(){}
explicit DrawSketchHandlerRegularPolygon(size_t nof_corners)
: Corners(nof_corners)
, AngleOfSeparation(2.0 * M_PI / static_cast<double>(Corners))
, cos_v(cos(AngleOfSeparation))
, sin_v(sin(AngleOfSeparation))
, Mode(STATUS_SEEK_First)
, EditCurve(Corners + 1)
{}
virtual ~DrawSketchHandlerRegularPolygon()
{}
/// mode table
enum SelectMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum SelectMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
EditCurve[0]= Base::Vector2d(onSketchPos.x, onSketchPos.y);
EditCurve[Corners]= Base::Vector2d(onSketchPos.x, onSketchPos.y);
else if (Mode == STATUS_SEEK_Second) {
EditCurve[0] = Base::Vector2d(onSketchPos.x, onSketchPos.y);
EditCurve[Corners] = Base::Vector2d(onSketchPos.x, onSketchPos.y);
Base::Vector2d dV = onSketchPos - StartPos;
double rx = dV.x;
double ry = dV.y;
for (int i=1; i < static_cast<int>(Corners); i++) {
for (int i = 1; i < static_cast<int>(Corners); i++) {
const double old_rx = rx;
rx = cos_v * rx - sin_v * ry;
ry = cos_v * ry + sin_v * old_rx;
@@ -79,18 +81,18 @@ public:
// Display radius for user
const float radius = dV.Length();
const float angle = ( 180.0 / M_PI ) * atan2( dV.y, dV.x );
const float angle = (180.0 / M_PI) * atan2(dV.y, dV.x);
if (showCursorCoords()) {
SbString text;
std::string radiusString = lengthToDisplayFormat(radius, 1);
std::string angleString = angleToDisplayFormat(angle, 1);
text.sprintf(" (R%s, %s)", radiusString.c_str(), angleString.c_str());
setPositionText(onSketchPos, text);
text.sprintf(" (R%s, %s)", radiusString.c_str(), angleString.c_str());
setPositionText(onSketchPos, text);
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
@@ -100,7 +102,7 @@ public:
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if (Mode == STATUS_SEEK_First) {
StartPos = onSketchPos;
Mode = STATUS_SEEK_Second;
}
@@ -113,63 +115,72 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_End){
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add hexagon"));
try {
Gui::Command::doCommand(Gui::Command::Doc,
"import ProfileLib.RegularPolygon\n"
"ProfileLib.RegularPolygon.makeRegularPolygon(%s,%i,App.Vector(%f,%f,0),App.Vector(%f,%f,0),%s)",
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),
Corners,
StartPos.x,StartPos.y,EditCurve[0].x,EditCurve[0].y,
geometryCreationMode==Construction?"True":"False");
"import ProfileLib.RegularPolygon\n"
"ProfileLib.RegularPolygon.makeRegularPolygon(%s,%i,App."
"Vector(%f,%f,0),App.Vector(%f,%f,0),%s)",
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),
Corners,
StartPos.x,
StartPos.y,
EditCurve[0].x,
EditCurve[0].y,
geometryCreationMode == Construction ? "True" : "False");
Gui::Command::commitCommand();
// add auto constraints at the center of the polygon
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::mid);
createAutoConstraints(
sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::mid);
sugConstr1.clear();
}
// add auto constraints to the last side of the polygon
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 1, Sketcher::PointPos::end);
createAutoConstraints(
sugConstr2, getHighestCurveIndex() - 1, Sketcher::PointPos::end);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add polygon"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add polygon"));
Gui::Command::abortCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if(continuousMode){
if (continuousMode) {
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(Corners+1);
EditCurve.resize(Corners + 1);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -180,6 +191,7 @@ private:
{
return QString::fromLatin1("Sketcher_Pointer_Regular_Polygon");
}
protected:
const size_t Corners;
const double AngleOfSeparation;
@@ -191,8 +203,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerPolygon_H
#endif// SKETCHERGUI_DrawSketchHandlerPolygon_H
+303 -175
View File
@@ -28,44 +28,49 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerBox: public DrawSketchHandler
{
public:
enum ConstructionMethod {
enum ConstructionMethod
{
Diagonal,
CenterAndCorner
};
explicit DrawSketchHandlerBox(ConstructionMethod constrMethod = Diagonal): Mode(STATUS_SEEK_First),
EditCurve(5),
constructionMethod(constrMethod){}
virtual ~DrawSketchHandlerBox(){}
explicit DrawSketchHandlerBox(ConstructionMethod constrMethod = Diagonal)
: Mode(STATUS_SEEK_First)
, EditCurve(5)
, constructionMethod(constrMethod)
{}
virtual ~DrawSketchHandlerBox()
{}
/// mode table
enum BoxMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum BoxMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
public:
void mouseMove(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First) {
if (Mode == STATUS_SEEK_First) {
setPositionText(onSketchPos);
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f,0.f))) {
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f))) {
renderSuggestConstraintsCursor(sugConstr1);
return;
}
}
else if (Mode==STATUS_SEEK_Second) {
if(constructionMethod == Diagonal) {
else if (Mode == STATUS_SEEK_Second) {
if (constructionMethod == Diagonal) {
float dx = onSketchPos.x - EditCurve[0].x;
float dy = onSketchPos.y - EditCurve[0].y;
if (showCursorCoords()) {
@@ -77,14 +82,13 @@ public:
}
EditCurve[2] = onSketchPos;
EditCurve[1] = Base::Vector2d(onSketchPos.x ,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[1] = Base::Vector2d(onSketchPos.x, EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x, onSketchPos.y);
}
else if (constructionMethod == CenterAndCorner) {
float dx = onSketchPos.x - center.x;
float dy = onSketchPos.y - center.y;
if (showCursorCoords()) {
if (showCursorCoords()) {
SbString text;
std::string dxString = lengthToDisplayFormat(dx, 1);
std::string dyString = lengthToDisplayFormat(dy, 1);
@@ -93,26 +97,25 @@ public:
}
EditCurve[0] = center - (onSketchPos - center);
EditCurve[1] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[1] = Base::Vector2d(EditCurve[0].x, onSketchPos.y);
EditCurve[2] = onSketchPos;
EditCurve[3] = Base::Vector2d(onSketchPos.x,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(onSketchPos.x, EditCurve[0].y);
EditCurve[4] = EditCurve[0];
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.0,0.0))) {
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.0, 0.0))) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
}
applyCursor();
}
bool pressButton(Base::Vector2d onSketchPos) override
{
if (Mode==STATUS_SEEK_First){
if(constructionMethod == Diagonal) {
if (Mode == STATUS_SEEK_First) {
if (constructionMethod == Diagonal) {
EditCurve[0] = onSketchPos;
EditCurve[4] = onSketchPos;
}
@@ -123,18 +126,18 @@ public:
Mode = STATUS_SEEK_Second;
}
else {
if(constructionMethod == Diagonal) {
if (constructionMethod == Diagonal) {
EditCurve[2] = onSketchPos;
EditCurve[1] = Base::Vector2d(onSketchPos.x ,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[1] = Base::Vector2d(onSketchPos.x, EditCurve[0].y);
EditCurve[3] = Base::Vector2d(EditCurve[0].x, onSketchPos.y);
drawEdit(EditCurve);
Mode = STATUS_End;
}
else if (constructionMethod == CenterAndCorner) {
EditCurve[0] = center - (onSketchPos - center);
EditCurve[1] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
EditCurve[1] = Base::Vector2d(EditCurve[0].x, onSketchPos.y);
EditCurve[2] = onSketchPos;
EditCurve[3] = Base::Vector2d(onSketchPos.x,EditCurve[0].y);
EditCurve[3] = Base::Vector2d(onSketchPos.x, EditCurve[0].y);
EditCurve[4] = EditCurve[0];
drawEdit(EditCurve);
Mode = STATUS_End;
@@ -146,20 +149,25 @@ public:
bool releaseButton(Base::Vector2d onSketchPos) override
{
Q_UNUSED(onSketchPos);
if (Mode==STATUS_End){
if (Mode == STATUS_End) {
unsetCursor();
resetPositionText();
int firstCurve = getHighestCurveIndex() + 1;
try {
if(constructionMethod == Diagonal) {
if (constructionMethod == Diagonal) {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add sketch box"));
Gui::Command::doCommand(Gui::Command::Doc,
Gui::Command::doCommand(
Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"%s.addGeometry(geoList,%s)\n"
"conList = []\n"
"conList.append(Sketcher.Constraint('Coincident',%i,2,%i,1))\n"
@@ -172,32 +180,56 @@ public:
"conList.append(Sketcher.Constraint('Vertical',%i))\n"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
EditCurve[3].x,EditCurve[3].y,EditCurve[0].x,EditCurve[0].y, // line 4
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode==Construction?"True":"False", // geometry as construction or not
firstCurve,firstCurve+1, // coincident1
firstCurve+1,firstCurve+2, // coincident2
firstCurve+2,firstCurve+3, // coincident3
firstCurve+3,firstCurve, // coincident4
firstCurve, // horizontal1
firstCurve+2, // horizontal2
firstCurve+1, // vertical1
firstCurve+3, // vertical2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
EditCurve[0].x,
EditCurve[0].y,
EditCurve[1].x,
EditCurve[1].y,// line 1
EditCurve[1].x,
EditCurve[1].y,
EditCurve[2].x,
EditCurve[2].y,// line 2
EditCurve[2].x,
EditCurve[2].y,
EditCurve[3].x,
EditCurve[3].y,// line 3
EditCurve[3].x,
EditCurve[3].y,
EditCurve[0].x,
EditCurve[0].y, // line 4
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),// the sketch
geometryCreationMode == Construction
? "True"
: "False",// geometry as construction or not
firstCurve,
firstCurve + 1,// coincident1
firstCurve + 1,
firstCurve + 2,// coincident2
firstCurve + 2,
firstCurve + 3,// coincident3
firstCurve + 3,
firstCurve, // coincident4
firstCurve, // horizontal1
firstCurve + 2, // horizontal2
firstCurve + 1, // vertical1
firstCurve + 3, // vertical2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str());// the sketch
Gui::Command::commitCommand();
Gui::Command::commitCommand();
}
else if (constructionMethod == CenterAndCorner) {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add centered sketch box"));
Gui::Command::doCommand(Gui::Command::Doc,
Gui::Command::openCommand(
QT_TRANSLATE_NOOP("Command", "Add centered sketch box"));
Gui::Command::doCommand(
Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.LineSegment(App.Vector(%f,%f,0),App.Vector(%f,%f,0)))"
"\n"
"geoList.append(Part.Point(App.Vector(%f,%f,0)))\n"
"%s.addGeometry(geoList,%s)\n"
"conList = []\n"
@@ -212,94 +244,119 @@ public:
"conList.append(Sketcher.Constraint('Symmetric',%i,2,%i,1,%i,1))\n"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
EditCurve[0].x,EditCurve[0].y,EditCurve[1].x,EditCurve[1].y, // line 1
EditCurve[1].x,EditCurve[1].y,EditCurve[2].x,EditCurve[2].y, // line 2
EditCurve[2].x,EditCurve[2].y,EditCurve[3].x,EditCurve[3].y, // line 3
EditCurve[3].x,EditCurve[3].y,EditCurve[0].x,EditCurve[0].y, // line 4
center.x,center.y, // center point
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode==Construction?"True":"False", // geometry as construction or not
firstCurve,firstCurve+1, // coincident1
firstCurve+1,firstCurve+2, // coincident2
firstCurve+2,firstCurve+3, // coincident3
firstCurve+3,firstCurve, // coincident4
firstCurve+1, // horizontal1
firstCurve+3, // horizontal2
firstCurve, // vertical1
firstCurve+2, // vertical2
firstCurve+1, firstCurve, firstCurve + 4, // Symmetric
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
EditCurve[0].x,
EditCurve[0].y,
EditCurve[1].x,
EditCurve[1].y,// line 1
EditCurve[1].x,
EditCurve[1].y,
EditCurve[2].x,
EditCurve[2].y,// line 2
EditCurve[2].x,
EditCurve[2].y,
EditCurve[3].x,
EditCurve[3].y,// line 3
EditCurve[3].x,
EditCurve[3].y,
EditCurve[0].x,
EditCurve[0].y,// line 4
center.x,
center.y, // center point
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),// the sketch
geometryCreationMode == Construction
? "True"
: "False",// geometry as construction or not
firstCurve,
firstCurve + 1,// coincident1
firstCurve + 1,
firstCurve + 2,// coincident2
firstCurve + 2,
firstCurve + 3,// coincident3
firstCurve + 3,
firstCurve, // coincident4
firstCurve + 1,// horizontal1
firstCurve + 3,// horizontal2
firstCurve, // vertical1
firstCurve + 2,// vertical2
firstCurve + 1,
firstCurve,
firstCurve + 4, // Symmetric
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str());// the sketch
Gui::Command::commitCommand();
Gui::Command::commitCommand();
}
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add box"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add box"));
Gui::Command::abortCommand();
}
if(constructionMethod == Diagonal) {
if (constructionMethod == Diagonal) {
// add auto constraints at the start of the first side
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3 , Sketcher::PointPos::start);
createAutoConstraints(
sugConstr1, getHighestCurveIndex() - 3, Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the end of the second side
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::PointPos::end);
createAutoConstraints(
sugConstr2, getHighestCurveIndex() - 2, Sketcher::PointPos::end);
sugConstr2.clear();
}
}
else if (constructionMethod == CenterAndCorner) {
// add auto constraints at the start of the first side
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
createAutoConstraints(
sugConstr1, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the end of the second side
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 3, Sketcher::PointPos::end);
createAutoConstraints(
sugConstr2, getHighestCurveIndex() - 3, Sketcher::PointPos::end);
sugConstr2.clear();
}
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
if(continuousMode){
// This code enables the continuous creation mode.
Mode=STATUS_SEEK_First;
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
// This code enables the continuous creation mode.
Mode = STATUS_SEEK_First;
EditCurve.clear();
drawEdit(EditCurve);
EditCurve.resize(5);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else{
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else {
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Create_Box");
}
protected:
BoxMode Mode;
std::vector<Base::Vector2d> EditCurve;
@@ -308,20 +365,25 @@ protected:
Base::Vector2d center;
};
class DrawSketchHandlerOblong : public DrawSketchHandler
class DrawSketchHandlerOblong: public DrawSketchHandler
{
public:
DrawSketchHandlerOblong()
: Mode(STATUS_SEEK_First)
, lengthX(0), lengthY(0), radius(0), signX(1), signY(1)
, lengthX(0)
, lengthY(0)
, radius(0)
, signX(1)
, signY(1)
, EditCurve(37)
{
}
virtual ~DrawSketchHandlerOblong() {}
{}
virtual ~DrawSketchHandlerOblong()
{}
/// mode table
enum BoxMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum BoxMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
@@ -339,11 +401,13 @@ public:
float distanceX = onSketchPos.x - StartPos.x;
float distanceY = onSketchPos.y - StartPos.y;
lengthX = distanceX; lengthY = distanceY;
lengthX = distanceX;
lengthY = distanceY;
signX = Base::sgn(distanceX);
signY = Base::sgn(distanceY);
if (fabs(distanceX) > fabs(distanceY)) {
radius = fabs(distanceY) / 4; // we use a fourth of the smaller distance as default radius
radius =
fabs(distanceY) / 4;// we use a fourth of the smaller distance as default radius
}
else {
radius = fabs(distanceX) / 4;
@@ -358,40 +422,56 @@ public:
double y_i = -radius * cos(angle);
// we are drawing clockwise starting with the arc that is besides StartPos
if (signX == signY) {
EditCurve[i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + signY * (radius + y_i));
EditCurve[9 + i] = Base::Vector2d(StartPos.x + signY * (radius + y_i), StartPos.y + lengthY - signX * (radius + x_i));
EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i));
EditCurve[27 + i] = Base::Vector2d(StartPos.x + lengthX - signY * (radius + y_i), StartPos.y + signX * (radius + x_i));
EditCurve[i] = Base::Vector2d(StartPos.x + signX * (radius + x_i),
StartPos.y + signY * (radius + y_i));
EditCurve[9 + i] =
Base::Vector2d(StartPos.x + signY * (radius + y_i),
StartPos.y + lengthY - signX * (radius + x_i));
EditCurve[18 + i] =
Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i),
StartPos.y + lengthY - signY * (radius + y_i));
EditCurve[27 + i] =
Base::Vector2d(StartPos.x + lengthX - signY * (radius + y_i),
StartPos.y + signX * (radius + x_i));
}
else {
EditCurve[i] = Base::Vector2d(StartPos.x - signY * (radius + y_i), StartPos.y - signX * (radius + x_i));
EditCurve[9 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i), StartPos.y + signY * (radius + y_i));
EditCurve[18 + i] = Base::Vector2d(StartPos.x + lengthX + signY * (radius + y_i), StartPos.y + lengthY + signX * (radius + x_i));
EditCurve[27 + i] = Base::Vector2d(StartPos.x + signX * (radius + x_i), StartPos.y + lengthY - signY * (radius + y_i));
EditCurve[i] = Base::Vector2d(StartPos.x - signY * (radius + y_i),
StartPos.y - signX * (radius + x_i));
EditCurve[9 + i] = Base::Vector2d(StartPos.x + lengthX - signX * (radius + x_i),
StartPos.y + signY * (radius + y_i));
EditCurve[18 + i] =
Base::Vector2d(StartPos.x + lengthX + signY * (radius + y_i),
StartPos.y + lengthY + signX * (radius + x_i));
EditCurve[27 + i] =
Base::Vector2d(StartPos.x + signX * (radius + x_i),
StartPos.y + lengthY - signY * (radius + y_i));
}
}
// draw the lines
if (signX == signY) {
EditCurve[8] = Base::Vector2d(StartPos.x, StartPos.y + (signY * radius));
EditCurve[17] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y + lengthY);
EditCurve[26] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + lengthY - (signY * radius));
EditCurve[26] =
Base::Vector2d(StartPos.x + lengthX, StartPos.y + lengthY - (signY * radius));
EditCurve[35] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y);
}
else {
EditCurve[8] = Base::Vector2d(StartPos.x + (signX * radius), StartPos.y);
EditCurve[17] = Base::Vector2d(StartPos.x + lengthX, StartPos.y + (signY * radius));
EditCurve[26] = Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY);
EditCurve[26] =
Base::Vector2d(StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY);
EditCurve[35] = Base::Vector2d(StartPos.x, StartPos.y + lengthY - (signY * radius));
}
// close the curve
EditCurve[36] = EditCurve[0];
if (showCursorCoords()) {
if (showCursorCoords()) {
SbString text;
std::string radiusString = lengthToDisplayFormat(radius, 1);
std::string xString = lengthToDisplayFormat(lengthX, 1);
std::string yString = lengthToDisplayFormat(lengthY, 1);
text.sprintf(" (R%s X%s Y%s)", radiusString.c_str(), xString.c_str(), yString.c_str());
text.sprintf(
" (R%s X%s Y%s)", radiusString.c_str(), xString.c_str(), yString.c_str());
setPositionText(onSketchPos, text);
}
@@ -444,17 +524,27 @@ public:
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add rounded rectangle"));
Gui::Command::doCommand(Gui::Command::Doc,
// syntax for arcs: Part.ArcOfCircle(Part.Circle(center, axis, radius), startangle, endangle)
Gui::Command::doCommand(
Gui::Command::Doc,
// syntax for arcs: Part.ArcOfCircle(Part.Circle(center, axis, radius),
// startangle, endangle)
"geoList = []\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"%s.addGeometry(geoList, %s)\n"
"conList = []\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 1, %i, 1))\n"
@@ -474,47 +564,80 @@ public:
"conList.append(Sketcher.Constraint('Equal', %i, %i))\n"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x + (signX * radius), StartPos.y + (signY * radius), // center of the arc 1
StartPos.x + (signX * radius),
StartPos.y + (signY * radius),// center of the arc 1
radius,
start, end, // start and end angle of arc1
EditCurve[8].x, EditCurve[8].y, EditCurve[9].x, EditCurve[9].y, // line 1
signX == signY ? StartPos.x + (signX * radius) : StartPos.x + lengthX - (signX * radius), // center of the arc 2
signX == signY ? StartPos.y + lengthY - (signY * radius) : StartPos.y + (signY * radius),
start,
end,// start and end angle of arc1
EditCurve[8].x,
EditCurve[8].y,
EditCurve[9].x,
EditCurve[9].y,// line 1
signX == signY ? StartPos.x + (signX * radius)
: StartPos.x + lengthX - (signX * radius),// center of the arc 2
signX == signY ? StartPos.y + lengthY - (signY * radius)
: StartPos.y + (signY * radius),
radius,
// start and end angle of arc 2
// the logic is that end is start + M_PI / 2 and start is the previous end - M_PI
// the logic is that end is start + M_PI / 2 and start is the previous end -
// M_PI
end - M_PI,
end - 0.5 * M_PI,
EditCurve[17].x, EditCurve[17].y, EditCurve[18].x, EditCurve[18].y, // line 2
StartPos.x + lengthX - (signX * radius), StartPos.y + lengthY - (signY * radius), // center of the arc 3
EditCurve[17].x,
EditCurve[17].y,
EditCurve[18].x,
EditCurve[18].y,// line 2
StartPos.x + lengthX - (signX * radius),
StartPos.y + lengthY - (signY * radius),// center of the arc 3
radius,
end - 1.5 * M_PI,
end - M_PI,
EditCurve[26].x, EditCurve[26].y, EditCurve[27].x, EditCurve[27].y, // line 3
signX == signY ? StartPos.x + lengthX - (signX * radius) : StartPos.x + (signX * radius), // center of the arc 4
signX == signY ? StartPos.y + (signY * radius) : StartPos.y + lengthY - (signY * radius),
EditCurve[26].x,
EditCurve[26].y,
EditCurve[27].x,
EditCurve[27].y,// line 3
signX == signY ? StartPos.x + lengthX - (signX * radius)
: StartPos.x + (signX * radius),// center of the arc 4
signX == signY ? StartPos.y + (signY * radius)
: StartPos.y + lengthY - (signY * radius),
radius,
end - 2 * M_PI,
end - 1.5 * M_PI,
EditCurve[35].x, EditCurve[35].y, EditCurve[36].x, EditCurve[36].y, // line 4
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode == Construction ? "True" : "False", // geometry as construction or not
firstCurve, firstCurve + 1, // tangent 1
firstCurve + 1, firstCurve + 2, // tangent 2
firstCurve + 2, firstCurve + 3, // tangent 3
firstCurve + 3, firstCurve + 4, // tangent 4
firstCurve + 4, firstCurve + 5, // tangent 5
firstCurve + 5, firstCurve + 6, // tangent 6
firstCurve + 6, firstCurve + 7, // tangent 7
firstCurve + 7, firstCurve, // tangent 8
signX == signY ? firstCurve + 3 : firstCurve + 1, // horizontal constraint
signX == signY ? firstCurve + 7 : firstCurve + 5, // horizontal constraint
signX == signY ? firstCurve + 1 : firstCurve + 3, // vertical constraint
signX == signY ? firstCurve + 5 : firstCurve + 7, // vertical constraint
firstCurve, firstCurve + 2, // equal 1
firstCurve + 2, firstCurve + 4, // equal 2
firstCurve + 4, firstCurve + 6, // equal 3
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
EditCurve[35].x,
EditCurve[35].y,
EditCurve[36].x,
EditCurve[36].y, // line 4
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),// the sketch
geometryCreationMode == Construction
? "True"
: "False",// geometry as construction or not
firstCurve,
firstCurve + 1,// tangent 1
firstCurve + 1,
firstCurve + 2,// tangent 2
firstCurve + 2,
firstCurve + 3,// tangent 3
firstCurve + 3,
firstCurve + 4,// tangent 4
firstCurve + 4,
firstCurve + 5,// tangent 5
firstCurve + 5,
firstCurve + 6,// tangent 6
firstCurve + 6,
firstCurve + 7,// tangent 7
firstCurve + 7,
firstCurve, // tangent 8
signX == signY ? firstCurve + 3 : firstCurve + 1,// horizontal constraint
signX == signY ? firstCurve + 7 : firstCurve + 5,// horizontal constraint
signX == signY ? firstCurve + 1 : firstCurve + 3,// vertical constraint
signX == signY ? firstCurve + 5 : firstCurve + 7,// vertical constraint
firstCurve,
firstCurve + 2,// equal 1
firstCurve + 2,
firstCurve + 4,// equal 2
firstCurve + 4,
firstCurve + 6, // equal 3
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str());// the sketch
// not all users want these extra points, some power users find them unnecessary
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
@@ -555,28 +678,33 @@ public:
// add auto constraints at the StartPos auxiliary point
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 1, Sketcher::PointPos::start);
createAutoConstraints(
sugConstr1, getHighestCurveIndex() - 1, Sketcher::PointPos::start);
sugConstr1.clear();
}
// add auto constraints at the EndPos auxiliary point
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex(), Sketcher::PointPos::start);
createAutoConstraints(
sugConstr2, getHighestCurveIndex(), Sketcher::PointPos::start);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add rounded rectangle"));
Gui::NotifyError(
sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add rounded rectangle"));
Gui::Command::abortCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
@@ -587,12 +715,13 @@ public:
EditCurve.resize(37);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else {
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
}
return true;
@@ -614,8 +743,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerRectangle_H
#endif// SKETCHERGUI_DrawSketchHandlerRectangle_H
+102 -58
View File
@@ -28,26 +28,30 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class DrawSketchHandlerSlot : public DrawSketchHandler
class DrawSketchHandlerSlot: public DrawSketchHandler
{
public:
DrawSketchHandlerSlot()
: Mode(STATUS_SEEK_First)
, SnapMode(SNAP_MODE_Free)
, SnapDir(SNAP_DIR_Horz)
, dx(0), dy(0), r(0)
, dx(0)
, dy(0)
, r(0)
, EditCurve(35)
{
}
virtual ~DrawSketchHandlerSlot() {}
{}
virtual ~DrawSketchHandlerSlot()
{}
/// mode table
enum BoxMode {
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
enum BoxMode
{
STATUS_SEEK_First, /**< enum value ----. */
STATUS_SEEK_Second, /**< enum value ----. */
STATUS_End
};
@@ -77,7 +81,7 @@ public:
dx = onSketchPos.x - StartPos.x;
dy = onSketchPos.y - StartPos.y;
if(QApplication::keyboardModifiers() == Qt::ControlModifier)
if (QApplication::keyboardModifiers() == Qt::ControlModifier)
SnapMode = SNAP_MODE_Straight;
else
SnapMode = SNAP_MODE_Free;
@@ -88,24 +92,28 @@ public:
r = fabs(dx) / 4;
rev = Base::sgn(dx);
SnapDir = SNAP_DIR_Horz;
if (SnapMode == SNAP_MODE_Straight) dy = 0;
if (SnapMode == SNAP_MODE_Straight)
dy = 0;
}
else {
r = fabs(dy) / 4;
a = 8;
rev = Base::sgn(dy);
SnapDir = SNAP_DIR_Vert;
if (SnapMode == SNAP_MODE_Straight) dx = 0;
if (SnapMode == SNAP_MODE_Straight)
dx = 0;
}
// draw the arcs with each 16 segments
for (int i = 0; i < 17; i++) {
// first get the position at the arc
// if a is 0, the end points of the arc are at the y-axis, if it is 8, they are on the x-axis
// if a is 0, the end points of the arc are at the y-axis, if it is 8, they are on
// the x-axis
double angle = (i + a) * M_PI / 16.0;
double rx = -r * rev * sin(angle);
double ry = r * rev * cos(angle);
// now apply the rotation matrix according to the angle between StartPos and onSketchPos
// now apply the rotation matrix according to the angle between StartPos and
// onSketchPos
if (!(dx == 0 || dy == 0)) {
double rotAngle = atan(dy / dx);
if (a > 0)
@@ -120,7 +128,7 @@ public:
}
EditCurve[34] = EditCurve[0];
if (showCursorCoords()) {
if (showCursorCoords()) {
SbString text;
std::string rString = lengthToDisplayFormat(r, 1);
std::string sqrtString = lengthToDisplayFormat(sqrt(dx * dx + dy * dy), 1);
@@ -129,7 +137,10 @@ public:
}
drawEdit(EditCurve);
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(dx, dy), AutoConstraint::VERTEX_NO_TANGENCY)) {
if (seekAutoConstraint(sugConstr2,
onSketchPos,
Base::Vector2d(dx, dy),
AutoConstraint::VERTEX_NO_TANGENCY)) {
renderSuggestConstraintsCursor(sugConstr2);
return;
}
@@ -184,9 +195,11 @@ public:
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add slot"));
AutoConstraint lastCons = {Sketcher::None, Sketcher::GeoEnum::GeoUndef, Sketcher::PointPos::none};
AutoConstraint lastCons = {
Sketcher::None, Sketcher::GeoEnum::GeoUndef, Sketcher::PointPos::none};
if (!sugConstr2.empty()) lastCons = sugConstr2.back();
if (!sugConstr2.empty())
lastCons = sugConstr2.back();
ostringstream snapCon = ostringstream("");
if (SnapMode == SNAP_MODE_Straight) {
@@ -199,22 +212,31 @@ public:
}
snapCon << "'," << firstCurve + 2 << "))\n";
// If horizontal/vertical already applied because of snap, do not duplicate with Autocontraint
if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical)
// If horizontal/vertical already applied because of snap, do not duplicate with
// Autocontraint
if (lastCons.Type == Sketcher::Horizontal
|| lastCons.Type == Sketcher::Vertical)
sugConstr2.pop_back();
}
else {
// If horizontal/vertical Autoconstraint suggested, applied it on first line (rather than last arc)
if (lastCons.Type == Sketcher::Horizontal || lastCons.Type == Sketcher::Vertical)
// If horizontal/vertical Autoconstraint suggested, applied it on first line
// (rather than last arc)
if (lastCons.Type == Sketcher::Horizontal
|| lastCons.Type == Sketcher::Vertical)
sugConstr2.back().GeoId = firstCurve + 2;
}
Gui::Command::doCommand(Gui::Command::Doc,
Gui::Command::doCommand(
Gui::Command::Doc,
"geoList = []\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f ,0), App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, 0)))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f, 0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.ArcOfCircle(Part.Circle(App.Vector(%f, %f ,0), "
"App.Vector(0, 0, 1), %f), %f, %f))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"geoList.append(Part.LineSegment(App.Vector(%f, %f, 0), App.Vector(%f, %f, "
"0)))\n"
"%s.addGeometry(geoList, %s)\n"
"conList = []\n"
"conList.append(Sketcher.Constraint('Tangent', %i, 2, %i, 1))\n"
@@ -225,50 +247,71 @@ public:
"%s"
"%s.addConstraint(conList)\n"
"del geoList, conList\n",
StartPos.x, StartPos.y, // center of the arc1
r, // radius arc1
start, end, // start and end angle of arc1
StartPos.x + dx, StartPos.y + dy, // center of the arc2
r, // radius arc2
end, end + M_PI, // start and end angle of arc2
EditCurve[16].x, EditCurve[16].y, EditCurve[17].x, EditCurve[17].y, // line1
EditCurve[33].x, EditCurve[33].y, EditCurve[34].x, EditCurve[34].y, // line2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(), // the sketch
geometryCreationMode == Construction ? "True" : "False", // geometry as construction or not
firstCurve, firstCurve + 2, // tangent1
firstCurve + 2, firstCurve + 1, // tangent2
firstCurve + 1, firstCurve + 3, // tangent3
firstCurve + 3, firstCurve, // tangent4
firstCurve, firstCurve + 1, // equal constraint
snapCon.str().c_str(), // horizontal/vertical constraint if snapping
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str()); // the sketch
StartPos.x,
StartPos.y,// center of the arc1
r, // radius arc1
start,
end,// start and end angle of arc1
StartPos.x + dx,
StartPos.y + dy,// center of the arc2
r, // radius arc2
end,
end + M_PI,// start and end angle of arc2
EditCurve[16].x,
EditCurve[16].y,
EditCurve[17].x,
EditCurve[17].y,// line1
EditCurve[33].x,
EditCurve[33].y,
EditCurve[34].x,
EditCurve[34].y, // line2
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str(),// the sketch
geometryCreationMode == Construction
? "True"
: "False",// geometry as construction or not
firstCurve,
firstCurve + 2,// tangent1
firstCurve + 2,
firstCurve + 1,// tangent2
firstCurve + 1,
firstCurve + 3,// tangent3
firstCurve + 3,
firstCurve,// tangent4
firstCurve,
firstCurve + 1, // equal constraint
snapCon.str().c_str(),// horizontal/vertical constraint if snapping
Gui::Command::getObjectCmd(sketchgui->getObject()).c_str());// the sketch
Gui::Command::commitCommand();
// add auto constraints at the center of the first arc
if (!sugConstr1.empty()) {
createAutoConstraints(sugConstr1, getHighestCurveIndex() - 3, Sketcher::PointPos::mid);
createAutoConstraints(
sugConstr1, getHighestCurveIndex() - 3, Sketcher::PointPos::mid);
sugConstr1.clear();
}
// add auto constraints at the center of the second arc
if (!sugConstr2.empty()) {
createAutoConstraints(sugConstr2, getHighestCurveIndex() - 2, Sketcher::PointPos::mid);
createAutoConstraints(
sugConstr2, getHighestCurveIndex() - 2, Sketcher::PointPos::mid);
sugConstr2.clear();
}
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
tryAutoRecomputeIfNotSolve(
static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add slot"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add slot"));
Gui::Command::abortCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool continuousMode = hGrp->GetBool("ContinuousCreationMode", true);
if (continuousMode) {
@@ -279,17 +322,19 @@ public:
EditCurve.resize(35);
applyCursor();
/* this is ok not to call to purgeHandler
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
* in continuous creation mode because the
* handler is destroyed by the quit() method on pressing the
* right button of the mouse */
}
else {
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
}
SnapMode = SNAP_MODE_Straight;
}
return true;
}
private:
QString getCrosshairCursorSVGName() const override
{
@@ -307,8 +352,7 @@ protected:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerSlot_H
#endif// SKETCHERGUI_DrawSketchHandlerSlot_H
@@ -28,30 +28,33 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class SplittingSelection : public Gui::SelectionFilterGate
class SplittingSelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit SplittingSelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer()), object(obj)
: Gui::SelectionFilterGate(nullPointer())
, object(obj)
{}
bool allow(App::Document * /*pDoc*/, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName)
{
if (pObj != this->object)
return false;
if (!sSubName || sSubName[0] == '\0')
return false;
std::string element(sSubName);
if (element.substr(0,4) == "Edge") {
int GeoId = std::atoi(element.substr(4,4000).c_str()) - 1;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
if (element.substr(0, 4) == "Edge") {
int GeoId = std::atoi(element.substr(4, 4000).c_str()) - 1;
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry* geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomEllipse::getClassTypeId()
@@ -60,16 +63,16 @@ public:
return true;
}
}
else if (element.substr(0,6) == "Vertex") {
int VertId = std::atoi(element.substr(6,4000).c_str()) - 1;
else if (element.substr(0, 6) == "Vertex") {
int VertId = std::atoi(element.substr(6, 4000).c_str()) - 1;
int GeoId = Sketcher::GeoEnum::GeoUndef;
Sketcher::PointPos PosId = Sketcher::PointPos::none;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
Sketch->getGeoVertexIndex(VertId, GeoId, PosId);
if (isBsplineKnot(Sketch, GeoId))
return true;
}
return false;
return false;
}
};
@@ -100,7 +103,7 @@ public:
int curveGeoId = getPreselectCurve();
if (curveGeoId >= 0) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(curveGeoId);
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(curveGeoId);
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomEllipse::getClassTypeId()
@@ -113,16 +116,15 @@ public:
// No curve of interest is pre-selected. Try pre-selected point.
int pointGeoId = getPreselectPoint();
if (pointGeoId >=0) {
if (pointGeoId >= 0) {
// TODO: This has to be a knot. Find the spline.
const auto& constraints = getSketchObject()->Constraints.getValues();
const auto& conIt = std::find_if(
constraints.begin(), constraints.end(),
[pointGeoId](auto constr) {
return (constr->Type == Sketcher::InternalAlignment &&
constr->AlignmentType == Sketcher::BSplineKnotPoint &&
constr->First == pointGeoId);
const auto& conIt =
std::find_if(constraints.begin(), constraints.end(), [pointGeoId](auto constr) {
return (constr->Type == Sketcher::InternalAlignment
&& constr->AlignmentType == Sketcher::BSplineKnotPoint
&& constr->First == pointGeoId);
});
if (conIt != constraints.end())
@@ -133,15 +135,18 @@ public:
if (GeoId >= 0) {
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Split edge"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "split(%d,App.Vector(%f,%f,0))",
GeoId, onSketchPos.x, onSketchPos.y);
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"split(%d,App.Vector(%f,%f,0))",
GeoId,
onSketchPos.x,
onSketchPos.y);
Gui::Command::commitCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add edge"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to add edge"));
Gui::Command::abortCommand();
}
@@ -161,13 +166,13 @@ private:
Gui::Selection().addSelectionGate(new SplittingSelection(sketchgui->getObject()));
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Splitting");
}
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerSplitting_H
#endif// SKETCHERGUI_DrawSketchHandlerSplitting_H
@@ -28,40 +28,42 @@
#include "GeometryCreationMode.h"
namespace SketcherGui {
namespace SketcherGui
{
extern GeometryCreationMode geometryCreationMode; // defined in CommandCreateGeo.cpp
extern GeometryCreationMode geometryCreationMode;// defined in CommandCreateGeo.cpp
class TrimmingSelection : public Gui::SelectionFilterGate
class TrimmingSelection: public Gui::SelectionFilterGate
{
App::DocumentObject* object;
public:
explicit TrimmingSelection(App::DocumentObject* obj)
: Gui::SelectionFilterGate(nullPointer()), object(obj)
: Gui::SelectionFilterGate(nullPointer())
, object(obj)
{}
bool allow(App::Document * /*pDoc*/, App::DocumentObject *pObj, const char *sSubName)
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName)
{
if (pObj != this->object)
return false;
if (!sSubName || sSubName[0] == '\0')
return false;
std::string element(sSubName);
if (element.substr(0,4) == "Edge") {
int GeoId = std::atoi(element.substr(4,4000).c_str()) - 1;
Sketcher::SketchObject *Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry *geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomTrimmedCurve::getClassTypeId()) ||
geom->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geom->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()
) {
if (element.substr(0, 4) == "Edge") {
int GeoId = std::atoi(element.substr(4, 4000).c_str()) - 1;
Sketcher::SketchObject* Sketch = static_cast<Sketcher::SketchObject*>(object);
const Part::Geometry* geom = Sketch->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomTrimmedCurve::getClassTypeId())
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomEllipse::getClassTypeId()
|| geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
// We do not trim internal geometry of complex geometries
if( Sketcher::GeometryFacade::isInternalType(geom, Sketcher::InternalType::None))
if (Sketcher::GeometryFacade::isInternalType(geom, Sketcher::InternalType::None))
return true;
}
}
return false;
return false;
}
};
@@ -81,30 +83,34 @@ public:
int GeoId = getPreselectCurve();
if (GeoId > -1) {
auto sk = static_cast<Sketcher::SketchObject *>(sketchgui->getObject());
auto sk = static_cast<Sketcher::SketchObject*>(sketchgui->getObject());
int GeoId1, GeoId2;
Base::Vector3d intersect1, intersect2;
if(sk->seekTrimPoints(GeoId, Base::Vector3d(onSketchPos.x,onSketchPos.y,0),
GeoId1, intersect1,
GeoId2, intersect2)) {
if (sk->seekTrimPoints(GeoId,
Base::Vector3d(onSketchPos.x, onSketchPos.y, 0),
GeoId1,
intersect1,
GeoId2,
intersect2)) {
EditMarkers.resize(0);
if(GeoId1 != Sketcher::GeoEnum::GeoUndef)
if (GeoId1 != Sketcher::GeoEnum::GeoUndef)
EditMarkers.emplace_back(intersect1.x, intersect1.y);
else {
auto start = sk->getPoint(GeoId, Sketcher::PointPos::start);
EditMarkers.emplace_back(start.x, start.y);
}
if(GeoId2 != Sketcher::GeoEnum::GeoUndef)
if (GeoId2 != Sketcher::GeoEnum::GeoUndef)
EditMarkers.emplace_back(intersect2.x, intersect2.y);
else {
auto end = sk->getPoint(GeoId, Sketcher::PointPos::end);
EditMarkers.emplace_back( end.x, end.y);
EditMarkers.emplace_back(end.x, end.y);
}
drawEditMarkers(EditMarkers, 2); // maker augmented by two sizes (see supported marker sizes)
drawEditMarkers(EditMarkers,
2);// maker augmented by two sizes (see supported marker sizes)
}
}
else {
@@ -123,22 +129,25 @@ public:
{
int GeoId = getPreselectCurve();
if (GeoId > -1) {
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomTrimmedCurve::getClassTypeId()) ||
geom->getTypeId() == Part::GeomCircle::getClassTypeId() ||
geom->getTypeId() == Part::GeomEllipse::getClassTypeId() ||
geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId() ) {
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(GeoId);
if (geom->getTypeId().isDerivedFrom(Part::GeomTrimmedCurve::getClassTypeId())
|| geom->getTypeId() == Part::GeomCircle::getClassTypeId()
|| geom->getTypeId() == Part::GeomEllipse::getClassTypeId()
|| geom->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
try {
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Trim edge"));
Gui::cmdAppObjectArgs(sketchgui->getObject(), "trim(%d,App.Vector(%f,%f,0))",
GeoId, onSketchPos.x, onSketchPos.y);
Gui::cmdAppObjectArgs(sketchgui->getObject(),
"trim(%d,App.Vector(%f,%f,0))",
GeoId,
onSketchPos.x,
onSketchPos.y);
Gui::Command::commitCommand();
tryAutoRecompute(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
tryAutoRecompute(static_cast<Sketcher::SketchObject*>(sketchgui->getObject()));
}
catch (const Base::Exception& e) {
Gui::NotifyError(sketchgui,
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to trim edge"));
QT_TRANSLATE_NOOP("Notifications", "Error"),
QT_TRANSLATE_NOOP("Notifications", "Failed to trim edge"));
Gui::Command::abortCommand();
}
@@ -147,8 +156,9 @@ public:
EditMarkers.resize(0);
drawEditMarkers(EditMarkers);
}
else // exit the trimming tool if the user clicked on empty space
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
else// exit the trimming tool if the user clicked on empty space
sketchgui
->purgeHandler();// no code after this line, Handler get deleted in ViewProvider
return true;
}
@@ -161,7 +171,8 @@ private:
Gui::Selection().addSelectionGate(new TrimmingSelection(sketchgui->getObject()));
}
QString getCrosshairCursorSVGName() const override {
QString getCrosshairCursorSVGName() const override
{
return QString::fromLatin1("Sketcher_Pointer_Trimming");
}
@@ -170,9 +181,7 @@ private:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_DrawSketchHandlerTrimming_H
#endif// SKETCHERGUI_DrawSketchHandlerTrimming_H
+64 -50
View File
@@ -23,11 +23,11 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Standard_math.hxx>
#include <Standard_math.hxx>
/// Qt Include Files
# include <QApplication>
# include <QDialog>
# include <Inventor/sensors/SoSensor.h>
#include <Inventor/sensors/SoSensor.h>
#include <QApplication>
#include <QDialog>
#endif
#include <Base/Tools.h>
@@ -38,13 +38,13 @@
#include <Gui/Notifications.h>
#include <Gui/View3DInventor.h>
#include <Gui/View3DInventorViewer.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include <Mod/Sketcher/App/GeometryFacade.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ViewProviderSketch.h"
#include "ui_InsertDatum.h"
#include "EditDatumDialog.h"
#include "Utils.h"
#include "ViewProviderSketch.h"
#include "ui_InsertDatum.h"
using namespace SketcherGui;
@@ -55,7 +55,7 @@ EditDatumDialog::EditDatumDialog(ViewProviderSketch* vp, int ConstrNbr)
: ConstrNbr(ConstrNbr)
{
sketch = vp->getSketchObject();
const std::vector<Sketcher::Constraint *> &Constraints = sketch->Constraints.getValues();
const std::vector<Sketcher::Constraint*>& Constraints = sketch->Constraints.getValues();
Constr = Constraints[ConstrNbr];
}
@@ -63,14 +63,12 @@ EditDatumDialog::EditDatumDialog(Sketcher::SketchObject* pcSketch, int ConstrNbr
: sketch(pcSketch)
, ConstrNbr(ConstrNbr)
{
const std::vector<Sketcher::Constraint *> &Constraints = sketch->Constraints.getValues();
const std::vector<Sketcher::Constraint*>& Constraints = sketch->Constraints.getValues();
Constr = Constraints[ConstrNbr];
}
EditDatumDialog::~EditDatumDialog()
{
}
{}
void EditDatumDialog::exec(bool atCursor)
{
@@ -79,8 +77,9 @@ void EditDatumDialog::exec(bool atCursor)
if (sketch->hasConflicts()) {
Gui::TranslatedUserWarning(sketch,
QObject::tr("Dimensional constraint"),
QObject::tr("Not allowed to edit the datum because the sketch contains conflicting constraints"));
QObject::tr("Dimensional constraint"),
QObject::tr("Not allowed to edit the datum because the "
"sketch contains conflicting constraints"));
return;
}
@@ -99,36 +98,42 @@ void EditDatumDialog::exec(bool atCursor)
dlg.setWindowTitle(tr("Insert angle"));
init_val.setUnit(Base::Unit::Angle);
ui_ins_datum->label->setText(tr("Angle:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherAngle"));
ui_ins_datum->labelEdit->setParamGrpPath(
QByteArray("User parameter:BaseApp/History/SketcherAngle"));
}
else if (Constr->Type == Sketcher::Radius) {
dlg.setWindowTitle(tr("Insert radius"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum->label->setText(tr("Radius:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
ui_ins_datum->labelEdit->setParamGrpPath(
QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
else if (Constr->Type == Sketcher::Diameter) {
dlg.setWindowTitle(tr("Insert diameter"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum->label->setText(tr("Diameter:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
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"));
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"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio"));
ui_ins_datum->labelEdit->setParamGrpPath(
QByteArray("User parameter:BaseApp/History/SketcherRefrIndexRatio"));
ui_ins_datum->labelEdit->setSingleStep(0.05);
}
else {
dlg.setWindowTitle(tr("Insert length"));
init_val.setUnit(Base::Unit::Length);
ui_ins_datum->label->setText(tr("Length:"));
ui_ins_datum->labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength"));
ui_ins_datum->labelEdit->setParamGrpPath(
QByteArray("User parameter:BaseApp/History/SketcherLength"));
}
init_val.setValue(datum);
@@ -139,25 +144,32 @@ void EditDatumDialog::exec(bool atCursor)
ui_ins_datum->labelEdit->bind(sketch->Constraints.createPath(ConstrNbr));
ui_ins_datum->name->setText(Base::Tools::fromStdString(Constr->Name));
ui_ins_datum->cbDriving->setChecked(! Constr->isDriving);
ui_ins_datum->cbDriving->setChecked(!Constr->isDriving);
connect(ui_ins_datum->cbDriving, &QCheckBox::toggled, this, &EditDatumDialog::drivingToggled);
connect(ui_ins_datum->labelEdit, qOverload<const Base::Quantity&>(&Gui::QuantitySpinBox::valueChanged),
this, &EditDatumDialog::datumChanged);
connect(ui_ins_datum->labelEdit, &Gui::QuantitySpinBox::showFormulaDialog,
this, &EditDatumDialog::formEditorOpened);
connect(
ui_ins_datum->cbDriving, &QCheckBox::toggled, this, &EditDatumDialog::drivingToggled);
connect(ui_ins_datum->labelEdit,
qOverload<const Base::Quantity&>(&Gui::QuantitySpinBox::valueChanged),
this,
&EditDatumDialog::datumChanged);
connect(ui_ins_datum->labelEdit,
&Gui::QuantitySpinBox::showFormulaDialog,
this,
&EditDatumDialog::formEditorOpened);
connect(&dlg, &QDialog::accepted, this, &EditDatumDialog::accepted);
connect(&dlg, &QDialog::rejected, this, &EditDatumDialog::rejected);
if (atCursor) {
dlg.show(); // Need to show the dialog so geometry is computed
dlg.show();// Need to show the dialog so geometry is computed
QRect pg = dlg.parentWidget()->geometry();
int Xmin = pg.x() + 10;
int Ymin = pg.y() + 10;
int Xmax = pg.x() + pg.width() - dlg.geometry().width() - 10;
int Ymax = pg.y() + pg.height() - dlg.geometry().height() - 10;
int x = Xmax < Xmin ? (Xmin + Xmax)/2 : std::min(std::max(QCursor::pos().x(), Xmin), Xmax);
int y = Ymax < Ymin ? (Ymin + Ymax)/2 : std::min(std::max(QCursor::pos().y(), Ymin), Ymax);
int x = Xmax < Xmin ? (Xmin + Xmax) / 2
: std::min(std::max(QCursor::pos().x(), Xmin), Xmax);
int y = Ymax < Ymin ? (Ymin + Ymax) / 2
: std::min(std::max(QCursor::pos().y(), Ymin), Ymax);
dlg.setGeometry(x, y, dlg.geometry().width(), dlg.geometry().height());
}
@@ -168,9 +180,8 @@ 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()) ||
(Constr->Type == Sketcher::Weight && 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();
@@ -183,19 +194,23 @@ void EditDatumDialog::accepted()
Gui::cmdAppObjectArgs(sketch, "toggleDriving(%i)", ConstrNbr);
}*/
if (! ui_ins_datum->cbDriving->isChecked()) {
if (!ui_ins_datum->cbDriving->isChecked()) {
if (ui_ins_datum->labelEdit->hasExpression())
ui_ins_datum->labelEdit->apply();
else
Gui::cmdAppObjectArgs(sketch, "setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr, newDatum, (const char*)newQuant.getUnit().getString().toUtf8());
Gui::cmdAppObjectArgs(sketch,
"setDatum(%i,App.Units.Quantity('%f %s'))",
ConstrNbr,
newDatum,
(const char*)newQuant.getUnit().getString().toUtf8());
}
QString constraintName = ui_ins_datum->name->text().trimmed();
if (Base::Tools::toStdString(constraintName) != sketch->Constraints[ConstrNbr]->Name) {
std::string escapedstr = Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
Gui::cmdAppObjectArgs(sketch, "renameConstraint(%d, u'%s')",
ConstrNbr, escapedstr.c_str());
std::string escapedstr =
Base::Tools::escapedUnicodeFromUtf8(constraintName.toUtf8().constData());
Gui::cmdAppObjectArgs(
sketch, "renameConstraint(%d, u'%s')", ConstrNbr, escapedstr.c_str());
}
Gui::Command::commitCommand();
@@ -208,27 +223,26 @@ void EditDatumDialog::accepted()
// It appears related to a drastic change in how dependencies are calculated, see:
// https://forum.freecad.org/viewtopic.php?f=3&t=55633&p=481061#p481061
//
// This is NOT the solution, as there is no point in systematically executing the ExpressionEngine
// on every dimensional constraint change. Just a quick fix to avoid clearly unwanted behaviour in
// absence of time to actually fix the root cause.
// This is NOT the solution, as there is no point in systematically executing the
// ExpressionEngine on every dimensional constraint change. Just a quick fix to avoid
// clearly unwanted behaviour in absence of time to actually fix the root cause.
//if (sketch->noRecomputes && sketch->ExpressionEngine.depsAreTouched()) {
sketch->ExpressionEngine.execute();
sketch->solve();
// if (sketch->noRecomputes && sketch->ExpressionEngine.depsAreTouched()) {
sketch->ExpressionEngine.execute();
sketch->solve();
//}
tryAutoRecompute(sketch);
}
catch (const Base::Exception& e) {
Gui::NotifyUserError(sketch,
QT_TRANSLATE_NOOP("Notifications", "Value Error"),
e.what());
Gui::NotifyUserError(
sketch, QT_TRANSLATE_NOOP("Notifications", "Value Error"), e.what());
Gui::Command::abortCommand();
if(sketch->noRecomputes) // if setdatum failed, it is highly likely that solver information is invalid.
if (sketch->noRecomputes)// if setdatum failed, it is highly likely that solver
// information is invalid.
sketch->solve();
}
}
}
@@ -245,7 +259,7 @@ void EditDatumDialog::drivingToggled(bool state)
ui_ins_datum->labelEdit->setToLastUsedValue();
}
sketch->setDriving(ConstrNbr, !state);
if(!sketch->noRecomputes) // if noRecomputes, solve() is already done by setDriving()
if (!sketch->noRecomputes)// if noRecomputes, solve() is already done by setDriving()
sketch->solve();
}
+11 -8
View File
@@ -23,20 +23,23 @@
#ifndef SKETCHERGUI_EditDatumDialog_H
#define SKETCHERGUI_EditDatumDialog_H
#include <memory>
#include <QObject>
#include <memory>
namespace Sketcher {
namespace Sketcher
{
class Constraint;
class SketchObject;
}
}// namespace Sketcher
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class Ui_InsertDatum;
class EditDatumDialog : public QObject {
class EditDatumDialog: public QObject
{
Q_OBJECT
public:
@@ -44,7 +47,7 @@ public:
EditDatumDialog(Sketcher::SketchObject* pcSketch, int ConstrNbr);
~EditDatumDialog() override;
void exec(bool atCursor=true);
void exec(bool atCursor = true);
private:
Sketcher::SketchObject* sketch;
@@ -60,5 +63,5 @@ private Q_SLOTS:
void formEditorOpened(bool);
};
}
#endif // SKETCHERGUI_DrawSketchHandler_H
}// namespace SketcherGui
#endif// SKETCHERGUI_DrawSketchHandler_H
File diff suppressed because it is too large Load Diff
+90 -71
View File
@@ -37,25 +37,29 @@ class SoRayPickAction;
class SoPickedPoint;
class SbVec3s;
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
class Placement;
class Placement;
}// namespace Base
namespace Part
{
class Geometry;
}
namespace Part {
class Geometry;
}
namespace Sketcher
{
class Constraint;
class PropertyConstraintList;
};// namespace Sketcher
namespace Sketcher {
class Constraint;
class PropertyConstraintList;
};
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class EditModeConstraintCoinManager;
@@ -71,7 +75,8 @@ using GeoListFacade = Sketcher::GeoListFacade;
* further delegates on other specialised helper classes. Some of them share the
* ViewProviderSketchCoinAttorney, which defines the maximum coupling and minimum encapsulation.
*
* The most important such delegates are: EditModeGeometryCoinManager and EditModeConstraintCoinManager.
* The most important such delegates are: EditModeGeometryCoinManager and
* EditModeConstraintCoinManager.
*
* EditModeCoinManager takes over the responsibility of creating the Coin (Inventor) scenograph
* and modifying it, including all the drawing of geometry, constraints and overlay layer. This
@@ -82,31 +87,35 @@ using GeoListFacade = Sketcher::GeoListFacade;
* its responsibility, this access is defined by ViewProviderSketchCoinAttorney.
*
* EditModeCoinManager is responsible, under the Single Responsibility Principle, to manage the coin
* EditRoot node. This node is ref-ed on creation and unref-ed on destruction to ensure that its lifetime
* matches the one of EditModecoinManager.
* EditRoot node. This node is ref-ed on creation and unref-ed on destruction to ensure that its
* lifetime matches the one of EditModecoinManager.
*
* EditRoot is added on request to pcRoot by ViewProviderSketch. The node pcRoot belongs, under the Single
* Responsibility Principle, to ViewProviderSketch. EditModeCoinManager delegates addition and removal of
* child notes of EditRoot to specialised helper classes.
* EditRoot is added on request to pcRoot by ViewProviderSketch. The node pcRoot belongs, under the
* Single Responsibility Principle, to ViewProviderSketch. EditModeCoinManager delegates addition
* and removal of child notes of EditRoot to specialised helper classes.
*
* EditModeCoinManager is designed to define the span of time in which ViewProviderSketch is in edit mode.
* EditModeCoinManager is designed to define the span of time in which ViewProviderSketch is in edit
* mode.
*
* In addition to the scenograph, EditModeCoinManager is responsible for keeping any necessary mapping between
* indices used at ViewProviderSketch level, and internal indexing used by EditModeCoinManager and its subclasses.
* In addition to the scenograph, EditModeCoinManager is responsible for keeping any necessary
* mapping between indices used at ViewProviderSketch level, and internal indexing used by
* EditModeCoinManager and its subclasses.
*/
class SketcherGuiExport EditModeCoinManager
{
/** @brief Class for monitoring changes in parameters affecting drawing and coin node generation
* @details
*
* This nested class is a helper responsible for attaching to the parameters relevant for
* EditModeCoinManager and its helpers, initialising the EditModeCoinManager to the current configuration
* and handle in real time any change to their values.
*/
class ParameterObserver : public ParameterGrp::ObserverType
/** @brief Class for monitoring changes in parameters affecting drawing and coin node
* generation
* @details
*
* This nested class is a helper responsible for attaching to the parameters relevant for
* EditModeCoinManager and its helpers, initialising the EditModeCoinManager to the current
* configuration and handle in real time any change to their values.
*/
class ParameterObserver: public ParameterGrp::ObserverType
{
private:
enum class OverlayVisibilityParameter {
enum class OverlayVisibilityParameter
{
BSplineDegree,
BSplineControlPolygonVisible,
BSplineCombVisible,
@@ -116,7 +125,7 @@ class SketcherGuiExport EditModeCoinManager
};
public:
explicit ParameterObserver(EditModeCoinManager & client);
explicit ParameterObserver(EditModeCoinManager& client);
~ParameterObserver() override;
void subscribeToParameters();
@@ -124,23 +133,23 @@ class SketcherGuiExport EditModeCoinManager
void unsubscribeToParameters();
/** Observer for parameter group. */
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
void OnChange(Base::Subject<const char*>& rCaller, const char* sReason) override;
private:
void initParameters();
void updateCurvedEdgeCountSegmentsParameter(const std::string & parametername);
void updateLineRenderingOrderParameters(const std::string & parametername);
void updateConstraintPresentationParameters(const std::string & parametername);
void updateElementSizeParameters(const std::string & parametername);
void updateColor(SbColor &sbcolor, const std::string &parametername);
void updateUnit(const std::string &parametername);
void updateCurvedEdgeCountSegmentsParameter(const std::string& parametername);
void updateLineRenderingOrderParameters(const std::string& parametername);
void updateConstraintPresentationParameters(const std::string& parametername);
void updateElementSizeParameters(const std::string& parametername);
void updateColor(SbColor& sbcolor, const std::string& parametername);
void updateUnit(const std::string& parametername);
template<OverlayVisibilityParameter visibilityparameter>
void updateOverlayVisibilityParameter(const std::string & parametername);
void updateOverlayVisibilityParameter(const std::string& parametername);
private:
std::map<std::string, std::function<void(const std::string &)>> str2updatefunction;
EditModeCoinManager &Client;
std::map<std::string, std::function<void(const std::string&)>> str2updatefunction;
EditModeCoinManager& Client;
};
public:
@@ -148,22 +157,27 @@ public:
*
* @details
*
* PointIndex: Only Positive values corresponding to VertexId (are positive for both normal and external geometry)
* GeoIndex: Same values as GeoId of GeoElementId, except for axes which are not included. -1 represents an invalid curve.
* PointIndex: Only Positive values corresponding to VertexId (are positive for both normal and
* external geometry) GeoIndex: Same values as GeoId of GeoElementId, except for axes which are
* not included. -1 represents an invalid curve.
*
* In other words valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
* In other words valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external
* geometry
*
* Cross: Axes and RootPoint values as defined in the enum class.
*
*/
struct PreselectionResult {
enum SpecialValues {
struct PreselectionResult
{
enum SpecialValues
{
InvalidPoint = -1,
InvalidCurve = -1,
ExternalCurve = -3
};
enum class Axes {
enum class Axes
{
None = -1,
RootPoint = 0,
HorizontalAxis = 1,
@@ -171,11 +185,13 @@ public:
};
int PointIndex = InvalidPoint;
int GeoIndex = InvalidCurve; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
int GeoIndex = InvalidCurve;// valid values are 0,1,2,... for normal geometry and
// -3,-4,-5,... for external geometry
Axes Cross = Axes::None;
std::set<int> ConstrIndices;
inline void clear() {
inline void clear()
{
PointIndex = InvalidPoint;
GeoIndex = InvalidCurve;
Cross = Axes::None;
@@ -184,29 +200,31 @@ public:
};
public:
explicit EditModeCoinManager(ViewProviderSketch &vp);
explicit EditModeCoinManager(ViewProviderSketch& vp);
~EditModeCoinManager();
/** @name Temporary edit curves and markers */
/** @name Temporary edit curves and markers */
//@{
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel);
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
void setPositionText(const Base::Vector2d &Pos);
void drawEditMarkers(const std::vector<Base::Vector2d>& EditMarkers,
unsigned int augmentationlevel);
void drawEdit(const std::vector<Base::Vector2d>& EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>>& list);
void setPositionText(const Base::Vector2d& Pos, const SbString& txt);
void setPositionText(const Base::Vector2d& Pos);
void resetPositionText();
void setAxisPickStyle(bool on);
//@}
/** @name handle preselection and selection of points */
//@{
PreselectionResult detectPreselection(SoPickedPoint * Point, const SbVec2s &cursorPos);
PreselectionResult detectPreselection(SoPickedPoint* Point, const SbVec2s& cursorPos);
/// The client is responsible for unref-ing the SoGroup to release the memory.
SoGroup* getSelectedConstraints();
//@}
/** @name update coin nodes*/
void processGeometryConstraintsInformationOverlay(const GeoListFacade & geolistfacade, bool rebuildinformationlayer);
void processGeometryConstraintsInformationOverlay(const GeoListFacade& geolistfacade,
bool rebuildinformationlayer);
void updateVirtualSpace();
@@ -215,7 +233,7 @@ public:
void drawConstraintIcons();
// This specific overload is to use a specific geometry list, which may be a temporal one
void drawConstraintIcons(const GeoListFacade & geolistfacade);
void drawConstraintIcons(const GeoListFacade& geolistfacade);
void updateGeometryLayersConfiguration();
//@}
@@ -227,7 +245,8 @@ public:
/** @name update coin colors*/
//@{
void updateColor();
void updateColor(const GeoListFacade & geolistfacade); // overload to be used with temporal geometry.
void
updateColor(const GeoListFacade& geolistfacade);// overload to be used with temporal geometry.
//@}
/** @name change constraints selectability*/
@@ -237,11 +256,12 @@ public:
private:
// This function populates the coin nodes with the information of the current geometry
void processGeometry(const GeoListFacade & geolistfacade);
void processGeometry(const GeoListFacade& geolistfacade);
// This function populates the geometry information layer of coin. It requires the analysis information
// gathered during the processGeometry step, so it is not possible to run both in parallel.
void processGeometryInformationOverlay(const GeoListFacade & geolistfacade);
// This function populates the geometry information layer of coin. It requires the analysis
// information gathered during the processGeometry step, so it is not possible to run both in
// parallel.
void processGeometryInformationOverlay(const GeoListFacade& geolistfacade);
// updates the Axes length to extend beyond the calculated bounding box magnitude
void updateAxesLength();
@@ -249,7 +269,7 @@ private:
// updates the parameters to be used for the Overlay information layer
void updateOverlayParameters();
void updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid);
void updateGeometryColor(const GeoListFacade& geolistfacade, bool issketchinvalid);
// causes the ViewProvider to draw
void redrawViewProvider();
@@ -268,7 +288,7 @@ private:
private:
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
/// Observer to track all the needed parameters.
std::unique_ptr<EditModeCoinManager::ParameterObserver> pObserver;
@@ -290,8 +310,7 @@ private:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_EditModeCoinManager_H
#endif// SKETCHERGUI_EditModeCoinManager_H
@@ -27,30 +27,35 @@
using namespace SketcherGui;
SbColor DrawingParameters::InformationColor (0.0f, 1.0f, 0.0f); // #00FF00 -> ( 0,255, 0)
SbColor DrawingParameters::CreateCurveColor (0.8f, 0.8f, 0.8f); // #CCCCCC -> (204,204,204)
SbColor DrawingParameters::CrossColorH (0.8f, 0.4f, 0.4f); // #CC6666 -> (204,102,102)
SbColor DrawingParameters::CrossColorV (0.47f, 1.0f, 0.51f); // #83FF83 -> (120,255,131)
SbColor DrawingParameters::InvalidSketchColor (1.0f, 0.42f, 0.0f); // #FF6D00 -> (255,109, 0)
SbColor DrawingParameters::FullyConstrainedColor (0.0f, 1.0f, 0.0f); // #00FF00 -> ( 0,255, 0)
SbColor DrawingParameters::FullyConstraintInternalAlignmentColor (0.87f, 0.87f, 0.78f); // #DEDEC8 -> (222,222,200)
SbColor DrawingParameters::InternalAlignedGeoColor (0.7f, 0.7f, 0.5f); // #B2B27F -> (178,178,127)
SbColor DrawingParameters::FullyConstraintConstructionPointColor (1.0f, 0.58f, 0.50f); // #FF9580 -> (255,149,128)
SbColor DrawingParameters::VertexColor (1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::FullyConstraintElementColor (0.50f, 0.81f, 0.62f); // #80D0A0 -> (128,208,160)
SbColor DrawingParameters::CurveColor (1.0f, 1.0f, 1.0f); // #FFFFFF -> (255,255,255)
SbColor DrawingParameters::PreselectColor (0.88f, 0.88f, 0.0f); // #E1E100 -> (225,225, 0)
SbColor DrawingParameters::SelectColor (0.11f, 0.68f, 0.11f); // #1CAD1C -> ( 28,173, 28)
SbColor DrawingParameters::PreselectSelectedColor (0.36f, 0.48f, 0.11f); // #5D7B1C -> ( 93,123, 28)
SbColor DrawingParameters::CurveExternalColor (0.8f, 0.2f, 0.6f); // #CC3399 -> (204, 51,153)
SbColor DrawingParameters::CurveDraftColor (0.0f, 0.0f, 0.86f); // #0000DC -> ( 0, 0,220)
SbColor DrawingParameters::FullyConstraintConstructionElementColor (0.56f, 0.66f, 0.99f); // #8FA9FD -> (143,169,253)
SbColor DrawingParameters::InformationColor(0.0f, 1.0f, 0.0f); // #00FF00 -> ( 0,255, 0)
SbColor DrawingParameters::CreateCurveColor(0.8f, 0.8f, 0.8f); // #CCCCCC -> (204,204,204)
SbColor DrawingParameters::CrossColorH(0.8f, 0.4f, 0.4f); // #CC6666 -> (204,102,102)
SbColor DrawingParameters::CrossColorV(0.47f, 1.0f, 0.51f); // #83FF83 -> (120,255,131)
SbColor DrawingParameters::InvalidSketchColor(1.0f, 0.42f, 0.0f); // #FF6D00 -> (255,109, 0)
SbColor DrawingParameters::FullyConstrainedColor(0.0f, 1.0f, 0.0f);// #00FF00 -> ( 0,255, 0)
SbColor DrawingParameters::FullyConstraintInternalAlignmentColor(0.87f, 0.87f,
0.78f);// #DEDEC8 -> (222,222,200)
SbColor DrawingParameters::InternalAlignedGeoColor(0.7f, 0.7f, 0.5f); // #B2B27F -> (178,178,127)
SbColor DrawingParameters::FullyConstraintConstructionPointColor(1.0f, 0.58f,
0.50f);// #FF9580 -> (255,149,128)
SbColor DrawingParameters::VertexColor(1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::FullyConstraintElementColor(0.50f, 0.81f,
0.62f); // #80D0A0 -> (128,208,160)
SbColor DrawingParameters::CurveColor(1.0f, 1.0f, 1.0f); // #FFFFFF -> (255,255,255)
SbColor DrawingParameters::PreselectColor(0.88f, 0.88f, 0.0f); // #E1E100 -> (225,225, 0)
SbColor DrawingParameters::SelectColor(0.11f, 0.68f, 0.11f); // #1CAD1C -> ( 28,173, 28)
SbColor DrawingParameters::PreselectSelectedColor(0.36f, 0.48f, 0.11f);// #5D7B1C -> ( 93,123, 28)
SbColor DrawingParameters::CurveExternalColor(0.8f, 0.2f, 0.6f); // #CC3399 -> (204, 51,153)
SbColor DrawingParameters::CurveDraftColor(0.0f, 0.0f, 0.86f); // #0000DC -> ( 0, 0,220)
SbColor
DrawingParameters::FullyConstraintConstructionElementColor(0.56f, 0.66f,
0.99f);// #8FA9FD -> (143,169,253)
SbColor DrawingParameters::ConstrDimColor (1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::ConstrIcoColor (1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::NonDrivingConstrDimColor (0.0f, 0.149f, 1.0f); // #0026FF -> ( 0, 38,255)
SbColor DrawingParameters::ExprBasedConstrDimColor (1.0f, 0.5f, 0.149f); // #FF7F26 -> (255, 127,38)
SbColor DrawingParameters::DeactivatedConstrDimColor (0.8f, 0.8f, 0.8f); // #CCCCCC -> (204,204,204)
SbColor DrawingParameters::CursorTextColor (0.0f, 0.0f, 1.0f); // #0000FF -> (0,0,255)
SbColor DrawingParameters::ConstrDimColor(1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::ConstrIcoColor(1.0f, 0.149f, 0.0f); // #FF2600 -> (255, 38, 0)
SbColor DrawingParameters::NonDrivingConstrDimColor(0.0f, 0.149f, 1.0f);// #0026FF -> ( 0, 38,255)
SbColor DrawingParameters::ExprBasedConstrDimColor(1.0f, 0.5f, 0.149f); // #FF7F26 -> (255, 127,38)
SbColor DrawingParameters::DeactivatedConstrDimColor(0.8f, 0.8f, 0.8f); // #CCCCCC -> (204,204,204)
SbColor DrawingParameters::CursorTextColor(0.0f, 0.0f, 1.0f); // #0000FF -> (0,0,255)
const MultiFieldId MultiFieldId::Invalid = MultiFieldId();
@@ -29,8 +29,8 @@
#include <QString>
#include <Inventor/SbColor.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
@@ -47,39 +47,45 @@
#include "ViewProviderSketchGeometryExtension.h"
namespace Part {
class Geometry;
namespace Part
{
class Geometry;
}
namespace SketcherGui {
namespace SketcherGui
{
/** @brief Struct for storing local drawing parameters
*
* Parameters based on user preferenced are auto loaded by EditCoinManager observer nested class.
*/
struct DrawingParameters {
struct DrawingParameters
{
/// Defines the number of segments to use to draw a curved edge
int curvedEdgeCountSegments;
/** @name Rendering Heights - virtual height introduced in the scenegraph to determine what is drawn on top of what*/
/** @name Rendering Heights - virtual height introduced in the scenegraph to determine what is
* drawn on top of what*/
//@{
const float zEdit = 0.001f; // Height used by temporal edit curves
const float zCross = 0.001f; // Height used by the Axes
const float zInfo = 0.004f; // Height used by the Overlay information layer
const float zLowLines = 0.005f; // Height used for bottom rendered lines
const float zMidLines = 0.006f; // Height used for in-the-middle rendered lines
const float zHighLines = 0.007f; // Height used for on top rendered lines
const float zHighLine = 0.008f; // Height for highlighted lines (selected/preselected)
const float zConstr = 0.009f; // Height for rendering constraints
const float zRootPoint = 0.010f; // Height used for rendering the root point
const float zLowPoints = 0.011f; // Height used for bottom rendered points
const float zHighPoints = 0.012f; // Height used for in-the-middle rendered points
const float zHighlight = 0.013f; // Height for highlighted points (selected/preselected)
const float zText = 0.013f; // Height for rendered text
const float zEdit = 0.001f; // Height used by temporal edit curves
const float zCross = 0.001f; // Height used by the Axes
const float zInfo = 0.004f; // Height used by the Overlay information layer
const float zLowLines = 0.005f; // Height used for bottom rendered lines
const float zMidLines = 0.006f; // Height used for in-the-middle rendered lines
const float zHighLines = 0.007f; // Height used for on top rendered lines
const float zHighLine = 0.008f; // Height for highlighted lines (selected/preselected)
const float zConstr = 0.009f; // Height for rendering constraints
const float zRootPoint = 0.010f; // Height used for rendering the root point
const float zLowPoints = 0.011f; // Height used for bottom rendered points
const float zHighPoints = 0.012f;// Height used for in-the-middle rendered points
const float zHighlight = 0.013f; // Height for highlighted points (selected/preselected)
const float zText = 0.013f; // Height for rendered text
//@}
/// Different categories of geometries that can be selected by the user to be rendered on top, in the middle or in the bottom
enum class GeometryRendering {
/// Different categories of geometries that can be selected by the user to be rendered on top,
/// in the middle or in the bottom
enum class GeometryRendering
{
NormalGeometry = 1,
Construction = 2,
ExternalGeometry = 3
@@ -93,80 +99,93 @@ struct DrawingParameters {
/** @name Rendering Coin Colors **/
//@{
static SbColor InformationColor; // Information Overlay Color
static SbColor CreateCurveColor; // Color for Edit Curves during creation
static SbColor CrossColorH; // Color for the Horizontal Axis
static SbColor CrossColorV; // Color for the Vertical Axis
static SbColor InvalidSketchColor; // Color for rendering an invalid sketch
static SbColor FullyConstrainedColor; // Color for a fully constrained sketch
static SbColor FullyConstraintInternalAlignmentColor; // Color for fully constrained internal alignment geometry
static SbColor InternalAlignedGeoColor; // Color for non-fully constrained internal alignment geometry
static SbColor FullyConstraintConstructionPointColor; // Color for fully constrained construction points
static SbColor VertexColor; // Color for vertices
static SbColor FullyConstraintElementColor; // Color for a fully constrained element
static SbColor CurveColor; // Color for curves
static SbColor PreselectColor; // Color used for pre-selection
static SbColor PreselectSelectedColor; // Color used for pre-selection when geometry is already selected
static SbColor SelectColor; // Color used for selected geometry
static SbColor CurveExternalColor; // Color used for external geometry
static SbColor CurveDraftColor; // Color used for construction geometry
static SbColor FullyConstraintConstructionElementColor; // Color used for a fully constrained construction element
static SbColor ConstrDimColor; // Color used for a dimensional constraints
static SbColor ConstrIcoColor; // Color used for constraint icons
static SbColor NonDrivingConstrDimColor; // Color used for non-driving (reference) dimensional constraints
static SbColor ExprBasedConstrDimColor; // Color used for expression based dimensional constraints
static SbColor DeactivatedConstrDimColor; // Color used for deactivated dimensional constraints
static SbColor CursorTextColor; // Color used by the edit mode cursor
static SbColor InformationColor; // Information Overlay Color
static SbColor CreateCurveColor; // Color for Edit Curves during creation
static SbColor CrossColorH; // Color for the Horizontal Axis
static SbColor CrossColorV; // Color for the Vertical Axis
static SbColor InvalidSketchColor; // Color for rendering an invalid sketch
static SbColor FullyConstrainedColor; // Color for a fully constrained sketch
static SbColor FullyConstraintInternalAlignmentColor;// Color for fully constrained internal
// alignment geometry
static SbColor
InternalAlignedGeoColor;// Color for non-fully constrained internal alignment geometry
static SbColor
FullyConstraintConstructionPointColor; // Color for fully constrained construction points
static SbColor VertexColor; // Color for vertices
static SbColor FullyConstraintElementColor;// Color for a fully constrained element
static SbColor CurveColor; // Color for curves
static SbColor PreselectColor; // Color used for pre-selection
static SbColor
PreselectSelectedColor;// Color used for pre-selection when geometry is already selected
static SbColor SelectColor;// Color used for selected geometry
static SbColor CurveExternalColor; // Color used for external geometry
static SbColor CurveDraftColor; // Color used for construction geometry
static SbColor FullyConstraintConstructionElementColor;// Color used for a fully constrained
// construction element
static SbColor ConstrDimColor;// Color used for a dimensional constraints
static SbColor ConstrIcoColor;// Color used for constraint icons
static SbColor
NonDrivingConstrDimColor;// Color used for non-driving (reference) dimensional constraints
static SbColor
ExprBasedConstrDimColor;// Color used for expression based dimensional constraints
static SbColor DeactivatedConstrDimColor;// Color used for deactivated dimensional constraints
static SbColor CursorTextColor; // Color used by the edit mode cursor
//@}
/** @name Rendering sizes (also to support HDPI monitors) **/
//@{
double pixelScalingFactor = 1.0; // Scaling factor to be used for pixels
int coinFontSize = 17; // Font size to be used by coin
int labelFontSize = 17; // Font size to be used by SoDatumLabel, which uses a QPainter and a QFont internally
int constraintIconSize = 15; // Size of constraint icons
int markerSize = 7; // Size used for markers
double pixelScalingFactor = 1.0;// Scaling factor to be used for pixels
int coinFontSize = 17; // Font size to be used by coin
int labelFontSize =
17;// Font size to be used by SoDatumLabel, which uses a QPainter and a QFont internally
int constraintIconSize = 15;// Size of constraint icons
int markerSize = 7; // Size used for markers
//@}
};
/** @brief Struct for storing references to the scenegraph nodes necessary for geometry layers
*/
struct GeometryLayerNodes {
struct GeometryLayerNodes
{
/** @name Point nodes*/
//@{
std::vector<SoMaterial *> & PointsMaterials; // The materials for the points/vertices
std::vector<SoCoordinate3 *>& PointsCoordinate; // The coordinates of the points/vertices
std::vector<SoMaterial*>& PointsMaterials; // The materials for the points/vertices
std::vector<SoCoordinate3*>& PointsCoordinate;// The coordinates of the points/vertices
//@}
/** @name Curve nodes*/
//@{
std::vector<SoMaterial *> & CurvesMaterials; // The materials for the curves
std::vector<SoCoordinate3 *> & CurvesCoordinate; // The coordinates of the segments of the curves
std::vector<SoLineSet *> & CurveSet; // The set of curves
std::vector<SoMaterial*>& CurvesMaterials; // The materials for the curves
std::vector<SoCoordinate3*>& CurvesCoordinate;// The coordinates of the segments of the curves
std::vector<SoLineSet*>& CurveSet; // The set of curves
//@}
};
/** @brief
* Helper class to store together a field index of a coin multifield object and the coin geometry layer to
* which it belongs.
* Helper class to store together a field index of a coin multifield object and the coin geometry
* layer to which it belongs.
*
* @details
*
* @warning the layer is * not * the logical layer (the one of GeometryFacade), but the coin layer. See GeometryLayerParameters.
* @warning the layer is * not * the logical layer (the one of GeometryFacade), but the coin layer.
* See GeometryLayerParameters.
*
* Overloaded operators and specialisation of std::less enable it to be used in containers including ordered
* containers.
* Overloaded operators and specialisation of std::less enable it to be used in containers including
* ordered containers.
*/
class MultiFieldId {
class MultiFieldId
{
public:
explicit constexpr MultiFieldId(int fieldindex = -1, int layerid = 0): fieldIndex(fieldindex),
layerId(layerid){}
explicit constexpr MultiFieldId(int fieldindex = -1, int layerid = 0)
: fieldIndex(fieldindex)
, layerId(layerid)
{}
MultiFieldId(const MultiFieldId & ) = default;
MultiFieldId & operator=(const MultiFieldId &) = default;
MultiFieldId(const MultiFieldId&) = default;
MultiFieldId& operator=(const MultiFieldId&) = default;
MultiFieldId(MultiFieldId && ) = default;
MultiFieldId & operator=(MultiFieldId &&) = default;
MultiFieldId(MultiFieldId&&) = default;
MultiFieldId& operator=(MultiFieldId&&) = default;
inline bool operator==(const MultiFieldId& obj) const
{
@@ -185,21 +204,26 @@ public:
};
} // namespace SketcherGui
}// namespace SketcherGui
namespace std
{
template<> struct less<SketcherGui::MultiFieldId>
template<>
struct less<SketcherGui::MultiFieldId>
{
bool operator()(const SketcherGui::MultiFieldId& lhs,
const SketcherGui::MultiFieldId& rhs) const
{
bool operator() (const SketcherGui::MultiFieldId& lhs, const SketcherGui::MultiFieldId& rhs) const
{
return (lhs.layerId != rhs.layerId)?(lhs.layerId < rhs.layerId):(static_cast<int>(lhs.fieldIndex) < static_cast<int>(rhs.fieldIndex));
}
};
} // namespace std
return (lhs.layerId != rhs.layerId)
? (lhs.layerId < rhs.layerId)
: (static_cast<int>(lhs.fieldIndex) < static_cast<int>(rhs.fieldIndex));
}
};
}// namespace std
namespace SketcherGui {
namespace SketcherGui
{
/** @brief
* Helper class to store geometry layers configuration
@@ -216,54 +240,65 @@ namespace SketcherGui {
* 1. A N:N relationship between logical layers and coin layers.
* 2. A M:N relationship between logical layers and coin layers (M<N), including a 1:N relationship.
*/
class GeometryLayerParameters {
class GeometryLayerParameters
{
public:
GeometryLayerParameters() { reset();}
GeometryLayerParameters()
{
reset();
}
private:
enum CoinLayer {
enum CoinLayer
{
Default = 0
};
public:
void reset() {
void reset()
{
CoinLayers = 1;
}
inline int getSafeCoinLayer(int coinlayer) {
if(coinlayer < CoinLayers) {
inline int getSafeCoinLayer(int coinlayer)
{
if (coinlayer < CoinLayers) {
return coinlayer;
}
return Default;
}
int inline getCoinLayerCount() const {
int inline getCoinLayerCount() const
{
return CoinLayers;
}
void setCoinLayerCount(int layernumber) {
void setCoinLayerCount(int layernumber)
{
CoinLayers = layernumber;
}
private:
int CoinLayers = 1; // defaults to a single Coin Geometry Layer.
int CoinLayers = 1;// defaults to a single Coin Geometry Layer.
};
/** @brief Struct to hold the results of analysis performed on geometry
*/
struct AnalysisResults { // TODO: This needs to be refactored
double combRepresentationScale = 0; // used for information overlay (BSpline comb)
float boundingBoxMagnitudeOrder = 0; // used for grid extension
std::vector<int> bsplineGeoIds; // used for information overlay
*/
struct AnalysisResults
{ // TODO: This needs to be refactored
double combRepresentationScale = 0; // used for information overlay (BSpline comb)
float boundingBoxMagnitudeOrder = 0;// used for grid extension
std::vector<int> bsplineGeoIds; // used for information overlay
std::vector<int> arcGeoIds;
};
/** @brief Struct adapted to store the parameters necessary to create and update
* the information overlay layer.
*/
struct OverlayParameters {
struct OverlayParameters
{
bool rebuildInformationLayer = false;
bool visibleInformationChanged = true;
double currentBSplineCombRepresentationScale = 0;
@@ -280,79 +315,81 @@ struct OverlayParameters {
/** @brief Struct adapted to store the parameters necessary to create and update
* constraints.
*/
struct ConstraintParameters {
bool bHideUnits; // whether units should be hidden or not
bool bShowDimensionalName; // whether the name of dimensional constraints should be shown or not
QString sDimensionalStringFormat; // how to code strings of dimensional constraints
struct ConstraintParameters
{
bool bHideUnits; // whether units should be hidden or not
bool bShowDimensionalName;// whether the name of dimensional constraints should be shown or not
QString sDimensionalStringFormat;// how to code strings of dimensional constraints
};
/** @brief Helper struct adapted to store the pointer to edit mode scenegraph objects.
*/
struct EditModeScenegraphNodes {
struct EditModeScenegraphNodes
{
/** @name Point nodes*/
//@{
SoSeparator * EditRoot;
SmSwitchboard * PointsGroup;
std::vector<SoMaterial *> PointsMaterials;
std::vector<SoCoordinate3 *> PointsCoordinate;
std::vector<SoDrawStyle *> PointsDrawStyle;
std::vector<SoMarkerSet *> PointSet;
SoSeparator* EditRoot;
SmSwitchboard* PointsGroup;
std::vector<SoMaterial*> PointsMaterials;
std::vector<SoCoordinate3*> PointsCoordinate;
std::vector<SoDrawStyle*> PointsDrawStyle;
std::vector<SoMarkerSet*> PointSet;
//@}
/** @name Curve nodes*/
//@{
SmSwitchboard * CurvesGroup;
std::vector<SoMaterial *> CurvesMaterials;
std::vector<SoCoordinate3 *> CurvesCoordinate;
std::vector<SoDrawStyle *> CurvesDrawStyle;
std::vector<SoLineSet *> CurveSet;
SmSwitchboard* CurvesGroup;
std::vector<SoMaterial*> CurvesMaterials;
std::vector<SoCoordinate3*> CurvesCoordinate;
std::vector<SoDrawStyle*> CurvesDrawStyle;
std::vector<SoLineSet*> CurveSet;
//@}
/** @name Axes nodes*/
/// @warning Root Point is added together with the Point nodes above
//@{
SoMaterial *RootCrossMaterials;
SoCoordinate3 *RootCrossCoordinate;
SoLineSet *RootCrossSet;
SoDrawStyle *RootCrossDrawStyle;
SoMaterial* RootCrossMaterials;
SoCoordinate3* RootCrossCoordinate;
SoLineSet* RootCrossSet;
SoDrawStyle* RootCrossDrawStyle;
//@}
/** @name Temporal edit curve nodes - For geometry creation */
//@{
SoMaterial *EditCurvesMaterials;
SoCoordinate3 *EditCurvesCoordinate;
SoLineSet *EditCurveSet;
SoDrawStyle *EditCurvesDrawStyle;
SoPickStyle *pickStyleAxes;
SoMaterial* EditCurvesMaterials;
SoCoordinate3* EditCurvesCoordinate;
SoLineSet* EditCurveSet;
SoDrawStyle* EditCurvesDrawStyle;
SoPickStyle* pickStyleAxes;
//@}
/** @name Temporal edit markers nodes- For operation rendering, such as trimming green circles*/
//@{
SoMaterial *EditMarkersMaterials;
SoCoordinate3 *EditMarkersCoordinate;
SoMarkerSet *EditMarkerSet;
SoDrawStyle *EditMarkersDrawStyle;
SoMaterial* EditMarkersMaterials;
SoCoordinate3* EditMarkersCoordinate;
SoMarkerSet* EditMarkerSet;
SoDrawStyle* EditMarkersDrawStyle;
//@}
/** @name Temporal edit text nodes*/
//@{
SoText2 *textX;
SoTranslation *textPos;
SoFont *textFont;
SoMaterial *textMaterial;
SoText2* textX;
SoTranslation* textPos;
SoFont* textFont;
SoMaterial* textMaterial;
//@}
/** @name Constraint nodes*/
//@{
SmSwitchboard *constrGroup;
SoPickStyle *constrGrpSelect;
SoDrawStyle *ConstraintDrawStyle;
SmSwitchboard* constrGroup;
SoPickStyle* constrGrpSelect;
SoDrawStyle* ConstraintDrawStyle;
//@}
/** @name Information Overlay Layer nodes*/
//@{
SoGroup *infoGroup;
SoDrawStyle *InformationDrawStyle;
SoGroup* infoGroup;
SoDrawStyle* InformationDrawStyle;
//@}
};
@@ -361,24 +398,40 @@ struct EditModeScenegraphNodes {
*
* These are updated with every draw of the scenegraph.
*/
struct CoinMapping {
struct CoinMapping
{
void clear() {
void clear()
{
CurvIdToGeoId.clear();
PointIdToGeoId.clear();
GeoElementId2SetId.clear();
PointIdToVertexId.clear();
};
/// given the MF index of a curve and the coin layer in which it is drawn returns the GeoId of the curve
int getCurveGeoId(int curveindex, int layerindex) {return CurvIdToGeoId[layerindex][curveindex];}
/// given the MF index of a point and the coin layer in which it is drawn returns the GeoId of the point
int getPointGeoId(int pointindex, int layerindex) {return PointIdToGeoId[layerindex][pointindex];}
/// given the MF index of a point and the coin layer in which it is drawn returns the VertexId of the point
int getPointVertexId(int pointindex, int layerindex) {return PointIdToVertexId[layerindex][pointindex];}
/// given the MF index of a curve and the coin layer in which it is drawn returns the GeoId of
/// the curve
int getCurveGeoId(int curveindex, int layerindex)
{
return CurvIdToGeoId[layerindex][curveindex];
}
/// given the MF index of a point and the coin layer in which it is drawn returns the GeoId of
/// the point
int getPointGeoId(int pointindex, int layerindex)
{
return PointIdToGeoId[layerindex][pointindex];
}
/// given the MF index of a point and the coin layer in which it is drawn returns the VertexId
/// of the point
int getPointVertexId(int pointindex, int layerindex)
{
return PointIdToVertexId[layerindex][pointindex];
}
/// given the {GeoId, PointPos} of a curve or point, returns MultiFieldId containing the MF index and the coin layer of the curve or point
MultiFieldId getIndexLayer(int geoid, Sketcher::PointPos pos) {
/// given the {GeoId, PointPos} of a curve or point, returns MultiFieldId containing the MF
/// index and the coin layer of the curve or point
MultiFieldId getIndexLayer(int geoid, Sketcher::PointPos pos)
{
auto indexit = GeoElementId2SetId.find(Sketcher::GeoElementId(geoid, pos));
if (indexit != GeoElementId2SetId.end()) {
@@ -388,31 +441,36 @@ struct CoinMapping {
return MultiFieldId::Invalid;
}
/// given the VertexId of a point, returns MultiFieldId containing the MF index and the coin layer of the point
MultiFieldId getIndexLayer(int vertexId) {
/// given the VertexId of a point, returns MultiFieldId containing the MF index and the coin
/// layer of the point
MultiFieldId getIndexLayer(int vertexId)
{
for(size_t l=0; l<PointIdToVertexId.size(); l++) {
auto indexit = std::find(PointIdToVertexId[l].begin(), PointIdToVertexId[l].end(), vertexId);
for (size_t l = 0; l < PointIdToVertexId.size(); l++) {
auto indexit =
std::find(PointIdToVertexId[l].begin(), PointIdToVertexId[l].end(), vertexId);
if(indexit != PointIdToVertexId[l].end())
return MultiFieldId(std::distance(PointIdToVertexId[l].begin(),indexit),l);
if (indexit != PointIdToVertexId[l].end())
return MultiFieldId(std::distance(PointIdToVertexId[l].begin(), indexit), l);
}
return MultiFieldId::Invalid;
}
//* These map a MF index (second index) within a coin layer (first index) for points or curves to a GeoId */
//* These map a MF index (second index) within a coin layer (first index) for points or curves
//to a GeoId */
std::vector<std::vector<int>> CurvIdToGeoId; // conversion of SoLineSet index to GeoId
std::vector<std::vector<int>> PointIdToGeoId; // conversion of SoCoordinate3 index to GeoId
std::vector<std::vector<int>> PointIdToGeoId;// conversion of SoCoordinate3 index to GeoId
//* This maps an MF index (second index) of a point within a coin layer (first index) to a global VertexId */
//* This maps an MF index (second index) of a point within a coin layer (first index) to a
//global VertexId */
std::vector<std::vector<int>> PointIdToVertexId;
/// This maps GeoElementId index {GeoId, PointPos} to a {coin layer and MF index} of a curve or point.
std::map<Sketcher::GeoElementId,MultiFieldId> GeoElementId2SetId;
/// This maps GeoElementId index {GeoId, PointPos} to a {coin layer and MF index} of a curve or
/// point.
std::map<Sketcher::GeoElementId, MultiFieldId> GeoElementId2SetId;
};
} // namespace SketcherGui
#endif // SKETCHERGUI_EditModeCoinManagerParameters_H
}// namespace SketcherGui
#endif// SKETCHERGUI_EditModeCoinManagerParameters_H
File diff suppressed because it is too large Load Diff
@@ -30,8 +30,8 @@
#include <QImage>
#include <QRect>
# include <Inventor/nodes/SoImage.h>
# include <Inventor/nodes/SoInfo.h>
#include <Inventor/nodes/SoImage.h>
#include <Inventor/nodes/SoInfo.h>
#include <Mod/Sketcher/App/GeoList.h>
@@ -43,32 +43,37 @@ class SoRayPickAction;
class SoPickedPoint;
class SbVec3s;
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
class Placement;
class Placement;
}// namespace Base
namespace Part
{
class Geometry;
}
namespace Part {
class Geometry;
}
namespace Sketcher
{
class Constraint;
class PropertyConstraintList;
};// namespace Sketcher
namespace Sketcher {
class Constraint;
class PropertyConstraintList;
};
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
using GeoList = Sketcher::GeoList;
using GeoListFacade = Sketcher::GeoListFacade;
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to constraints.
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to
* constraints.
* @details To be documented.
*
*/
@@ -76,7 +81,8 @@ class SketcherGuiExport EditModeConstraintCoinManager
{
private:
/// Coin Node indices for constraints
enum class ConstraintNodePosition {
enum class ConstraintNodePosition
{
MaterialIndex = 0,
DatumLabelIndex = 0,
FirstTranslationIndex = 1,
@@ -86,19 +92,19 @@ private:
SecondIconIndex = 5,
SecondConstraintIdIndex = 6
};
public:
explicit EditModeConstraintCoinManager( ViewProviderSketch &vp,
DrawingParameters & drawingParams,
GeometryLayerParameters & geometryLayerParams,
ConstraintParameters & constraintParams,
EditModeScenegraphNodes & editModeScenegraph,
CoinMapping & coinMap);
explicit EditModeConstraintCoinManager(ViewProviderSketch& vp, DrawingParameters& drawingParams,
GeometryLayerParameters& geometryLayerParams,
ConstraintParameters& constraintParams,
EditModeScenegraphNodes& editModeScenegraph,
CoinMapping& coinMap);
~EditModeConstraintCoinManager();
/** @name update coin nodes*/
// geometry list to be used for constraints, which may be a temporal geometry
void processConstraints(const GeoListFacade & geolistfacade);
void processConstraints(const GeoListFacade& geolistfacade);
void updateVirtualSpace();
@@ -107,12 +113,12 @@ public:
void drawConstraintIcons();
// This specific overload is to use a specific geometry list, which may be a temporal one
void drawConstraintIcons(const GeoListFacade & geolistfacade);
void drawConstraintIcons(const GeoListFacade& geolistfacade);
//@}
/** @name update coin colors*/
//@{
void updateConstraintColor(const std::vector<Sketcher::Constraint *> & constraints);
void updateConstraintColor(const std::vector<Sketcher::Constraint*>& constraints);
//@}
/** @name coin nodes creation*/
@@ -124,34 +130,33 @@ public:
void setConstraintSelectability(bool enabled = true);
//@}
std::set<int> detectPreselectionConstr( const SoPickedPoint *Point,
const SbVec2s &cursorPos);
std::set<int> detectPreselectionConstr(const SoPickedPoint* Point, const SbVec2s& cursorPos);
SoSeparator * getConstraintIdSeparator(int i);
SoSeparator* getConstraintIdSeparator(int i);
void createEditModeInventorNodes();
private:
void rebuildConstraintNodes(const GeoListFacade & geolistfacade); // with specific geometry
void rebuildConstraintNodes(const GeoListFacade& geolistfacade);// with specific geometry
void rebuildConstraintNodes(const GeoListFacade & geolistfacade, const std::vector<Sketcher::Constraint *> constrlist, SbVec3f norm);
void rebuildConstraintNodes(const GeoListFacade& geolistfacade,
const std::vector<Sketcher::Constraint*> constrlist, SbVec3f norm);
/// finds a free position for placing a constraint icon
Base::Vector3d seekConstraintPosition(const Base::Vector3d &origPos,
const Base::Vector3d &norm,
const Base::Vector3d &dir, float step,
const SoNode *constraint);
Base::Vector3d seekConstraintPosition(const Base::Vector3d& origPos, const Base::Vector3d& norm,
const Base::Vector3d& dir, float step,
const SoNode* constraint);
/// Return display string for constraint including hiding units if
//requested.
QString getPresentationString(const Sketcher::Constraint *constraint);
// requested.
QString getPresentationString(const Sketcher::Constraint* constraint);
/// Returns the size that Coin should display the indicated image at
SbVec3s getDisplayedSize(const SoImage *) const;
SbVec3s getDisplayedSize(const SoImage*) const;
/** @name Protected helpers for drawing constraint icons*/
//@{
QString iconTypeFromConstraint(Sketcher::Constraint *constraint);
QString iconTypeFromConstraint(Sketcher::Constraint* constraint);
/// Returns a QColor object appropriate for constraint with given id
/*! In the case of combined icons, the icon color is chosen based on
@@ -177,14 +182,15 @@ private:
// rendering tree) to a vector of those bounding boxes paired with relevant
// constraint IDs.
using ConstrIconBB = std::pair<QRect, std::set<int> >;
using ConstrIconBB = std::pair<QRect, std::set<int>>;
using ConstrIconBBVec = std::vector<ConstrIconBB>;
std::map<QString, ConstrIconBBVec> combinedConstrBoxes;
/// Internal type used for drawing constraint icons
struct constrIconQueueItem {
struct constrIconQueueItem
{
/// Type of constraint the icon represents. Eg: "small/Constraint_PointOnObject_sm"
QString type;
@@ -199,10 +205,10 @@ private:
SbVec3f position;
/// Pointer to the SoImage object where the icon should be written
SoImage *destination;
SoImage* destination;
/// Pointer to SoInfo object where we store the constraint IDs that the icon refers to
SoInfo *infoPtr;
SoInfo* infoPtr;
/// Angle to rotate an icon
double iconRotation;
@@ -215,48 +221,44 @@ private:
void combineConstraintIcons(IconQueue iconQueue);
/// Renders an icon for a single constraint and sends it to Coin
void drawTypicalConstraintIcon(const constrIconQueueItem &i);
void drawTypicalConstraintIcon(const constrIconQueueItem& i);
/// Combines multiple constraint icons and sends them to Coin
void drawMergedConstraintIcons(IconQueue iconQueue);
/// Helper for drawMergedConstraintIcons and drawTypicalConstraintIcon
QImage renderConstrIcon(const QString &type,
const QColor &iconColor,
const QStringList &labels,
const QList<QColor> &labelColors,
double iconRotation,
QImage renderConstrIcon(const QString& type, const QColor& iconColor, const QStringList& labels,
const QList<QColor>& labelColors, double iconRotation,
//! Gets populated with bounding boxes (in icon
//! image coordinates) for the icon at left, then
//! labels for different constraints.
std::vector<QRect> *boundingBoxes = nullptr,
std::vector<QRect>* boundingBoxes = nullptr,
//! If not NULL, gets set to the number of pixels
//! that the text extends below the icon base.
int *vPad = nullptr);
int* vPad = nullptr);
/// Copies a QImage constraint icon into a SoImage*
/*! Used by drawTypicalConstraintIcon() and drawMergedConstraintIcons() */
void sendConstraintIconToCoin(const QImage &icon, SoImage *soImagePtr);
void sendConstraintIconToCoin(const QImage& icon, SoImage* soImagePtr);
/// Essentially a version of sendConstraintIconToCoin, with a blank icon
void clearCoinImage(SoImage *soImagePtr);
void clearCoinImage(SoImage* soImagePtr);
//@}
private:
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
DrawingParameters & drawingParameters;
GeometryLayerParameters & geometryLayerParameters;
ConstraintParameters & constraintParameters;
DrawingParameters& drawingParameters;
GeometryLayerParameters& geometryLayerParameters;
ConstraintParameters& constraintParameters;
EditModeScenegraphNodes & editModeScenegraphNodes;
EditModeScenegraphNodes& editModeScenegraphNodes;
CoinMapping & coinMapping;
CoinMapping& coinMapping;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_EditModeConstraintCoinManager_H
#endif// SKETCHERGUI_EditModeConstraintCoinManager_H
@@ -25,28 +25,27 @@
#include <Base/Console.h>
#include <Base/Exception.h>
#include "EditModeGeometryCoinConverter.h"
#include "EditModeCoinManagerParameters.h"
#include "EditModeGeometryCoinConverter.h"
#include "Utils.h"
#include "ViewProviderSketchCoinAttorney.h"
#include "ViewProviderSketchGeometryExtension.h"
#include "Utils.h"
using namespace SketcherGui;
EditModeGeometryCoinConverter::EditModeGeometryCoinConverter( ViewProviderSketch & vp,
GeometryLayerNodes & geometrylayernodes,
DrawingParameters & drawingparameters,
GeometryLayerParameters& geometryLayerParams,
CoinMapping & coinMap ):
viewProvider(vp),
geometryLayerNodes(geometrylayernodes),
drawingParameters(drawingparameters),
geometryLayerParameters(geometryLayerParams),
coinMapping(coinMap)
EditModeGeometryCoinConverter::EditModeGeometryCoinConverter(
ViewProviderSketch& vp, GeometryLayerNodes& geometrylayernodes,
DrawingParameters& drawingparameters, GeometryLayerParameters& geometryLayerParams,
CoinMapping& coinMap)
: viewProvider(vp)
, geometryLayerNodes(geometrylayernodes)
, drawingParameters(drawingparameters)
, geometryLayerParameters(geometryLayerParams)
, coinMapping(coinMap)
{}
void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geolistfacade)
void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade& geolistfacade)
{
// measurements
@@ -63,7 +62,7 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geol
pointCounter.clear();
curveCounter.clear();
for(auto l=0; l<geometryLayerParameters.getCoinLayerCount(); l++){
for (auto l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
Coords.emplace_back();
Points.emplace_back();
Index.emplace_back();
@@ -73,82 +72,93 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geol
coinMapping.PointIdToVertexId.emplace_back();
}
pointCounter.resize(geometryLayerParameters.getCoinLayerCount(),0);
curveCounter.resize(geometryLayerParameters.getCoinLayerCount(),0);
pointCounter.resize(geometryLayerParameters.getCoinLayerCount(), 0);
curveCounter.resize(geometryLayerParameters.getCoinLayerCount(), 0);
// RootPoint
// TODO: RootPoint is here added in layer0. However, this layer may be hidden. The point should,
// when that functionality is provided, be added to the first visible layer, or may even a new
// empty layer.
Points[0].emplace_back(0.,0.,0.);
coinMapping.PointIdToGeoId[0].push_back(-1); // root point
coinMapping.PointIdToVertexId[0].push_back(-1); // VertexId is the reference used for point selection/preselection
Points[0].emplace_back(0., 0., 0.);
coinMapping.PointIdToGeoId[0].push_back(-1);// root point
coinMapping.PointIdToVertexId[0].push_back(
-1);// VertexId is the reference used for point selection/preselection
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(Sketcher::GeoElementId::RtPnt),
std::forward_as_tuple(pointCounter[0]++, 0));
coinMapping.GeoElementId2SetId.emplace(std::piecewise_construct,
std::forward_as_tuple(Sketcher::GeoElementId::RtPnt),
std::forward_as_tuple(pointCounter[0]++, 0));
auto setTracking = [this] (int geoId, int coinLayer, EditModeGeometryCoinConverter::PointsMode pointmode, int numberCurves) {
auto setTracking = [this](int geoId,
int coinLayer,
EditModeGeometryCoinConverter::PointsMode pointmode,
int numberCurves) {
int numberPoints = 0;
if(pointmode == PointsMode::InsertSingle) {
if (pointmode == PointsMode::InsertSingle) {
numberPoints = 1;
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
}
else if (pointmode == PointsMode::InsertStartEnd) {
numberPoints = 2;
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
}
else if (pointmode == PointsMode::InsertMidOnly) {
numberPoints = 1;
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
}
else if (pointmode == PointsMode::InsertStartEndMid) {
numberPoints = 3;
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
}
for(int i = 0; i < numberPoints; i++) {
for (int i = 0; i < numberPoints; i++) {
coinMapping.PointIdToGeoId[coinLayer].push_back(geoId);
coinMapping.PointIdToVertexId[coinLayer].push_back(vertexCounter++);
}
if(numberCurves > 0) // insert the first segment of the curve into the map
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::none),
std::forward_as_tuple(static_cast<int>(coinMapping.CurvIdToGeoId[coinLayer].size()), coinLayer));
if (numberCurves > 0)// insert the first segment of the curve into the map
coinMapping.GeoElementId2SetId.emplace(
std::piecewise_construct,
std::forward_as_tuple(geoId, Sketcher::PointPos::none),
std::forward_as_tuple(static_cast<int>(coinMapping.CurvIdToGeoId[coinLayer].size()),
coinLayer));
for(int i = 0; i < numberCurves; i++)
for (int i = 0; i < numberCurves; i++)
coinMapping.CurvIdToGeoId[coinLayer].push_back(geoId);
};
for (size_t i = 0 ; i < geolistfacade.geomlist.size()- 2; i++) {
for (size_t i = 0; i < geolistfacade.geomlist.size() - 2; i++) {
const auto GeoId = geolistfacade.getGeoIdFromGeomListIndex(i);
const auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
@@ -158,46 +168,53 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geol
auto coinLayer = geometryLayerParameters.getSafeCoinLayer(layerId);
if (type == Part::GeomPoint::getClassTypeId()) { // add a point
convert< Part::GeomPoint,
EditModeGeometryCoinConverter::PointsMode::InsertSingle,
EditModeGeometryCoinConverter::CurveMode::NoCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertSingle, 0);
if (type == Part::GeomPoint::getClassTypeId()) {// add a point
convert<Part::GeomPoint,
EditModeGeometryCoinConverter::PointsMode::InsertSingle,
EditModeGeometryCoinConverter::CurveMode::NoCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(
GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertSingle, 0);
}
else if (type == Part::GeomLineSegment::getClassTypeId()) { // add a line
convert< Part::GeomLineSegment,
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
EditModeGeometryCoinConverter::CurveMode::StartEndPointsOnly,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
else if (type == Part::GeomLineSegment::getClassTypeId()) {// add a line
convert<Part::GeomLineSegment,
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
EditModeGeometryCoinConverter::CurveMode::StartEndPointsOnly,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(
GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
}
else if (type.isDerivedFrom(Part::GeomConic::getClassTypeId())) { // add a closed curve conic
convert< Part::GeomConic,
EditModeGeometryCoinConverter::PointsMode::InsertMidOnly,
EditModeGeometryCoinConverter::CurveMode::ClosedCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertMidOnly, 1);
else if (type.isDerivedFrom(Part::GeomConic::getClassTypeId())) {// add a closed curve conic
convert<Part::GeomConic,
EditModeGeometryCoinConverter::PointsMode::InsertMidOnly,
EditModeGeometryCoinConverter::CurveMode::ClosedCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(
GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertMidOnly, 1);
}
else if (type.isDerivedFrom(Part::GeomArcOfConic::getClassTypeId())) { // add an arc of conic
convert< Part::GeomArcOfConic,
EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid,
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid, 1);
else if (type.isDerivedFrom(Part::GeomArcOfConic::getClassTypeId())) {// add an arc of conic
convert<Part::GeomArcOfConic,
EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid,
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
setTracking(
GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid, 1);
arcGeoIds.push_back(GeoId);
}
else if (type == Part::GeomBSplineCurve::getClassTypeId()) { // add a bspline (a bounded curve that is not a conic)
convert< Part::GeomBSplineCurve,
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature>(geom, GeoId);
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
else if (type == Part::GeomBSplineCurve::getClassTypeId()) {// add a bspline (a bounded
// curve that is not a conic)
convert<Part::GeomBSplineCurve,
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
EditModeGeometryCoinConverter::AnalyseMode::
BoundingBoxMagnitudeAndBSplineCurvature>(geom, GeoId);
setTracking(
GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
bsplineGeoIds.push_back(GeoId);
}
}
for(auto l=0 ; l < geometryLayerParameters.getCoinLayerCount() ; l++) {
for (auto l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
// Coin Nodes Editing
geometryLayerNodes.CurvesCoordinate[l]->point.setNum(Coords[l].size());
@@ -206,23 +223,33 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geol
geometryLayerNodes.PointsCoordinate[l]->point.setNum(Points[l].size());
geometryLayerNodes.PointsMaterials[l]->diffuseColor.setNum(Points[l].size());
SbVec3f *verts = geometryLayerNodes.CurvesCoordinate[l]->point.startEditing();
int32_t *index = geometryLayerNodes.CurveSet[l]->numVertices.startEditing();
SbVec3f *pverts = geometryLayerNodes.PointsCoordinate[l]->point.startEditing();
SbVec3f* verts = geometryLayerNodes.CurvesCoordinate[l]->point.startEditing();
int32_t* index = geometryLayerNodes.CurveSet[l]->numVertices.startEditing();
SbVec3f* pverts = geometryLayerNodes.PointsCoordinate[l]->point.startEditing();
int i=0; // setting up the line set
for (std::vector<Base::Vector3d>::const_iterator it = Coords[l].begin(); it != Coords[l].end(); ++it,i++)
verts[i].setValue(it->x,it->y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zLowLines);
int i = 0;// setting up the line set
for (std::vector<Base::Vector3d>::const_iterator it = Coords[l].begin();
it != Coords[l].end();
++it, i++)
verts[i].setValue(it->x,
it->y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zLowLines);
i=0; // setting up the indexes of the line set
for (std::vector<unsigned int>::const_iterator it = Index[l].begin(); it != Index[l].end(); ++it,i++)
i = 0;// setting up the indexes of the line set
for (std::vector<unsigned int>::const_iterator it = Index[l].begin(); it != Index[l].end();
++it, i++)
index[i] = *it;
i=0; // setting up the point set
for (std::vector<Base::Vector3d>::const_iterator it = Points[l].begin(); it != Points[l].end(); ++it,i++)
pverts[i].setValue(it->x,it->y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zLowPoints);
i = 0;// setting up the point set
for (std::vector<Base::Vector3d>::const_iterator it = Points[l].begin();
it != Points[l].end();
++it, i++)
pverts[i].setValue(
it->x,
it->y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zLowPoints);
geometryLayerNodes.CurvesCoordinate[l]->point.finishEditing();
geometryLayerNodes.CurveSet[l]->numVertices.finishEditing();
@@ -230,21 +257,22 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geol
}
}
template < typename GeoType,
EditModeGeometryCoinConverter::PointsMode pointmode,
EditModeGeometryCoinConverter::CurveMode curvemode,
EditModeGeometryCoinConverter::AnalyseMode analysemode >
void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade * geometryfacade, [[maybe_unused]] int geoid) {
auto geo = static_cast<const GeoType *>(geometryfacade->getGeometry());
template<typename GeoType, EditModeGeometryCoinConverter::PointsMode pointmode,
EditModeGeometryCoinConverter::CurveMode curvemode,
EditModeGeometryCoinConverter::AnalyseMode analysemode>
void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade* geometryfacade,
[[maybe_unused]] int geoid)
{
auto geo = static_cast<const GeoType*>(geometryfacade->getGeometry());
auto layerId = getSafeGeomLayerId(geometryfacade);
auto coinLayer = geometryLayerParameters.getSafeCoinLayer(layerId);
auto addPoint = [&dMg = boundingBoxMaxMagnitude] (auto & pushvector, Base::Vector3d point) {
if constexpr (analysemode == AnalyseMode::BoundingBoxMagnitude || analysemode == AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature) {
dMg = dMg>std::abs(point.x)?dMg:std::abs(point.x);
dMg = dMg>std::abs(point.y)?dMg:std::abs(point.y);
auto addPoint = [&dMg = boundingBoxMaxMagnitude](auto& pushvector, Base::Vector3d point) {
if constexpr (analysemode == AnalyseMode::BoundingBoxMagnitude
|| analysemode == AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature) {
dMg = dMg > std::abs(point.x) ? dMg : std::abs(point.x);
dMg = dMg > std::abs(point.y) ? dMg : std::abs(point.y);
pushvector.push_back(point);
}
};
@@ -280,32 +308,32 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade * geo
double segment = (geo->getLastParameter() - geo->getFirstParameter()) / numSegments;
for (int i=0; i < numSegments; i++) {
Base::Vector3d pnt = geo->value(i*segment);
for (int i = 0; i < numSegments; i++) {
Base::Vector3d pnt = geo->value(i * segment);
addPoint(Coords[coinLayer], pnt);
}
Base::Vector3d pnt = geo->value(0);
addPoint(Coords[coinLayer], pnt);
Index[coinLayer].push_back(numSegments+1);
Index[coinLayer].push_back(numSegments + 1);
}
else if constexpr (curvemode == CurveMode::OpenCurve) {
int numSegments = drawingParameters.curvedEdgeCountSegments;
if constexpr (std::is_same<GeoType, Part::GeomBSplineCurve>::value)
numSegments *= (geo->countKnots() - 1); // one less segments than knots
numSegments *= (geo->countKnots() - 1);// one less segments than knots
double segment = (geo->getLastParameter() - geo->getFirstParameter()) / numSegments;
for (int i=0; i < numSegments; i++) {
Base::Vector3d pnt = geo->value(geo->getFirstParameter() + i*segment);
for (int i = 0; i < numSegments; i++) {
Base::Vector3d pnt = geo->value(geo->getFirstParameter() + i * segment);
addPoint(Coords[coinLayer], pnt);
}
Base::Vector3d pnt = geo->value(geo->getLastParameter());
addPoint(Coords[coinLayer], pnt);
addPoint(Coords[coinLayer], pnt);
Index[coinLayer].push_back(numSegments+1);
Index[coinLayer].push_back(numSegments + 1);
if constexpr (analysemode == AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature) {
//***************************************************************************************************************
@@ -313,19 +341,20 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade * geo
std::vector<Base::Vector3d> poles = geo->getPoles();
Base::Vector3d midp = Base::Vector3d(0,0,0);
Base::Vector3d midp = Base::Vector3d(0, 0, 0);
for (std::vector<Base::Vector3d>::iterator it = poles.begin(); it != poles.end(); ++it) {
for (std::vector<Base::Vector3d>::iterator it = poles.begin(); it != poles.end();
++it) {
midp += (*it);
}
midp /= poles.size();
double firstparam = geo->getFirstParameter();
double lastparam = geo->getLastParameter();
double lastparam = geo->getLastParameter();
const int ndiv = poles.size()>4?poles.size()*16:64;
double step = (lastparam - firstparam ) / (ndiv -1);
const int ndiv = poles.size() > 4 ? poles.size() * 16 : 64;
double step = (lastparam - firstparam) / (ndiv - 1);
std::vector<double> paramlist(ndiv);
std::vector<Base::Vector3d> pointatcurvelist(ndiv);
@@ -342,36 +371,36 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade * geo
try {
curvaturelist[i] = geo->curvatureAt(paramlist[i]);
}
catch(Base::CADKernelError &e) {
catch (Base::CADKernelError& e) {
// it is "just" a visualisation matter OCC could not calculate the curvature
// terminating here would mean that the other shapes would not be drawn.
// Solution: Report the issue and set dummy curvature to 0
e.ReportException();
Base::Console().DeveloperError("EditModeGeometryCoinConverter","Curvature graph for B-Spline with GeoId=%d could not be calculated.\n", geoid); // TODO: Fix identification of curve.
Base::Console().DeveloperError(
"EditModeGeometryCoinConverter",
"Curvature graph for B-Spline with GeoId=%d could not be calculated.\n",
geoid);// TODO: Fix identification of curve.
curvaturelist[i] = 0;
}
if (curvaturelist[i] > maxcurv)
maxcurv = curvaturelist[i];
double tempf = ( pointatcurvelist[i] - midp ).Length();
double tempf = (pointatcurvelist[i] - midp).Length();
if (tempf > maxdisttocenterofmass)
maxdisttocenterofmass = tempf;
}
double temprepscale = 0;
if (maxcurv > 0)
temprepscale = (0.5 * maxdisttocenterofmass) / maxcurv; // just a factor to make a comb reasonably visible
temprepscale = (0.5 * maxdisttocenterofmass)
/ maxcurv;// just a factor to make a comb reasonably visible
if (temprepscale > combrepscale)
combrepscale = temprepscale;
}
}
}
float EditModeGeometryCoinConverter::getBoundingBoxMaxMagnitude()
@@ -28,28 +28,32 @@
#include "ViewProviderSketch.h"
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
}// namespace Base
namespace Sketcher
{
enum ConstraintType : int;
enum class PointPos : int;
}// namespace Sketcher
namespace Part
{
class Geometry;
}
namespace Sketcher {
enum ConstraintType : int;
enum class PointPos : int;
}
namespace Part {
class Geometry;
}
namespace SketcherGui {
class ViewProviderSketch;
struct GeometryLayerNodes;
struct DrawingParameters;
class GeometryLayerParameters;
struct CoinMapping;
namespace SketcherGui
{
class ViewProviderSketch;
struct GeometryLayerNodes;
struct DrawingParameters;
class GeometryLayerParameters;
struct CoinMapping;
/** @brief Class for creating the Geometry layer into coin nodes
* @details
@@ -61,31 +65,38 @@ namespace SketcherGui {
* Interface:
* A single entry point convert(), performing the following flow:
*
* [Geometry] => Analysis => construct drawing elements => Create mappings GeoId coin => populate coin nodes
* [Geometry] => Analysis => construct drawing elements => Create mappings GeoId coin => populate
* coin nodes
*
* Analysis performs analysis such as maximum boundingbox magnitude of all geometries and maximum curvature of BSplines
* Analysis performs analysis such as maximum boundingbox magnitude of all geometries and maximum
* curvature of BSplines
*/
class EditModeGeometryCoinConverter {
// These internal private classes are used to parametrize the conversion of geometry into points and line sets (see template method convert)
class EditModeGeometryCoinConverter
{
// These internal private classes are used to parametrize the conversion of geometry into points
// and line sets (see template method convert)
private:
enum class PointsMode {
enum class PointsMode
{
InsertSingle,
InsertStartEnd,
InsertStartEndMid,
InsertMidOnly
};
};
enum class CurveMode {
enum class CurveMode
{
NoCurve,
StartEndPointsOnly,
ClosedCurve,
OpenCurve
};
};
enum class AnalyseMode {
enum class AnalyseMode
{
BoundingBoxMagnitude,
BoundingBoxMagnitudeAndBSplineCurvature
};
};
public:
/** Constructs an GeometryCoinConverter responsible for
@@ -98,50 +109,55 @@ public:
*
* @param drawingparameters: Parameters for drawing the overlay information
*/
EditModeGeometryCoinConverter( ViewProviderSketch & vp,
GeometryLayerNodes & geometrylayernodes,
DrawingParameters & drawingparameters,
GeometryLayerParameters& geometryLayerParams,
CoinMapping & coinMap );
EditModeGeometryCoinConverter(ViewProviderSketch& vp, GeometryLayerNodes& geometrylayernodes,
DrawingParameters& drawingparameters,
GeometryLayerParameters& geometryLayerParams,
CoinMapping& coinMap);
/**
* converts the geometry defined by GeometryLayer into the coin nodes.
*
* @param geometry: the geometry to be processed
*/
void convert(const Sketcher::GeoListFacade & geolistfacade);
* converts the geometry defined by GeometryLayer into the coin nodes.
*
* @param geometry: the geometry to be processed
*/
void convert(const Sketcher::GeoListFacade& geolistfacade);
/**
* returns the maximum of the vertical and horizontal magnitudes of the
* coordinates of the points and lines added to coin by this layer (local responsibility).
*/
* returns the maximum of the vertical and horizontal magnitudes of the
* coordinates of the points and lines added to coin by this layer (local responsibility).
*/
float getBoundingBoxMaxMagnitude();
/**
* returns the Comb representation scale that should be used to represent
* the B-Splines of this layer (local responsibility).
*/
* returns the Comb representation scale that should be used to represent
* the B-Splines of this layer (local responsibility).
*/
double getCombRepresentationScale();
/**
* returns the GeoIds of BSpline geometries
*/
auto getBSplineGeoIds(){ return std::move(bsplineGeoIds);}
* returns the GeoIds of BSpline geometries
*/
auto getBSplineGeoIds()
{
return std::move(bsplineGeoIds);
}
/**
* returns the GeoIds of Arc geometries
*/
auto getArcGeoIds(){ return std::move(arcGeoIds);}
* returns the GeoIds of Arc geometries
*/
auto getArcGeoIds()
{
return std::move(arcGeoIds);
}
private:
template < typename GeoType, PointsMode pointmode, CurveMode curvemode, AnalyseMode analysemode >
void convert(const Sketcher::GeometryFacade * geometryfacade, [[maybe_unused]] int geoId);
template<typename GeoType, PointsMode pointmode, CurveMode curvemode, AnalyseMode analysemode>
void convert(const Sketcher::GeometryFacade* geometryfacade, [[maybe_unused]] int geoId);
private:
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
GeometryLayerNodes & geometryLayerNodes;
GeometryLayerNodes& geometryLayerNodes;
std::vector<std::vector<Base::Vector3d>> Coords;
std::vector<std::vector<Base::Vector3d>> Points;
@@ -155,22 +171,21 @@ private:
int vertexCounter = 0;
// Parameters
DrawingParameters & drawingParameters;
DrawingParameters& drawingParameters;
GeometryLayerParameters& geometryLayerParameters;
// Mappings coin geoId
CoinMapping & coinMapping;
CoinMapping& coinMapping;
// measurements
float boundingBoxMaxMagnitude = 100;
double combrepscale = 0; // the repscale that would correspond to this comb based only on this calculation.
double combrepscale =
0;// the repscale that would correspond to this comb based only on this calculation.
std::vector<int> bsplineGeoIds;
std::vector<int> arcGeoIds;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_GeometryCoinConverter_H
#endif// SKETCHERGUI_GeometryCoinConverter_H
@@ -22,16 +22,16 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <memory>
#include <memory>
# include <Inventor/SbVec3f.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoSeparator.h>
#endif // #ifndef _PreComp_
#include <Inventor/SbVec3f.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoMarkerSet.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSeparator.h>
#endif// #ifndef _PreComp_
#include <Gui/Inventor/MarkerBitmaps.h>
#include <Gui/Inventor/SmSwitchboard.h>
@@ -41,8 +41,8 @@
#include <Mod/Sketcher/App/GeometryFacade.h>
#include <Mod/Sketcher/App/SolverGeometryExtension.h>
#include "EditModeGeometryCoinManager.h"
#include "EditModeGeometryCoinConverter.h"
#include "EditModeGeometryCoinManager.h"
#include "ViewProviderSketchCoinAttorney.h"
@@ -51,70 +51,69 @@ using namespace Sketcher;
//**************************** EditModeGeometryCoinManager class ******************************
EditModeGeometryCoinManager::EditModeGeometryCoinManager( ViewProviderSketch &vp,
DrawingParameters & drawingParams,
GeometryLayerParameters & geometryLayerParams,
AnalysisResults & analysisResultStruct,
EditModeScenegraphNodes & editModeScenegraph,
CoinMapping & coinMap):
viewProvider(vp),
drawingParameters(drawingParams),
geometryLayerParameters(geometryLayerParams),
analysisResults(analysisResultStruct),
editModeScenegraphNodes(editModeScenegraph),
coinMapping(coinMap)
EditModeGeometryCoinManager::EditModeGeometryCoinManager(
ViewProviderSketch& vp, DrawingParameters& drawingParams,
GeometryLayerParameters& geometryLayerParams, AnalysisResults& analysisResultStruct,
EditModeScenegraphNodes& editModeScenegraph, CoinMapping& coinMap)
: viewProvider(vp)
, drawingParameters(drawingParams)
, geometryLayerParameters(geometryLayerParams)
, analysisResults(analysisResultStruct)
, editModeScenegraphNodes(editModeScenegraph)
, coinMapping(coinMap)
{}
EditModeGeometryCoinManager::~EditModeGeometryCoinManager()
{}
void EditModeGeometryCoinManager::processGeometry(const GeoListFacade & geolistfacade)
void EditModeGeometryCoinManager::processGeometry(const GeoListFacade& geolistfacade)
{
// enable all layers
editModeScenegraphNodes.PointsGroup->enable.setNum(geometryLayerParameters.getCoinLayerCount());
editModeScenegraphNodes.CurvesGroup->enable.setNum(geometryLayerParameters.getCoinLayerCount());
SbBool *swsp = editModeScenegraphNodes.PointsGroup->enable.startEditing();
SbBool *swsc = editModeScenegraphNodes.CurvesGroup->enable.startEditing();
SbBool* swsp = editModeScenegraphNodes.PointsGroup->enable.startEditing();
SbBool* swsc = editModeScenegraphNodes.CurvesGroup->enable.startEditing();
auto setEnableLayer = [swsp, swsc](int l, bool enabled) {
swsp[l] = enabled; // layer defaults to enabled
swsc[l] = enabled; // layer defaults to enabled
swsp[l] = enabled;// layer defaults to enabled
swsc[l] = enabled;// layer defaults to enabled
};
auto layersconfigurations = viewProvider.VisualLayerList.getValues();
for(auto l=0; l<geometryLayerParameters.getCoinLayerCount(); l++){
setEnableLayer(l,layersconfigurations[l].isVisible());
for (auto l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
setEnableLayer(l, layersconfigurations[l].isVisible());
}
editModeScenegraphNodes.PointsGroup->enable.finishEditing();
editModeScenegraphNodes.CurvesGroup->enable.finishEditing();
// Define the coin nodes that will be filled in with the geometry layers
GeometryLayerNodes geometrylayernodes {
editModeScenegraphNodes.PointsMaterials,
editModeScenegraphNodes.PointsCoordinate,
editModeScenegraphNodes.CurvesMaterials,
editModeScenegraphNodes.CurvesCoordinate,
editModeScenegraphNodes.CurveSet
};
GeometryLayerNodes geometrylayernodes {editModeScenegraphNodes.PointsMaterials,
editModeScenegraphNodes.PointsCoordinate,
editModeScenegraphNodes.CurvesMaterials,
editModeScenegraphNodes.CurvesCoordinate,
editModeScenegraphNodes.CurveSet};
// process geometry layers
EditModeGeometryCoinConverter gcconv(viewProvider, geometrylayernodes, drawingParameters, geometryLayerParameters, coinMapping);
EditModeGeometryCoinConverter gcconv(
viewProvider, geometrylayernodes, drawingParameters, geometryLayerParameters, coinMapping);
gcconv.convert(geolistfacade);
// set cross coordinates
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(0,2);
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(1,2);
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(0, 2);
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(1, 2);
analysisResults.combRepresentationScale = gcconv.getCombRepresentationScale();
analysisResults.boundingBoxMagnitudeOrder = exp(ceil(log(std::abs(gcconv.getBoundingBoxMaxMagnitude()))));
analysisResults.boundingBoxMagnitudeOrder =
exp(ceil(log(std::abs(gcconv.getBoundingBoxMaxMagnitude()))));
analysisResults.bsplineGeoIds = gcconv.getBSplineGeoIds();
analysisResults.arcGeoIds = gcconv.getArcGeoIds();
}
void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid)
void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geolistfacade,
bool issketchinvalid)
{
// Lambdas for convenience retrieval of geometry information
auto isConstructionGeom = [&geolistfacade](int GeoId) {
@@ -142,13 +141,14 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
auto isFullyConstraintElement = [&geolistfacade](int GeoId) {
auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
if(geom) {
if(geom->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) {
if (geom) {
if (geom->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) {
auto solvext = std::static_pointer_cast<const Sketcher::SolverGeometryExtension>(
geom->getExtension(Sketcher::SolverGeometryExtension::getClassTypeId()).lock());
geom->getExtension(Sketcher::SolverGeometryExtension::getClassTypeId()).lock());
return (solvext->getGeometry() == Sketcher::SolverGeometryExtension::FullyConstraint);
return (solvext->getGeometry()
== Sketcher::SolverGeometryExtension::FullyConstraint);
}
}
return false;
@@ -156,30 +156,33 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
// Update Colors
SbColor *crosscolor = editModeScenegraphNodes.RootCrossMaterials->diffuseColor.startEditing();
auto viewOrientationFactor = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider);
SbColor* crosscolor = editModeScenegraphNodes.RootCrossMaterials->diffuseColor.startEditing();
auto viewOrientationFactor =
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider);
for(auto l=0; l<geometryLayerParameters.getCoinLayerCount(); l++) {
for (auto l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
int PtNum = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.getNum();
SbColor *pcolor = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.startEditing();
SbColor* pcolor = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.startEditing();
int CurvNum = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.getNum();
SbColor *color = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.startEditing();
SbColor* color = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.startEditing();
SbVec3f *verts = editModeScenegraphNodes.CurvesCoordinate[l]->point.startEditing();
SbVec3f *pverts = editModeScenegraphNodes.PointsCoordinate[l]->point.startEditing();
SbVec3f* verts = editModeScenegraphNodes.CurvesCoordinate[l]->point.startEditing();
SbVec3f* pverts = editModeScenegraphNodes.PointsCoordinate[l]->point.startEditing();
float x,y,z;
float x, y, z;
// colors of the point set
if( issketchinvalid ) {
for (int i=0; i < PtNum; i++)
if (issketchinvalid) {
for (int i = 0; i < PtNum; i++)
pcolor[i] = drawingParameters.InvalidSketchColor;
}
else {
for (int i=0; i < PtNum; i++) {
if ( !(i == 0 && l == 0) && ViewProviderSketchCoinAttorney::isSketchFullyConstrained(viewProvider)) {// root point is not coloured
for (int i = 0; i < PtNum; i++) {
if (!(i == 0 && l == 0)
&& ViewProviderSketchCoinAttorney::isSketchFullyConstrained(
viewProvider)) {// root point is not coloured
pcolor[i] = drawingParameters.FullyConstrainedColor;
}
else {
@@ -187,21 +190,21 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
bool constrainedElement = isFullyConstraintElement(GeoId);
if(isInternalAlignedGeom(GeoId)) {
if(constrainedElement)
if (isInternalAlignedGeom(GeoId)) {
if (constrainedElement)
pcolor[i] = drawingParameters.FullyConstraintInternalAlignmentColor;
else
pcolor[i] = drawingParameters.InternalAlignedGeoColor;
}
else {
if(!isDefinedGeomPoint(GeoId)) {
if(constrainedElement)
if (!isDefinedGeomPoint(GeoId)) {
if (constrainedElement)
pcolor[i] = drawingParameters.FullyConstraintConstructionPointColor;
else
pcolor[i] = drawingParameters.VertexColor;
}
else { // this is a defined GeomPoint
if(constrainedElement)
else {// this is a defined GeomPoint
if (constrainedElement)
pcolor[i] = drawingParameters.FullyConstraintElementColor;
else
pcolor[i] = drawingParameters.CurveColor;
@@ -213,38 +216,42 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
// update rendering height of points
auto getRenderHeight = [this](DrawingParameters::GeometryRendering renderingtype, float toprendering, float midrendering, float lowrendering) {
if(drawingParameters.topRenderingGeometry == renderingtype)
auto getRenderHeight = [this](DrawingParameters::GeometryRendering renderingtype,
float toprendering,
float midrendering,
float lowrendering) {
if (drawingParameters.topRenderingGeometry == renderingtype)
return toprendering;
else if(drawingParameters.midRenderingGeometry == renderingtype)
else if (drawingParameters.midRenderingGeometry == renderingtype)
return midrendering;
else
return lowrendering;
};
float zNormPoint = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry,
drawingParameters.zHighPoints,
drawingParameters.zLowPoints,
drawingParameters.zLowPoints);
drawingParameters.zHighPoints,
drawingParameters.zLowPoints,
drawingParameters.zLowPoints);
float zConstrPoint = getRenderHeight(DrawingParameters::GeometryRendering::Construction,
drawingParameters.zHighPoints,
drawingParameters.zLowPoints,
drawingParameters.zLowPoints);
drawingParameters.zHighPoints,
drawingParameters.zLowPoints,
drawingParameters.zLowPoints);
for (int i=0; i < PtNum; i++) { // 0 is the origin
if( i == 0 && l == 0 ) { // reset root point to lowest
for (int i = 0; i < PtNum; i++) {// 0 is the origin
if (i == 0 && l == 0) { // reset root point to lowest
pverts[i].setValue(0, 0, viewOrientationFactor * drawingParameters.zRootPoint);
}
else {
pverts[i].getValue(x,y,z);
auto geom = geolistfacade.getGeometryFacadeFromGeoId(coinMapping.getPointGeoId(i, l));
pverts[i].getValue(x, y, z);
auto geom =
geolistfacade.getGeometryFacadeFromGeoId(coinMapping.getPointGeoId(i, l));
if(geom) {
if(geom->getConstruction())
pverts[i].setValue(x,y,viewOrientationFactor * zConstrPoint);
if (geom) {
if (geom->getConstruction())
pverts[i].setValue(x, y, viewOrientationFactor * zConstrPoint);
else
pverts[i].setValue(x,y,viewOrientationFactor * zNormPoint);
pverts[i].setValue(x, y, viewOrientationFactor * zNormPoint);
}
}
}
@@ -253,7 +260,7 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
auto preselectcross = ViewProviderSketchCoinAttorney::getPreselectCross(viewProvider);
auto preselectcurve = ViewProviderSketchCoinAttorney::getPreselectCurve(viewProvider);
auto raisePoint = [](SbVec3f & point, float height) {
auto raisePoint = [](SbVec3f& point, float height) {
float x, y, z;
point.getValue(x, y, z);
point.setValue(x, y, height);
@@ -261,15 +268,14 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
MultiFieldId preselectpointmfid;
if ( preselectcross == 0) {
if(l == 0) // cross only in layer 0
if (preselectcross == 0) {
if (l == 0)// cross only in layer 0
pcolor[0] = drawingParameters.PreselectColor;
}
else if (preselectpoint != -1) {
preselectpointmfid = coinMapping.getIndexLayer(preselectpoint);
if (MultiFieldId::Invalid != preselectpointmfid &&
preselectpointmfid.layerId == l &&
preselectpointmfid.fieldIndex < PtNum) {
if (MultiFieldId::Invalid != preselectpointmfid && preselectpointmfid.layerId == l
&& preselectpointmfid.fieldIndex < PtNum) {
pcolor[preselectpointmfid.fieldIndex] = drawingParameters.PreselectColor;
@@ -277,12 +283,22 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
}
}
ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(viewProvider,
[pcolor, pverts, PtNum, preselectpointmfid, layerId = l, &coinMapping = coinMapping, drawingParameters = this->drawingParameters, raisePoint](const int i) {
ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(
viewProvider,
[pcolor,
pverts,
PtNum,
preselectpointmfid,
layerId = l,
&coinMapping = coinMapping,
drawingParameters = this->drawingParameters,
raisePoint](const int i) {
auto pointindex = coinMapping.getIndexLayer(i);
if (layerId == pointindex.layerId && pointindex.fieldIndex >= 0 && pointindex.fieldIndex < PtNum) {
if (layerId == pointindex.layerId && pointindex.fieldIndex >= 0
&& pointindex.fieldIndex < PtNum) {
pcolor[pointindex.fieldIndex] = (preselectpointmfid == pointindex)
? drawingParameters.PreselectSelectedColor : drawingParameters.SelectColor;
? drawingParameters.PreselectSelectedColor
: drawingParameters.SelectColor;
raisePoint(pverts[pointindex.fieldIndex], drawingParameters.zHighlight);
}
@@ -291,26 +307,26 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
// update colors and rendering height of the curves
float zNormLine = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry,
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
float zConstrLine = getRenderHeight(DrawingParameters::GeometryRendering::Construction,
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
float zExtLine = getRenderHeight(DrawingParameters::GeometryRendering::ExternalGeometry,
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
drawingParameters.zHighLines,
drawingParameters.zMidLines,
drawingParameters.zLowLines);
int j=0; // vertexindex
int j = 0;// vertexindex
for (int i=0; i < CurvNum; i++) {
for (int i = 0; i < CurvNum; i++) {
int GeoId = coinMapping.getCurveGeoId(i, l);
// CurvId has several vertices associated to 1 material
//edit->CurveSet->numVertices => [i] indicates number of vertex for line i.
// edit->CurveSet->numVertices => [i] indicates number of vertex for line i.
int indexes = (editModeScenegraphNodes.CurveSet[l]->numVertices[i]);
bool selected = ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, GeoId);
@@ -320,94 +336,96 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geol
if (selected && preselected) {
color[i] = drawingParameters.PreselectSelectedColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * drawingParameters.zHighLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * drawingParameters.zHighLine);
}
}
else if (selected){
else if (selected) {
color[i] = drawingParameters.SelectColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * drawingParameters.zHighLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * drawingParameters.zHighLine);
}
}
else if (preselected){
else if (preselected) {
color[i] = drawingParameters.PreselectColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * drawingParameters.zHighLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * drawingParameters.zHighLine);
}
}
else if (GeoId <= Sketcher::GeoEnum::RefExt) { // external Geometry
else if (GeoId <= Sketcher::GeoEnum::RefExt) {// external Geometry
color[i] = drawingParameters.CurveExternalColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zExtLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zExtLine);
}
}
else if ( issketchinvalid ) {
else if (issketchinvalid) {
color[i] = drawingParameters.InvalidSketchColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zNormLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zNormLine);
}
}
else if (isConstructionGeom(GeoId)) {
if(isInternalAlignedGeom(GeoId)) {
if(constrainedElement)
if (isInternalAlignedGeom(GeoId)) {
if (constrainedElement)
color[i] = drawingParameters.FullyConstraintInternalAlignmentColor;
else
color[i] = drawingParameters.InternalAlignedGeoColor;
}
else {
if(constrainedElement)
if (constrainedElement)
color[i] = drawingParameters.FullyConstraintConstructionElementColor;
else
color[i] = drawingParameters.CurveDraftColor;
}
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zConstrLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zConstrLine);
}
}
else if (ViewProviderSketchCoinAttorney::isSketchFullyConstrained(viewProvider)) {
color[i] = drawingParameters.FullyConstrainedColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zNormLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zNormLine);
}
}
else if (isFullyConstraintElement(GeoId)) {
color[i] = drawingParameters.FullyConstraintElementColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zNormLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zNormLine);
}
}
else {
color[i] = drawingParameters.CurveColor;
for (int k=j; j<k+indexes; j++) {
verts[j].getValue(x,y,z);
verts[j] = SbVec3f(x,y,viewOrientationFactor * zNormLine);
for (int k = j; j < k + indexes; j++) {
verts[j].getValue(x, y, z);
verts[j] = SbVec3f(x, y, viewOrientationFactor * zNormLine);
}
}
}
// colors of the cross
if ( l == 0 ) { // only in layer 0
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, Sketcher::GeoEnum::HAxis)) {
crosscolor[0] = drawingParameters.SelectColor;
if (l == 0) {// only in layer 0
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider,
Sketcher::GeoEnum::HAxis)) {
crosscolor[0] = drawingParameters.SelectColor;
}
else if (preselectcross == 1) { // cross only in layer 0
crosscolor[0] = drawingParameters.PreselectColor;
else if (preselectcross == 1) {// cross only in layer 0
crosscolor[0] = drawingParameters.PreselectColor;
}
else {
crosscolor[0] = drawingParameters.CrossColorH;
crosscolor[0] = drawingParameters.CrossColorH;
}
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, Sketcher::GeoEnum::VAxis)) {
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider,
Sketcher::GeoEnum::VAxis)) {
crosscolor[1] = drawingParameters.SelectColor;
}
else if (preselectcross == 2) {
@@ -442,9 +460,9 @@ void EditModeGeometryCoinManager::updateGeometryLayersConfiguration()
createEditModeCurveInventorNodes();
}
auto concat (std::string string, int i)
auto concat(std::string string, int i)
{
return string+std::to_string(i);
return string + std::to_string(i);
};
@@ -468,7 +486,6 @@ void EditModeGeometryCoinManager::createGeometryRootNodes()
// stuff for the Curves +++++++++++++++++++++++++++++++++++++++
editModeScenegraphNodes.CurvesGroup = new SmSwitchboard;
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.CurvesGroup);
}
void EditModeGeometryCoinManager::emptyGeometryRootNodes()
@@ -479,35 +496,38 @@ void EditModeGeometryCoinManager::emptyGeometryRootNodes()
void EditModeGeometryCoinManager::createEditModePointInventorNodes()
{
for(int i=0; i < geometryLayerParameters.getCoinLayerCount(); i++) {
SoSeparator * sep = new SoSeparator;
for (int i = 0; i < geometryLayerParameters.getCoinLayerCount(); i++) {
SoSeparator* sep = new SoSeparator;
sep->ref();
auto somaterial = new SoMaterial;
editModeScenegraphNodes.PointsMaterials.push_back(somaterial);
editModeScenegraphNodes.PointsMaterials[i]->setName(concat("PointsMaterials_",i).c_str());
editModeScenegraphNodes.PointsMaterials[i]->setName(concat("PointsMaterials_", i).c_str());
sep->addChild(editModeScenegraphNodes.PointsMaterials[i]);
SoMaterialBinding *MtlBind = new SoMaterialBinding;
MtlBind->setName(concat("PointsMaterialBinding",i).c_str());
SoMaterialBinding* MtlBind = new SoMaterialBinding;
MtlBind->setName(concat("PointsMaterialBinding", i).c_str());
MtlBind->value = SoMaterialBinding::PER_VERTEX;
sep->addChild(MtlBind);
auto coords = new SoCoordinate3;
editModeScenegraphNodes.PointsCoordinate.push_back(coords);
editModeScenegraphNodes.PointsCoordinate[i]->setName(concat("PointsCoordinate",i).c_str());
editModeScenegraphNodes.PointsCoordinate[i]->setName(concat("PointsCoordinate", i).c_str());
sep->addChild(editModeScenegraphNodes.PointsCoordinate[i]);
auto drawstyle = new SoDrawStyle;
editModeScenegraphNodes.PointsDrawStyle.push_back(drawstyle);
editModeScenegraphNodes.PointsDrawStyle[i]->setName(concat("PointsDrawStyle",i).c_str());
editModeScenegraphNodes.PointsDrawStyle[i]->pointSize = 8 * drawingParameters.pixelScalingFactor;
editModeScenegraphNodes.PointsDrawStyle[i]->setName(concat("PointsDrawStyle", i).c_str());
editModeScenegraphNodes.PointsDrawStyle[i]->pointSize =
8 * drawingParameters.pixelScalingFactor;
sep->addChild(editModeScenegraphNodes.PointsDrawStyle[i]);
auto pointset = new SoMarkerSet;
editModeScenegraphNodes.PointSet.push_back(pointset);
editModeScenegraphNodes.PointSet[i]->setName(concat("PointSet",i).c_str());
editModeScenegraphNodes.PointSet[i]->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize);
editModeScenegraphNodes.PointSet[i]->setName(concat("PointSet", i).c_str());
editModeScenegraphNodes.PointSet[i]->markerIndex =
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED",
drawingParameters.markerSize);
sep->addChild(editModeScenegraphNodes.PointSet[i]);
editModeScenegraphNodes.PointsGroup->addChild(sep);
@@ -519,38 +539,40 @@ void EditModeGeometryCoinManager::createEditModeCurveInventorNodes()
{
auto layersconfigurations = viewProvider.VisualLayerList.getValue();
for(int i=0; i < geometryLayerParameters.getCoinLayerCount(); i++) {
SoSeparator * sep = new SoSeparator;
for (int i = 0; i < geometryLayerParameters.getCoinLayerCount(); i++) {
SoSeparator* sep = new SoSeparator;
sep->ref();
auto somaterial = new SoMaterial;
editModeScenegraphNodes.CurvesMaterials.push_back(somaterial);
editModeScenegraphNodes.CurvesMaterials[i]->setName(concat("CurvesMaterials",i).c_str());
editModeScenegraphNodes.CurvesMaterials[i]->setName(concat("CurvesMaterials", i).c_str());
sep->addChild(editModeScenegraphNodes.CurvesMaterials[i]);
auto MtlBind = new SoMaterialBinding;
MtlBind->setName(concat("CurvesMaterialsBinding",i).c_str());
MtlBind->setName(concat("CurvesMaterialsBinding", i).c_str());
MtlBind->value = SoMaterialBinding::PER_FACE;
sep->addChild(MtlBind);
auto coords = new SoCoordinate3;
editModeScenegraphNodes.CurvesCoordinate.push_back(coords);
editModeScenegraphNodes.CurvesCoordinate[i]->setName(concat("CurvesCoordinate",i).c_str());
editModeScenegraphNodes.CurvesCoordinate[i]->setName(concat("CurvesCoordinate", i).c_str());
sep->addChild(editModeScenegraphNodes.CurvesCoordinate[i]);
auto drawstyle = new SoDrawStyle;
editModeScenegraphNodes.CurvesDrawStyle.push_back(drawstyle);
editModeScenegraphNodes.CurvesDrawStyle[i]->setName(concat("CurvesDrawStyle",i).c_str());
editModeScenegraphNodes.CurvesDrawStyle[i]->setName(concat("CurvesDrawStyle", i).c_str());
editModeScenegraphNodes.CurvesDrawStyle[i]->lineWidth = layersconfigurations[i].getLineWidth() * drawingParameters.pixelScalingFactor;
editModeScenegraphNodes.CurvesDrawStyle[i]->linePattern = layersconfigurations[i].getLinePattern();
editModeScenegraphNodes.CurvesDrawStyle[i]->lineWidth =
layersconfigurations[i].getLineWidth() * drawingParameters.pixelScalingFactor;
editModeScenegraphNodes.CurvesDrawStyle[i]->linePattern =
layersconfigurations[i].getLinePattern();
editModeScenegraphNodes.CurvesDrawStyle[i]->linePatternScaleFactor = 5;
sep->addChild(editModeScenegraphNodes.CurvesDrawStyle[i]);
auto solineset = new SoLineSet;
editModeScenegraphNodes.CurveSet.push_back(solineset);
editModeScenegraphNodes.CurveSet[i]->setName(concat("CurvesLineSet",i).c_str());
editModeScenegraphNodes.CurveSet[i]->setName(concat("CurvesLineSet", i).c_str());
sep->addChild(editModeScenegraphNodes.CurveSet[i]);
editModeScenegraphNodes.CurvesGroup->addChild(sep);
@@ -36,25 +36,29 @@ class SoRayPickAction;
class SoPickedPoint;
class SbVec3s;
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
class Placement;
class Placement;
}// namespace Base
namespace Part
{
class Geometry;
}
namespace Part {
class Geometry;
}
namespace Sketcher
{
class Constraint;
class PropertyConstraintList;
};// namespace Sketcher
namespace Sketcher {
class Constraint;
class PropertyConstraintList;
};
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class EditModeConstraintCoinManager;
@@ -62,10 +66,12 @@ class EditModeConstraintCoinManager;
using GeoList = Sketcher::GeoList;
using GeoListFacade = Sketcher::GeoListFacade;
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to geometry.
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to
* geometry.
* @details
*
* EditModeGeometryCoinManager is a helper of EditModeCoinManager specialised in geometry management.
* EditModeGeometryCoinManager is a helper of EditModeCoinManager specialised in geometry
* management.
*
* Three main functions are delegated to it:
* 1. Creation of Edit mode coin nodes to handle Geometry representation.
@@ -80,19 +86,18 @@ class SketcherGuiExport EditModeGeometryCoinManager
{
public:
explicit EditModeGeometryCoinManager( ViewProviderSketch &vp,
DrawingParameters & drawingParams,
GeometryLayerParameters & geometryLayerParams,
AnalysisResults & analysisResultStruct,
EditModeScenegraphNodes & editModeScenegraph,
CoinMapping & coinMap);
explicit EditModeGeometryCoinManager(ViewProviderSketch& vp, DrawingParameters& drawingParams,
GeometryLayerParameters& geometryLayerParams,
AnalysisResults& analysisResultStruct,
EditModeScenegraphNodes& editModeScenegraph,
CoinMapping& coinMap);
~EditModeGeometryCoinManager();
// This function populates the coin nodes with the information of the current geometry
void processGeometry(const GeoListFacade & geolistfacade);
void processGeometry(const GeoListFacade& geolistfacade);
void updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid);
void updateGeometryColor(const GeoListFacade& geolistfacade, bool issketchinvalid);
void updateGeometryLayersConfiguration();
@@ -107,21 +112,19 @@ private:
void createEditModeCurveInventorNodes();
private:
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
DrawingParameters & drawingParameters;
GeometryLayerParameters & geometryLayerParameters;
AnalysisResults & analysisResults;
DrawingParameters& drawingParameters;
GeometryLayerParameters& geometryLayerParameters;
AnalysisResults& analysisResults;
EditModeScenegraphNodes & editModeScenegraphNodes;
CoinMapping & coinMapping;
EditModeScenegraphNodes& editModeScenegraphNodes;
CoinMapping& coinMapping;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_EditModeGeometryCoinManager_H
#endif// SKETCHERGUI_EditModeGeometryCoinManager_H
@@ -22,43 +22,43 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoFont.h>
# include <Inventor/nodes/SoGroup.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoSwitch.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
#endif // #ifndef _PreComp_
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#include <Inventor/nodes/SoText2.h>
#include <Inventor/nodes/SoTranslation.h>
#endif// #ifndef _PreComp_
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/UnitsApi.h>
#include "EditModeInformationOverlayCoinConverter.h"
#include "EditModeCoinManagerParameters.h"
#include "EditModeInformationOverlayCoinConverter.h"
#include "ViewProviderSketchCoinAttorney.h"
using namespace SketcherGui;
EditModeInformationOverlayCoinConverter::EditModeInformationOverlayCoinConverter(
ViewProviderSketch & vp,
SoGroup * infogroup,
OverlayParameters & overlayparameters,
DrawingParameters & drawingparameters): viewProvider(vp),
infoGroup(infogroup),
overlayParameters(overlayparameters),
drawingParameters(drawingparameters),
nodeId(0){
ViewProviderSketch& vp, SoGroup* infogroup, OverlayParameters& overlayparameters,
DrawingParameters& drawingparameters)
: viewProvider(vp)
, infoGroup(infogroup)
, overlayParameters(overlayparameters)
, drawingParameters(drawingparameters)
, nodeId(0) {
};
};
void EditModeInformationOverlayCoinConverter::convert(const Part::Geometry * geometry, int geoid) {
void EditModeInformationOverlayCoinConverter::convert(const Part::Geometry* geometry, int geoid)
{
if (geometry->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()){
if (geometry->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
// at this point all calculations relate to BSplineCurves
calculate<CalculationType::BSplineDegree>(geometry, geoid);
calculate<CalculationType::BSplineControlPolygon>(geometry, geoid);
@@ -71,23 +71,27 @@ void EditModeInformationOverlayCoinConverter::convert(const Part::Geometry * geo
addUpdateNode(curvatureComb);
addUpdateNode(knotMultiplicity);
addUpdateNode(poleWeights);
} else if (geometry->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){
}
else if (geometry->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
// at this point all calculations relate to ArcOfCircle
calculate<CalculationType::ArcCircleHelper>(geometry, geoid);
addUpdateNode(circleHelper);
}
}
void EditModeInformationOverlayCoinConverter::addToInfoGroup(SoSwitch * sw) {
void EditModeInformationOverlayCoinConverter::addToInfoGroup(SoSwitch* sw)
{
infoGroup->addChild(sw);
nodeId++;
}
template < EditModeInformationOverlayCoinConverter::CalculationType calculation >
void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * geometry, [[maybe_unused]] int geoid) {
template<EditModeInformationOverlayCoinConverter::CalculationType calculation>
void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry* geometry,
[[maybe_unused]] int geoid)
{
if constexpr (calculation == CalculationType::ArcCircleHelper ) {
const Part::GeomArcOfCircle *arc = static_cast<const Part::GeomArcOfCircle *>(geometry);
if constexpr (calculation == CalculationType::ArcCircleHelper) {
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>(geometry);
clearCalculation(circleHelper);
Base::Vector3d center = arc->getCenter();
@@ -100,15 +104,16 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
circleHelper.coordinates.reserve(ndiv);
for (int i = 0; i < ndiv; i++) {
double param = i * std::atan(1) * 8 / ndiv;
circleHelper.coordinates.emplace_back(circle.value(param));
double param = i * std::atan(1) * 8 / ndiv;
circleHelper.coordinates.emplace_back(circle.value(param));
}
circleHelper.coordinates.emplace_back(circle.value(0.0));
circleHelper.coordinates.emplace_back(circle.value(0.0));
circleHelper.indices.push_back(ndiv + 1);
} else {
const Part::GeomBSplineCurve *spline = static_cast<const Part::GeomBSplineCurve *>(geometry);
}
else {
const Part::GeomBSplineCurve* spline = static_cast<const Part::GeomBSplineCurve*>(geometry);
if constexpr (calculation == CalculationType::BSplineDegree ) {
if constexpr (calculation == CalculationType::BSplineDegree) {
clearCalculation(degree);
std::vector<Base::Vector3d> poles = spline->getPoles();
@@ -116,7 +121,7 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
degree.strings.clear();
degree.positions.clear();
Base::Vector3d midp = Base::Vector3d(0,0,0);
Base::Vector3d midp = Base::Vector3d(0, 0, 0);
for (auto val : poles)
midp += val;
@@ -126,7 +131,7 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
degree.strings.emplace_back(std::to_string(spline->getDegree()));
degree.positions.emplace_back(midp);
}
else if constexpr (calculation == CalculationType::BSplineControlPolygon ) {
else if constexpr (calculation == CalculationType::BSplineControlPolygon) {
clearCalculation(controlPolygon);
@@ -138,21 +143,22 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
size_t nvertices;
if (spline->isPeriodic())
nvertices = poles.size()+1;
nvertices = poles.size() + 1;
else
nvertices = poles.size();
controlPolygon.coordinates.reserve(nvertices);
for (auto & v : poles)
for (auto& v : poles)
controlPolygon.coordinates.emplace_back(v);
if (spline->isPeriodic())
controlPolygon.coordinates.emplace_back(poles[0]);
controlPolygon.indices.push_back(nvertices); // single continuous polygon starting at index 0
controlPolygon.indices.push_back(
nvertices);// single continuous polygon starting at index 0
}
else if constexpr (calculation == CalculationType::BSplineCurvatureComb ) {
else if constexpr (calculation == CalculationType::BSplineCurvatureComb) {
clearCalculation(curvatureComb);
// curvature graph --------------------------------------------------------
@@ -165,7 +171,7 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
auto knots = spline->getKnots();
auto mults = spline->getMultiplicities();
const int ndivPerPiece = 64; // heuristic of number of division to fill in
const int ndivPerPiece = 64;// heuristic of number of division to fill in
const int ndiv = ndivPerPiece * (knots.size() - 1);
std::vector<Base::Vector3d> pointatcurvelist;
@@ -177,10 +183,13 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
normallist.reserve(ndiv);
// go through the polynomial pieces (i.e. from one knot to next)
for (size_t k = 0; k < knots.size()-1; ++k) {
// first and last params are a little off to account for possible discontinuity at knots
double firstparam = knots[k] + Precision::Approximation()*(knots[k + 1] - knots[k]);
double lastparam = knots[k + 1] - Precision::Approximation()*(knots[k + 1] - knots[k]);
for (size_t k = 0; k < knots.size() - 1; ++k) {
// first and last params are a little off to account for possible discontinuity at
// knots
double firstparam =
knots[k] + Precision::Approximation() * (knots[k + 1] - knots[k]);
double lastparam =
knots[k + 1] - Precision::Approximation() * (knots[k + 1] - knots[k]);
// TODO: Maybe this can be improved, specifically adapted for each piece
double step = (lastparam - firstparam) / (ndivPerPiece - 1);
@@ -192,12 +201,15 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
try {
curvaturelist.emplace_back(spline->curvatureAt(param));
}
catch(Base::CADKernelError &e) {
catch (Base::CADKernelError& e) {
// it is "just" a visualisation matter OCC could not calculate the curvature
// terminating here would mean that the other shapes would not be drawn.
// Solution: Report the issue and set dummy curvature to 0
e.ReportException();
Base::Console().DeveloperError("EditModeInformationOverlayCoinConverter","Curvature graph for B-Spline with GeoId=%d could not be calculated.\n", geoid);
Base::Console().DeveloperError(
"EditModeInformationOverlayCoinConverter",
"Curvature graph for B-Spline with GeoId=%d could not be calculated.\n",
geoid);
curvaturelist.emplace_back(0);
}
@@ -206,8 +218,8 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
spline->normalAt(param, normal);
normallist.emplace_back(normal);
}
catch(Base::Exception&) {
normallist.emplace_back(0,0,0);
catch (Base::Exception&) {
normallist.emplace_back(0, 0, 0);
}
}
}
@@ -216,52 +228,64 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
pointatcomblist.reserve(ndiv);
for (int i = 0; i < ndiv; i++) {
pointatcomblist.emplace_back(pointatcurvelist[i] - overlayParameters.currentBSplineCombRepresentationScale * curvaturelist[i] * normallist[i]);
pointatcomblist.emplace_back(
pointatcurvelist[i]
- overlayParameters.currentBSplineCombRepresentationScale * curvaturelist[i]
* normallist[i]);
}
curvatureComb.coordinates.reserve(3*ndiv); // 2*ndiv +1 points of ndiv separate segments + ndiv points for last segment
curvatureComb.indices.reserve(ndiv+1); // ndiv separate segments of radials + 1 segment connecting at comb end
curvatureComb.coordinates.reserve(
3
* ndiv);// 2*ndiv +1 points of ndiv separate segments + ndiv points for last segment
curvatureComb.indices.reserve(
ndiv + 1);// ndiv separate segments of radials + 1 segment connecting at comb end
auto zInfoH = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zInfo;
auto zInfoH = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zInfo;
for (int i = 0; i < ndiv; i++) {
// note emplace emplaces on the position BEFORE the iterator given.
curvatureComb.coordinates.emplace_back(pointatcurvelist[i].x, pointatcurvelist[i].y, zInfoH); // radials
curvatureComb.coordinates.emplace_back(pointatcomblist[i].x, pointatcomblist[i].y, zInfoH); // radials
curvatureComb.coordinates.emplace_back(
pointatcurvelist[i].x, pointatcurvelist[i].y, zInfoH);// radials
curvatureComb.coordinates.emplace_back(
pointatcomblist[i].x, pointatcomblist[i].y, zInfoH);// radials
curvatureComb.indices.emplace_back(2); // line
curvatureComb.indices.emplace_back(2);// line
}
for (int i = 0; i < ndiv; i++)
curvatureComb.coordinates.emplace_back(pointatcomblist[i].x, pointatcomblist[i].y, zInfoH); // // comb endpoint closing segment
curvatureComb.coordinates.emplace_back(pointatcomblist[i].x,
pointatcomblist[i].y,
zInfoH);// // comb endpoint closing segment
curvatureComb.indices.emplace_back(ndiv); // Comb line
curvatureComb.indices.emplace_back(ndiv);// Comb line
}
else if constexpr (calculation == CalculationType::BSplineKnotMultiplicity ) {
else if constexpr (calculation == CalculationType::BSplineKnotMultiplicity) {
clearCalculation(knotMultiplicity);
std::vector<double> knots = spline->getKnots();
std::vector<int> mult = spline->getMultiplicities();
for (size_t i=0; i<knots.size(); i++) {
for (size_t i = 0; i < knots.size(); i++) {
knotMultiplicity.positions.emplace_back(spline->pointAtParameter(knots[i]));
std::ostringstream stringStream;
stringStream << "(" << mult[i] << ")";
knotMultiplicity.strings.emplace_back( stringStream.str());
knotMultiplicity.strings.emplace_back(stringStream.str());
}
}
else if constexpr (calculation == CalculationType::BSplinePoleWeight ) {
else if constexpr (calculation == CalculationType::BSplinePoleWeight) {
clearCalculation(poleWeights);
std::vector<Base::Vector3d> poles = spline->getPoles();
auto weights = spline->getWeights();
for (size_t i=0; i<poles.size(); i++) {
for (size_t i = 0; i < poles.size(); i++) {
poleWeights.positions.emplace_back(poles[i]);
QString WeightString = QString::fromLatin1("[%1]").arg(weights[i], 0, 'f', Base::UnitsApi::getDecimals());
QString WeightString = QString::fromLatin1("[%1]").arg(
weights[i], 0, 'f', Base::UnitsApi::getDecimals());
poleWeights.strings.emplace_back(WeightString.toStdString());
}
@@ -269,8 +293,9 @@ void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * g
}
}
template <typename Result>
void EditModeInformationOverlayCoinConverter::addUpdateNode(const Result & result) {
template<typename Result>
void EditModeInformationOverlayCoinConverter::addUpdateNode(const Result& result)
{
if (overlayParameters.rebuildInformationLayer)
addNode(result);
@@ -278,40 +303,46 @@ void EditModeInformationOverlayCoinConverter::addUpdateNode(const Result & resul
updateNode(result);
}
template < EditModeInformationOverlayCoinConverter::CalculationType calculation >
bool EditModeInformationOverlayCoinConverter::isVisible() {
if constexpr ( calculation == CalculationType::BSplineDegree ) {
template<EditModeInformationOverlayCoinConverter::CalculationType calculation>
bool EditModeInformationOverlayCoinConverter::isVisible()
{
if constexpr (calculation == CalculationType::BSplineDegree) {
return overlayParameters.bSplineDegreeVisible;
}
else if constexpr ( calculation == CalculationType::BSplineControlPolygon ) {
else if constexpr (calculation == CalculationType::BSplineControlPolygon) {
return overlayParameters.bSplineControlPolygonVisible;
}
else if constexpr ( calculation == CalculationType::BSplineCurvatureComb ) {
else if constexpr (calculation == CalculationType::BSplineCurvatureComb) {
return overlayParameters.bSplineCombVisible;
}
else if constexpr ( calculation == CalculationType::BSplineKnotMultiplicity ) {
else if constexpr (calculation == CalculationType::BSplineKnotMultiplicity) {
return overlayParameters.bSplineKnotMultiplicityVisible;
}
else if constexpr ( calculation == CalculationType::BSplinePoleWeight ) {
else if constexpr (calculation == CalculationType::BSplinePoleWeight) {
return overlayParameters.bSplinePoleWeightVisible;
}
else if constexpr ( calculation == CalculationType::ArcCircleHelper ) {
else if constexpr (calculation == CalculationType::ArcCircleHelper) {
return overlayParameters.arcCircleHelperVisible;
}
}
template < typename Result >
void EditModeInformationOverlayCoinConverter::setPolygon(const Result & result, SoLineSet *polygonlineset, SoCoordinate3 *polygoncoords) {
template<typename Result>
void EditModeInformationOverlayCoinConverter::setPolygon(const Result& result,
SoLineSet* polygonlineset,
SoCoordinate3* polygoncoords)
{
polygoncoords->point.setNum(result.coordinates.size());
polygonlineset->numVertices.setNum(result.indices.size());
int32_t *index = polygonlineset->numVertices.startEditing();
SbVec3f *vts = polygoncoords->point.startEditing();
int32_t* index = polygonlineset->numVertices.startEditing();
SbVec3f* vts = polygoncoords->point.startEditing();
for (size_t i = 0; i < result.coordinates.size(); i++)
vts[i].setValue(result.coordinates[i].x, result.coordinates[i].y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zInfo);
vts[i].setValue(result.coordinates[i].x,
result.coordinates[i].y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zInfo);
for (size_t i = 0; i < result.indices.size(); i++)
index[i] = result.indices[i];
@@ -320,8 +351,9 @@ void EditModeInformationOverlayCoinConverter::setPolygon(const Result & result,
polygonlineset->numVertices.finishEditing();
}
template < int line >
void EditModeInformationOverlayCoinConverter::setText(const std::string & string, SoText2 * text) {
template<int line>
void EditModeInformationOverlayCoinConverter::setText(const std::string& string, SoText2* text)
{
if constexpr (line == 1) {
text->string = SbString(string.c_str());
@@ -329,65 +361,72 @@ void EditModeInformationOverlayCoinConverter::setText(const std::string & string
else {
assert(line > 1);
SoMFString label;
for ( int l = 0; l < (line - 1) ; l++)
for (int l = 0; l < (line - 1); l++)
label.set1Value(l, SbString(""));
label.set1Value(line-1, SbString(string.c_str()));
label.set1Value(line - 1, SbString(string.c_str()));
text->string = label;
}
}
template < typename Result >
void EditModeInformationOverlayCoinConverter::clearCalculation(Result & result) {
if constexpr (Result::visualisationType == VisualisationType::Text) {
template<typename Result>
void EditModeInformationOverlayCoinConverter::clearCalculation(Result& result)
{
if constexpr (Result::visualisationType == VisualisationType::Text) {
result.positions.clear();
result.strings.clear();
}
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
}
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
result.coordinates.clear();
result.indices.clear();
}
}
}
template < typename Result>
void EditModeInformationOverlayCoinConverter::addNode(const Result & result) {
template<typename Result>
void EditModeInformationOverlayCoinConverter::addNode(const Result& result)
{
if constexpr (Result::visualisationType == VisualisationType::Text) {
for(size_t i = 0; i < result.strings.size(); i++) {
for (size_t i = 0; i < result.strings.size(); i++) {
SoSwitch *sw = new SoSwitch();
SoSwitch* sw = new SoSwitch();
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
sw->whichChild = isVisible<Result::calculationType>() ? SO_SWITCH_ALL : SO_SWITCH_NONE;
SoSeparator *sep = new SoSeparator();
SoSeparator* sep = new SoSeparator();
sep->ref();
// no caching for frequently-changing 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;
// every information visual node gets its own material for to-be-implemented
// preselection and selection
SoMaterial* mat = new SoMaterial;
mat->ref();
mat->diffuseColor = drawingParameters.InformationColor;
SoTranslation *translate = new SoTranslation;
SoTranslation* translate = new SoTranslation;
translate->translation.setValue(result.positions[i].x, result.positions[i].y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zInfo);
translate->translation.setValue(
result.positions[i].x,
result.positions[i].y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zInfo);
SoFont *font = new SoFont;
SoFont* font = new SoFont;
font->name.setValue("Helvetica");
font->size.setValue(drawingParameters.coinFontSize);
SoText2 *text = new SoText2;
SoText2* text = new SoText2;
// 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
// therefore be output the weight in a second line
// can also have a displayed multiplicity, we must assure the multiplicity is not
// visibly overwritten therefore be output the weight in a second line
//
// This could be made into a more generic form, but it is probably not worth the effort at this time.
if constexpr ( Result::calculationType == CalculationType::BSplinePoleWeight )
// This could be made into a more generic form, but it is probably not worth the effort
// at this time.
if constexpr (Result::calculationType == CalculationType::BSplinePoleWeight)
setText<2>(result.strings[i], text);
else
setText(result.strings[i], text);
@@ -406,23 +445,24 @@ void EditModeInformationOverlayCoinConverter::addNode(const Result & result) {
}
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
SoSwitch *sw = new SoSwitch();
SoSwitch* sw = new SoSwitch();
// hGrpsk->GetBool("BSplineControlPolygonVisible", true)
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
sw->whichChild = isVisible<Result::calculationType>() ? SO_SWITCH_ALL : SO_SWITCH_NONE;
SoSeparator *sep = new SoSeparator();
SoSeparator* sep = new SoSeparator();
sep->ref();
// no caching for frequently-changing 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;
// every information visual node gets its own material for to-be-implemented preselection
// and selection
SoMaterial* mat = new SoMaterial;
mat->ref();
mat->diffuseColor = drawingParameters.InformationColor;
SoLineSet *polygonlineset = new SoLineSet;
SoCoordinate3 *polygoncoords = new SoCoordinate3;
SoLineSet* polygonlineset = new SoLineSet;
SoCoordinate3* polygoncoords = new SoCoordinate3;
setPolygon<Result>(result, polygonlineset, polygoncoords);
@@ -438,47 +478,61 @@ void EditModeInformationOverlayCoinConverter::addNode(const Result & result) {
}
}
template < typename Result >
void EditModeInformationOverlayCoinConverter::updateNode(const Result & result) {
template<typename Result>
void EditModeInformationOverlayCoinConverter::updateNode(const Result& result)
{
if constexpr (Result::visualisationType == VisualisationType::Text ) {
if constexpr (Result::visualisationType == VisualisationType::Text) {
for(size_t i = 0; i < result.strings.size(); i++) {
SoSwitch *sw = static_cast<SoSwitch *>(infoGroup->getChild(nodeId));
for (size_t i = 0; i < result.strings.size(); i++) {
SoSwitch* sw = static_cast<SoSwitch*>(infoGroup->getChild(nodeId));
if (overlayParameters.visibleInformationChanged)
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
sw->whichChild =
isVisible<Result::calculationType>() ? SO_SWITCH_ALL : SO_SWITCH_NONE;
SoSeparator *sep = static_cast<SoSeparator *>(sw->getChild(0));
SoSeparator* sep = static_cast<SoSeparator*>(sw->getChild(0));
static_cast<SoTranslation *>(sep->getChild(static_cast<int>(TextNodePosition::TextCoordinates)))->translation.setValue(result.positions[i].x, result.positions[i].y, ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider) * drawingParameters.zInfo);
static_cast<SoTranslation*>(
sep->getChild(static_cast<int>(TextNodePosition::TextCoordinates)))
->translation.setValue(
result.positions[i].x,
result.positions[i].y,
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zInfo);
// 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
// therefore be output the weight in a second line
// can also have a displayed multiplicity, we must assure the multiplicity is not
// visibly overwritten therefore be output the weight in a second line
//
// This could be made into a more generic form, but it is probably not worth the effort at this time.
if constexpr ( Result::calculationType == CalculationType::BSplinePoleWeight )
setText<2>(result.strings[i], static_cast<SoText2 *>(sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
// This could be made into a more generic form, but it is probably not worth the effort
// at this time.
if constexpr (Result::calculationType == CalculationType::BSplinePoleWeight)
setText<2>(result.strings[i],
static_cast<SoText2*>(
sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
else
setText(result.strings[i], static_cast<SoText2 *>(sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
setText(result.strings[i],
static_cast<SoText2*>(
sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
nodeId++;
}
}
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
SoSwitch *sw = static_cast<SoSwitch *>(infoGroup->getChild(nodeId));
SoSwitch* sw = static_cast<SoSwitch*>(infoGroup->getChild(nodeId));
if(overlayParameters.visibleInformationChanged)
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
if (overlayParameters.visibleInformationChanged)
sw->whichChild = isVisible<Result::calculationType>() ? SO_SWITCH_ALL : SO_SWITCH_NONE;
SoSeparator *sep = static_cast<SoSeparator *>(sw->getChild(0));
SoSeparator* sep = static_cast<SoSeparator*>(sw->getChild(0));
SoCoordinate3 *polygoncoords = static_cast<SoCoordinate3 *>(sep->getChild(static_cast<int>(PolygonNodePosition::PolygonCoordinates)));
SoCoordinate3* polygoncoords = static_cast<SoCoordinate3*>(
sep->getChild(static_cast<int>(PolygonNodePosition::PolygonCoordinates)));
SoLineSet *polygonlineset = static_cast<SoLineSet *>(sep->getChild(static_cast<int>(PolygonNodePosition::PolygonLineSet)));
SoLineSet* polygonlineset = static_cast<SoLineSet*>(
sep->getChild(static_cast<int>(PolygonNodePosition::PolygonLineSet)));
setPolygon(result, polygonlineset, polygoncoords);
@@ -28,21 +28,24 @@
#include "ViewProviderSketch.h"
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
}// namespace Base
namespace Part
{
class Geometry;
}
namespace Part {
class Geometry;
}
namespace SketcherGui {
class ViewProviderSketch;
struct OverlayParameters;
struct DrawingParameters;
namespace SketcherGui
{
class ViewProviderSketch;
struct OverlayParameters;
struct DrawingParameters;
/** @brief Class for creating the Overlay information layer
* @details
@@ -57,24 +60,27 @@ namespace SketcherGui {
*
* [Geometry] => Calculate => addUpdateNode
*
* Calculate is responsible for generating information directly usable by Coin (but with standard types that
* would enable portability) in a predetermined internal Node structure format (e.g. StringNode, PolygonNode)
* that can generically be used by the addUpdateNode.
* Calculate is responsible for generating information directly usable by Coin (but with standard
* types that would enable portability) in a predetermined internal Node structure format (e.g.
* StringNode, PolygonNode) that can generically be used by the addUpdateNode.
*
* addUpdateNode is responsible for creating or updating the node structure (depending on overlayParameters.rebuildInformationLayer)
* addUpdateNode is responsible for creating or updating the node structure (depending on
* overlayParameters.rebuildInformationLayer)
*
* Supported:
* Currently it only supports information of Part::Geometry objects and implements calculations only for GeomBSplineCurve and GeomArc.
* Currently it only supports information of Part::Geometry objects and implements calculations only
* for GeomBSplineCurve and GeomArc.
*
* Caveats:
* - This class relies on the order of creation to perform the update. Any parallel execution that does not deterministically
* maintain the order will result in undefined behaviour. This provides a reasonable tradeoff between complexity and the fact that
* currently the information layer is generally so small that no parallel execution would actually result in a performance gain.
* - This class relies on the order of creation to perform the update. Any parallel execution that
* does not deterministically maintain the order will result in undefined behaviour. This provides a
* reasonable tradeoff between complexity and the fact that currently the information layer is
* generally so small that no parallel execution would actually result in a performance gain.
*
*/
class EditModeInformationOverlayCoinConverter {
class EditModeInformationOverlayCoinConverter
{
private:
enum class CalculationType
{
BSplineDegree,
@@ -102,32 +108,37 @@ private:
//
// a struct Node template enables to define the VisualisationType and
// the CalculationType so that uniform treatment can be provided
template< VisualisationType vtype, CalculationType ctype >
struct Node {
template<VisualisationType vtype, CalculationType ctype>
struct Node
{
static constexpr VisualisationType visualisationType = vtype;
static constexpr CalculationType calculationType = ctype;
};
template< CalculationType ctype >
struct NodeText : public Node<VisualisationType::Text, ctype> {
template<CalculationType ctype>
struct NodeText: public Node<VisualisationType::Text, ctype>
{
std::vector<std::string> strings;
std::vector<Vector3d> positions;
};
template< CalculationType ctype >
struct NodePolygon: public Node<VisualisationType::Polygon, ctype> {
template<CalculationType ctype>
struct NodePolygon: public Node<VisualisationType::Polygon, ctype>
{
std::vector<Vector3d> coordinates;
std::vector<int> indices;
};
private:
// Node Position in the Coin Scenograph for the different types of nodes
enum class TextNodePosition {
enum class TextNodePosition
{
TextCoordinates = 0,
TextInformation = 3
};
enum class PolygonNodePosition {
enum class PolygonNodePosition
{
PolygonCoordinates = 1,
PolygonLineSet = 2
};
@@ -143,53 +154,52 @@ public:
* @param overlayparameters: Parameters for controlling the overlay
* @param drawingparameters: Parameters for drawing the overlay information
*/
EditModeInformationOverlayCoinConverter( ViewProviderSketch &vp,
SoGroup * infogroup,
OverlayParameters & overlayparameters,
DrawingParameters & drawingparameters);
EditModeInformationOverlayCoinConverter(ViewProviderSketch& vp, SoGroup* infogroup,
OverlayParameters& overlayparameters,
DrawingParameters& drawingparameters);
/**
* extracts information from the geometry and converts it into an information overlay in the
* SoGroup provided in the constructor.
*
* @param geometry: the geometry to be processed
*/
void convert(const Part::Geometry * geometry, int geoid);
* extracts information from the geometry and converts it into an information overlay in the
* SoGroup provided in the constructor.
*
* @param geometry: the geometry to be processed
*/
void convert(const Part::Geometry* geometry, int geoid);
private:
template < CalculationType calculation >
void calculate(const Part::Geometry * geometry, [[maybe_unused]] int geoid);
template<CalculationType calculation>
void calculate(const Part::Geometry* geometry, [[maybe_unused]] int geoid);
template <typename Result>
void addUpdateNode(const Result & result);
template<typename Result>
void addUpdateNode(const Result& result);
template < CalculationType calculation >
template<CalculationType calculation>
bool isVisible();
template < typename Result >
void setPolygon(const Result & result, SoLineSet *polygonlineset, SoCoordinate3 *polygoncoords);
template<typename Result>
void setPolygon(const Result& result, SoLineSet* polygonlineset, SoCoordinate3* polygoncoords);
template < int line = 1 >
void setText(const std::string & string, SoText2 * text);
template<int line = 1>
void setText(const std::string& string, SoText2* text);
void addToInfoGroup(SoSwitch * sw);
void addToInfoGroup(SoSwitch* sw);
template < typename Result >
void clearCalculation(Result & result);
template<typename Result>
void clearCalculation(Result& result);
template < typename Result>
void addNode(const Result & result);
template<typename Result>
void addNode(const Result& result);
template < typename Result >
void updateNode(const Result & result);
template<typename Result>
void updateNode(const Result& result);
private:
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
SoGroup * infoGroup;
OverlayParameters & overlayParameters;
DrawingParameters & drawingParameters;
SoGroup* infoGroup;
OverlayParameters& overlayParameters;
DrawingParameters& drawingParameters;
// Calculations
NodeText<CalculationType::BSplineDegree> degree;
@@ -204,8 +214,7 @@ private:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_InformationOverlayCoinConverter_H
#endif// SKETCHERGUI_InformationOverlayCoinConverter_H
+6 -5
View File
@@ -26,10 +26,11 @@
/***** Creation Mode ************/
namespace SketcherGui
{
enum GeometryCreationMode {
Normal,
Construction
};
enum GeometryCreationMode
{
Normal,
Construction
};
}
#endif //SKETCHERGUI_GEOMETRYCREATIONMODE_H
#endif// SKETCHERGUI_GEOMETRYCREATIONMODE_H
+1 -1
View File
@@ -20,4 +20,4 @@
* *
***************************************************************************/
#include "PreCompiled.h"
#include "PreCompiled.h"
+11 -11
View File
@@ -26,7 +26,7 @@
#include <FCConfig.h>
#ifdef _MSC_VER
# pragma warning(disable : 4005)
#pragma warning(disable : 4005)
#endif
#ifdef _PreComp_
@@ -45,41 +45,41 @@
#include <vector>
// Boost
#include <boost/math/special_functions/fpclassify.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#ifdef FC_OS_WIN32
# define NOMINMAX
# include <windows.h>
#define NOMINMAX
#include <windows.h>
#endif
// OpenCasCade
#include <BRep_Tool.hxx>
#include <GC_MakeEllipse.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <Standard_Version.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <gp_Pnt.hxx>
// Qt
#ifndef __QtAll__
# include <Gui/QtAll.h>
#include <Gui/QtAll.h>
#endif
#include <QWidgetAction>
// all of Inventor
#ifndef __InventorAll__
# include <Gui/InventorAll.h>
#include <Gui/InventorAll.h>
#endif
#endif //_PreComp_
#endif//_PreComp_
#endif // __PRECOMPILED_GUI__
#endif// __PRECOMPILED_GUI__
@@ -1,30 +1,30 @@
/***************************************************************************
* Copyright (c) 2014 Abdullah Tahiri <[email protected]> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
* Copyright (c) 2014 Abdullah Tahiri <[email protected]> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <memory>
# include <QDebug>
# include <QTextStream>
#include <QDebug>
#include <QTextStream>
#include <memory>
#endif
#include <Base/Tools.h>
@@ -45,12 +45,11 @@ PropertyConstraintListItem::PropertyConstraintListItem()
}
PropertyConstraintListItem::~PropertyConstraintListItem()
{
}
{}
QVariant PropertyConstraintListItem::toString(const QVariant& prop) const
{
const QList<Base::Quantity>& value = prop.value< QList<Base::Quantity> >();
const QList<Base::Quantity>& value = prop.value<QList<Base::Quantity>>();
QString str;
QTextStream out(&str);
out << "[";
@@ -65,21 +64,21 @@ QVariant PropertyConstraintListItem::toString(const QVariant& prop) const
void PropertyConstraintListItem::initialize()
{
const Sketcher::PropertyConstraintList* list = static_cast<const Sketcher::PropertyConstraintList*>(getPropertyData()[0]);
const std::vector< Sketcher::Constraint * > &vals = list->getValues();
const Sketcher::PropertyConstraintList* list =
static_cast<const Sketcher::PropertyConstraintList*>(getPropertyData()[0]);
const std::vector<Sketcher::Constraint*>& vals = list->getValues();
int id = 1;
int iNamed = 0;
std::vector<PropertyUnitItem *> unnamed;
std::vector<PropertyUnitItem*> unnamed;
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();it != vals.end(); ++it, ++id) {
if ((*it)->Type == Sketcher::Distance || // Datum constraint
(*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ) {
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin(); it != vals.end();
++it, ++id) {
if ((*it)->Type == Sketcher::Distance ||// Datum constraint
(*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY
|| (*it)->Type == Sketcher::Radius || (*it)->Type == Sketcher::Diameter
|| (*it)->Type == Sketcher::Angle) {
PropertyUnitItem* item = static_cast<PropertyUnitItem*>(PropertyUnitItem::create());
@@ -108,7 +107,7 @@ void PropertyConstraintListItem::initialize()
this->appendChild(item);
}
item->bind(list->createPath(id-1));
item->bind(list->createPath(id - 1));
item->setAutoApply(false);
}
}
@@ -116,7 +115,9 @@ void PropertyConstraintListItem::initialize()
// now deal with the unnamed
if (iNamed == 0) {
onlyUnnamed = true;
for (std::vector< PropertyUnitItem* >::const_iterator it = unnamed.begin();it != unnamed.end(); ++it) {
for (std::vector<PropertyUnitItem*>::const_iterator it = unnamed.begin();
it != unnamed.end();
++it) {
(*it)->setParent(this);
this->appendChild((*it));
}
@@ -124,12 +125,15 @@ void PropertyConstraintListItem::initialize()
else {
onlyUnnamed = false;
if (!unnamed.empty()) {
PropertyConstraintListItem* item = static_cast<PropertyConstraintListItem*>(PropertyConstraintListItem::create());
PropertyConstraintListItem* item =
static_cast<PropertyConstraintListItem*>(PropertyConstraintListItem::create());
item->setParent(this);
item->setPropertyName(tr("Unnamed"));
this->appendChild(item);
for (std::vector< PropertyUnitItem* >::const_iterator it = unnamed.begin();it != unnamed.end(); ++it) {
for (std::vector<PropertyUnitItem*>::const_iterator it = unnamed.begin();
it != unnamed.end();
++it) {
(*it)->setParent(item);
item->appendChild((*it));
}
@@ -145,8 +149,9 @@ void PropertyConstraintListItem::assignProperty(const App::Property* prop)
if (!prop->getTypeId().isDerivedFrom(Sketcher::PropertyConstraintList::getClassTypeId()))
return;
const Sketcher::PropertyConstraintList* list = static_cast<const Sketcher::PropertyConstraintList*>(prop);
const std::vector< Sketcher::Constraint * > &vals = list->getValues();
const Sketcher::PropertyConstraintList* list =
static_cast<const Sketcher::PropertyConstraintList*>(prop);
const std::vector<Sketcher::Constraint*>& vals = list->getValues();
// search for the group of unnamed items if available and take it out
int numUnnamed = 0;
@@ -166,19 +171,19 @@ void PropertyConstraintListItem::assignProperty(const App::Property* prop)
int numNamed = this->childCount();
this->onlyUnnamed = true;
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();it != vals.end(); ++it, ++id) {
if ((*it)->Type == Sketcher::Distance || // Datum constraint
(*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ) {
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin(); it != vals.end();
++it, ++id) {
if ((*it)->Type == Sketcher::Distance ||// Datum constraint
(*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY
|| (*it)->Type == Sketcher::Radius || (*it)->Type == Sketcher::Diameter
|| (*it)->Type == Sketcher::Angle) {
PropertyUnitItem* child = nullptr;
if ((*it)->Name.empty()) {
// search inside the group item for unnamed constraints
if (!unnamed) {
unnamed = static_cast<PropertyConstraintListItem*>(PropertyConstraintListItem::create());
unnamed = static_cast<PropertyConstraintListItem*>(
PropertyConstraintListItem::create());
unnamed->setPropertyName(tr("Unnamed"));
}
@@ -217,7 +222,7 @@ void PropertyConstraintListItem::assignProperty(const App::Property* prop)
child->setPropertyName(name);
child->setObjectName(internalName);
child->bind(list->createPath(id-1));
child->bind(list->createPath(id - 1));
child->setAutoApply(false);
}
}
@@ -232,7 +237,8 @@ void PropertyConstraintListItem::assignProperty(const App::Property* prop)
QVariant PropertyConstraintListItem::value(const App::Property* prop) const
{
assert(prop && prop->getTypeId().isDerivedFrom(Sketcher::PropertyConstraintList::getClassTypeId()));
assert(prop
&& prop->getTypeId().isDerivedFrom(Sketcher::PropertyConstraintList::getClassTypeId()));
PropertyConstraintListItem* self = const_cast<PropertyConstraintListItem*>(this);
@@ -242,17 +248,17 @@ QVariant PropertyConstraintListItem::value(const App::Property* prop) const
QList<Base::Quantity> subquantities;
bool onlyNamed = true;
const std::vector< Sketcher::Constraint * > &vals = static_cast<const Sketcher::PropertyConstraintList*>(prop)->getValues();
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();it != vals.end(); ++it, ++id) {
if ((*it)->Type == Sketcher::Distance || // Datum constraint
(*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ) {
const std::vector<Sketcher::Constraint*>& vals =
static_cast<const Sketcher::PropertyConstraintList*>(prop)->getValues();
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin(); it != vals.end();
++it, ++id) {
if ((*it)->Type == Sketcher::Distance ||// Datum constraint
(*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY
|| (*it)->Type == Sketcher::Radius || (*it)->Type == Sketcher::Diameter
|| (*it)->Type == Sketcher::Angle) {
Base::Quantity quant;
if ((*it)->Type == Sketcher::Angle ) {
if ((*it)->Type == Sketcher::Angle) {
double datum = Base::toDegrees<double>((*it)->getValue());
quant.setUnit(Base::Unit::Angle);
quant.setValue(datum);
@@ -271,11 +277,13 @@ QVariant PropertyConstraintListItem::value(const App::Property* prop) const
if ((*it)->Name.empty() && !onlyUnnamed) {
onlyNamed = false;
subquantities.append(quant);
PropertyItem* child = self->child(self->childCount()-1);
PropertyConstraintListItem* unnamednode = qobject_cast<PropertyConstraintListItem*>(child);
PropertyItem* child = self->child(self->childCount() - 1);
PropertyConstraintListItem* unnamednode =
qobject_cast<PropertyConstraintListItem*>(child);
if (unnamednode) {
unnamednode->blockEvent = true;
unnamednode->setProperty(internalName.toLatin1(), QVariant::fromValue<Base::Quantity>(quant));
unnamednode->setProperty(internalName.toLatin1(),
QVariant::fromValue<Base::Quantity>(quant));
unnamednode->blockEvent = false;
}
else {
@@ -285,7 +293,8 @@ QVariant PropertyConstraintListItem::value(const App::Property* prop) const
}
else {
self->blockEvent = true;
self->setProperty(internalName.toLatin1(), QVariant::fromValue<Base::Quantity>(quant));
self->setProperty(internalName.toLatin1(),
QVariant::fromValue<Base::Quantity>(quant));
self->blockEvent = false;
}
}
@@ -294,14 +303,14 @@ QVariant PropertyConstraintListItem::value(const App::Property* prop) const
// The quantities of unnamed constraints are only needed for display purposes inside toString()
if (!onlyUnnamed && !onlyNamed) {
self->blockEvent = true;
self->setProperty("Unnamed", QVariant::fromValue< QList<Base::Quantity> >(subquantities));
self->setProperty("Unnamed", QVariant::fromValue<QList<Base::Quantity>>(subquantities));
self->blockEvent = false;
}
return QVariant::fromValue< QList<Base::Quantity> >(quantities);
return QVariant::fromValue<QList<Base::Quantity>>(quantities);
}
bool PropertyConstraintListItem::event (QEvent* ev)
bool PropertyConstraintListItem::event(QEvent* ev)
{
if (ev->type() == QEvent::DynamicPropertyChange) {
if (!blockEvent) {
@@ -315,23 +324,24 @@ bool PropertyConstraintListItem::event (QEvent* ev)
int id = 0;
if (dynamic_cast<SketcherGui::PropertyConstraintListItem*>(this->parent())) {
item = static_cast<Sketcher::PropertyConstraintList*>(this->parent()->getFirstProperty());
item = static_cast<Sketcher::PropertyConstraintList*>(
this->parent()->getFirstProperty());
}
else {
item = static_cast<Sketcher::PropertyConstraintList*>(getFirstProperty());
}
const std::vector< Sketcher::Constraint * > &vals = item->getValues();
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();it != vals.end(); ++it, ++id) {
if ((*it)->Type == Sketcher::Distance || // Datum constraint
(*it)->Type == Sketcher::DistanceX ||
(*it)->Type == Sketcher::DistanceY ||
(*it)->Type == Sketcher::Radius ||
(*it)->Type == Sketcher::Diameter ||
(*it)->Type == Sketcher::Angle ) {
const std::vector<Sketcher::Constraint*>& vals = item->getValues();
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin();
it != vals.end();
++it, ++id) {
if ((*it)->Type == Sketcher::Distance ||// Datum constraint
(*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY
|| (*it)->Type == Sketcher::Radius || (*it)->Type == Sketcher::Diameter
|| (*it)->Type == Sketcher::Angle) {
// Get the internal name
QString internalName = QString::fromLatin1("Constraint%1").arg(id+1);
QString internalName = QString::fromLatin1("Constraint%1").arg(id + 1);
if (internalName == propName) {
double datum = quant.getValue();
if ((*it)->Type == Sketcher::Angle)
@@ -355,25 +365,26 @@ void PropertyConstraintListItem::setValue(const QVariant& value)
Q_UNUSED(value);
}
QWidget* PropertyConstraintListItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
QWidget* PropertyConstraintListItem::createEditor(QWidget* parent, const QObject* receiver,
const char* method) const
{
Q_UNUSED(receiver);
Q_UNUSED(method);
QLineEdit *le = new QLineEdit(parent);
QLineEdit* le = new QLineEdit(parent);
le->setFrame(false);
le->setReadOnly(true);
return le;
}
void PropertyConstraintListItem::setEditorData(QWidget *editor, const QVariant& data) const
void PropertyConstraintListItem::setEditorData(QWidget* editor, const QVariant& data) const
{
QLineEdit* le = qobject_cast<QLineEdit*>(editor);
le->setText(toString(data).toString());
}
QVariant PropertyConstraintListItem::editorData(QWidget *editor) const
QVariant PropertyConstraintListItem::editorData(QWidget* editor) const
{
QLineEdit *le = qobject_cast<QLineEdit*>(editor);
QLineEdit* le = qobject_cast<QLineEdit*>(editor);
return QVariant(le->text());
}
@@ -1,34 +1,35 @@
/***************************************************************************
* Copyright (c) 2014 Abdullah Tahiri <[email protected]> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
* Copyright (c) 2014 Abdullah Tahiri <[email protected]> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PROPERTYCONSTRAINTLISTITEM_H
#define PROPERTYCONSTRAINTLISTITEM_H
#include <vector>
#include <QObject>
#include <vector>
#include <Gui/propertyeditor/PropertyItem.h>
namespace SketcherGui {
namespace SketcherGui
{
class PropertyConstraintListItem: public Gui::PropertyEditor::PropertyItem
{
@@ -37,15 +38,16 @@ class PropertyConstraintListItem: public Gui::PropertyEditor::PropertyItem
~PropertyConstraintListItem() override;
void assignProperty(const App::Property* prop) override;
QWidget* createEditor(QWidget* parent, const QObject* receiver, const char* method) const override;
void setEditorData(QWidget *editor, const QVariant& data) const override;
QVariant editorData(QWidget *editor) const override;
QWidget* createEditor(QWidget* parent, const QObject* receiver,
const char* method) const override;
void setEditorData(QWidget* editor, const QVariant& data) const override;
QVariant editorData(QWidget* editor) const override;
protected:
QVariant toString(const QVariant&) const override;
QVariant value(const App::Property*) const override;
void setValue(const QVariant&) override;
bool event (QEvent* ev) override;
bool event(QEvent* ev) override;
void initialize() override;
@@ -55,7 +57,7 @@ protected:
bool onlyUnnamed;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif
@@ -23,9 +23,9 @@
#include "PreCompiled.h"
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Base/Reader.h>
#include <Base/Writer.h>
#include <Base/Interpreter.h>
#include "PropertyVisualLayerList.h"
@@ -36,7 +36,7 @@ using namespace std;
using namespace SketcherGui;
TYPESYSTEM_SOURCE(SketcherGui::PropertyVisualLayerList , App::PropertyLists)
TYPESYSTEM_SOURCE(SketcherGui::PropertyVisualLayerList, App::PropertyLists)
//**************************************************************************
// Construction/Destruction
@@ -48,29 +48,30 @@ PropertyVisualLayerList::~PropertyVisualLayerList() = default;
//**************************************************************************
// Base class implementer
PyObject *PropertyVisualLayerList::getPyObject()
PyObject* PropertyVisualLayerList::getPyObject()
{
THROWM(Base::NotImplementedError, "PropertyVisualLayerList has no python counterpart");
}
VisualLayer PropertyVisualLayerList::getPyValue(PyObject *item) const {
VisualLayer PropertyVisualLayerList::getPyValue(PyObject* item) const
{
(void) item;
(void)item;
THROWM(Base::NotImplementedError, "PropertyVisualLayerList has no python counterpart");
}
void PropertyVisualLayerList::Save (Base::Writer &writer) const
void PropertyVisualLayerList::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind() << "<VisualLayerList count=\"" << getSize() <<"\">" << endl;
writer.Stream() << writer.ind() << "<VisualLayerList count=\"" << getSize() << "\">" << endl;
writer.incInd();
for (int i = 0; i < getSize(); i++) {
_lValueList[i].Save(writer);
}
writer.decInd();
writer.Stream() << writer.ind() << "</VisualLayerList>" << endl ;
writer.Stream() << writer.ind() << "</VisualLayerList>" << endl;
}
void PropertyVisualLayerList::Restore(Base::XMLReader &reader)
void PropertyVisualLayerList::Restore(Base::XMLReader& reader)
{
reader.readElement("VisualLayerList");
// get the value of my attribute
@@ -90,19 +91,19 @@ void PropertyVisualLayerList::Restore(Base::XMLReader &reader)
setValues(std::move(layers));
}
Property *PropertyVisualLayerList::Copy() const
Property* PropertyVisualLayerList::Copy() const
{
PropertyVisualLayerList *p= new PropertyVisualLayerList();
PropertyVisualLayerList* p = new PropertyVisualLayerList();
p->_lValueList = _lValueList;
return p;
}
void PropertyVisualLayerList::Paste(const Property &from)
void PropertyVisualLayerList::Paste(const Property& from)
{
setValues(dynamic_cast<const PropertyVisualLayerList&>(from)._lValueList);
}
unsigned int PropertyVisualLayerList::getMemSize () const
unsigned int PropertyVisualLayerList::getMemSize() const
{
return static_cast<unsigned int>(_lValueList.size() * sizeof(VisualLayer));
}
+11 -11
View File
@@ -32,7 +32,8 @@
#include "VisualLayer.h"
namespace Base {
namespace Base
{
class Writer;
}
@@ -44,7 +45,6 @@ class SketcherGuiExport PropertyVisualLayerList: public App::PropertyListsT<Visu
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
/**
* A constructor.
* A more elaborate description of the constructor.
@@ -57,20 +57,20 @@ public:
*/
~PropertyVisualLayerList() override;
PyObject *getPyObject() override;
PyObject* getPyObject() override;
void Save (Base::Writer &writer) const override;
void Restore(Base::XMLReader &reader) override;
void Save(Base::Writer& writer) const override;
void Restore(Base::XMLReader& reader) override;
Property *Copy() const override;
void Paste(const Property &from) override;
unsigned int getMemSize () const override;
Property* Copy() const override;
void Paste(const Property& from) override;
unsigned int getMemSize() const override;
protected:
VisualLayer getPyValue(PyObject *) const override;
VisualLayer getPyValue(PyObject*) const override;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_PropertyVisualLayerList_H
#endif// SKETCHERGUI_PropertyVisualLayerList_H
+9 -10
View File
@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QKeyEvent>
#include <QKeyEvent>
#endif
#include "ShortcutListener.h"
@@ -32,27 +32,26 @@
using namespace SketcherGui;
// ******************** ViewProvider attorney *********************************************//
inline void ViewProviderSketchShortcutListenerAttorney::deleteSelected(ViewProviderSketch & vp)
inline void ViewProviderSketchShortcutListenerAttorney::deleteSelected(ViewProviderSketch& vp)
{
vp.deleteSelected();
};
// ******************** ShortcutListener *********************************************//
ShortcutListener::ShortcutListener(ViewProviderSketch * vp)
ShortcutListener::ShortcutListener(ViewProviderSketch* vp)
{
pViewProvider = vp;
}
ShortcutListener::~ShortcutListener()
{
}
{}
bool ShortcutListener::eventFilter(QObject *obj, QEvent *event) {
bool ShortcutListener::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::ShortcutOverride) {
QKeyEvent * kevent = static_cast<QKeyEvent*>(event);
if (kevent->modifiers() == Qt::NoModifier ||
kevent->modifiers() == Qt::ShiftModifier ||
kevent->modifiers() == Qt::KeypadModifier) {
QKeyEvent* kevent = static_cast<QKeyEvent*>(event);
if (kevent->modifiers() == Qt::NoModifier || kevent->modifiers() == Qt::ShiftModifier
|| kevent->modifiers() == Qt::KeypadModifier) {
switch (kevent->key()) {
case Qt::Key_Delete:
kevent->accept();
+11 -10
View File
@@ -26,13 +26,15 @@
#include <QObject>
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class ViewProviderSketchShortcutListenerAttorney {
class ViewProviderSketchShortcutListenerAttorney
{
private:
static inline void deleteSelected(ViewProviderSketch &vp);
static inline void deleteSelected(ViewProviderSketch& vp);
friend class ShortcutListener;
@@ -40,20 +42,19 @@ private:
class ShortcutListener: public QObject
{
//Q_OBJECT
// Q_OBJECT
public:
explicit ShortcutListener(ViewProviderSketch * vp);
explicit ShortcutListener(ViewProviderSketch* vp);
~ShortcutListener() override;
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
bool eventFilter(QObject* obj, QEvent* event) override;
ViewProviderSketch * pViewProvider;
ViewProviderSketch* pViewProvider;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_SHORTCUTLISTENER_H
#endif// SKETCHERGUI_SHORTCUTLISTENER_H
+13 -14
View File
@@ -22,43 +22,42 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QDialog>
#include <QDialog>
#endif
#include <Gui/MainWindow.h>
#include "ui_SketchMirrorDialog.h"
#include "SketchMirrorDialog.h"
#include "ui_SketchMirrorDialog.h"
using namespace SketcherGui;
SketchMirrorDialog::SketchMirrorDialog()
: QDialog(Gui::getMainWindow())
, RefGeoid(-1)
, RefPosid(Sketcher::PointPos::none)
, ui(new Ui_SketchMirrorDialog)
: QDialog(Gui::getMainWindow())
, RefGeoid(-1)
, RefPosid(Sketcher::PointPos::none)
, ui(new Ui_SketchMirrorDialog)
{
ui->setupUi(this);
}
SketchMirrorDialog::~SketchMirrorDialog()
{
}
{}
void SketchMirrorDialog::accept()
{
if (ui->XAxisRadioButton->isChecked()) {
RefGeoid=Sketcher::GeoEnum::HAxis;
RefPosid=Sketcher::PointPos::none;
RefGeoid = Sketcher::GeoEnum::HAxis;
RefPosid = Sketcher::PointPos::none;
}
else if (ui->YAxisRadioButton->isChecked()) {
RefGeoid=Sketcher::GeoEnum::VAxis;
RefPosid=Sketcher::PointPos::none;
RefGeoid = Sketcher::GeoEnum::VAxis;
RefPosid = Sketcher::PointPos::none;
}
else if (ui->OriginRadioButton->isChecked()) {
RefGeoid=Sketcher::GeoEnum::RtPnt;
RefPosid=Sketcher::PointPos::start;
RefGeoid = Sketcher::GeoEnum::RtPnt;
RefPosid = Sketcher::PointPos::start;
}
QDialog::accept();
+5 -4
View File
@@ -28,10 +28,11 @@
#include <Mod/Sketcher/App/GeoEnum.h>
namespace SketcherGui {
namespace SketcherGui
{
class Ui_SketchMirrorDialog;
class SketchMirrorDialog : public QDialog
class SketchMirrorDialog: public QDialog
{
Q_OBJECT
@@ -48,6 +49,6 @@ private:
std::unique_ptr<Ui_SketchMirrorDialog> ui;
};
}
}// namespace SketcherGui
#endif // SKETCHERGUI_SketchMirrorDialog_H
#endif// SKETCHERGUI_SketchMirrorDialog_H
@@ -22,34 +22,34 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QDialog>
#include <QDialog>
#endif
#include <Gui/BitmapFactory.h>
#include <Gui/MainWindow.h>
#include "ui_SketchOrientationDialog.h"
#include "SketchOrientationDialog.h"
#include "ui_SketchOrientationDialog.h"
using namespace SketcherGui;
SketchOrientationDialog::SketchOrientationDialog()
: QDialog(Gui::getMainWindow()), ui(new Ui_SketchOrientationDialog)
: QDialog(Gui::getMainWindow())
, ui(new Ui_SketchOrientationDialog)
{
DirType = 0;
ui->setupUi(this);
onPreview();
connect(ui->Reverse_checkBox, &QCheckBox::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->XY_radioButton , &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->XZ_radioButton , &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->YZ_radioButton , &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->XY_radioButton, &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->XZ_radioButton, &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
connect(ui->YZ_radioButton, &QRadioButton::clicked, this, &SketchOrientationDialog::onPreview);
}
SketchOrientationDialog::~SketchOrientationDialog()
{
}
{}
void SketchOrientationDialog::accept()
{
@@ -57,31 +57,32 @@ void SketchOrientationDialog::accept()
bool reverse = ui->Reverse_checkBox->isChecked();
if (ui->XY_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation(1.0,0.0,0.0,0.0));
Pos = Base::Placement(Base::Vector3d(0, 0, offset), Base::Rotation(1.0, 0.0, 0.0, 0.0));
DirType = 1;
}
else {
Pos = Base::Placement(Base::Vector3d(0,0,offset),Base::Rotation());
Pos = Base::Placement(Base::Vector3d(0, 0, offset), Base::Rotation());
DirType = 0;
}
}
else if (ui->XZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(0.0,1.0,1.0,0.0));
Pos = Base::Placement(Base::Vector3d(0, offset, 0), Base::Rotation(0.0, 1.0, 1.0, 0.0));
DirType = 3;
}
else {
Pos = Base::Placement(Base::Vector3d(0,offset,0),Base::Rotation(1.0,0.0,0.0,1.0));
Pos = Base::Placement(Base::Vector3d(0, offset, 0), Base::Rotation(1.0, 0.0, 0.0, 1.0));
DirType = 2;
}
}
else if (ui->YZ_radioButton->isChecked()) {
if (reverse) {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(-1.0,1.0,1.0,-1.0));
Pos =
Base::Placement(Base::Vector3d(offset, 0, 0), Base::Rotation(-1.0, 1.0, 1.0, -1.0));
DirType = 5;
}
else {
Pos = Base::Placement(Base::Vector3d(offset,0,0),Base::Rotation(1.0,1.0,1.0,1.0));
Pos = Base::Placement(Base::Vector3d(offset, 0, 0), Base::Rotation(1.0, 1.0, 1.0, 1.0));
DirType = 4;
}
}
@@ -113,8 +114,7 @@ void SketchOrientationDialog::onPreview()
}
ui->previewLabel->setPixmap(
Gui::BitmapFactory().pixmapFromSvg(icon.c_str(),
ui->previewLabel->size()));
Gui::BitmapFactory().pixmapFromSvg(icon.c_str(), ui->previewLabel->size()));
}
#include "moc_SketchOrientationDialog.cpp"
@@ -29,10 +29,11 @@
#include <Mod/Sketcher/SketcherGlobal.h>
namespace SketcherGui {
namespace SketcherGui
{
class Ui_SketchOrientationDialog;
class SketcherGuiExport SketchOrientationDialog : public QDialog
class SketcherGuiExport SketchOrientationDialog: public QDialog
{
Q_OBJECT
@@ -41,7 +42,7 @@ public:
~SketchOrientationDialog() override;
Base::Placement Pos;
int DirType;
int DirType;
void accept() override;
@@ -52,6 +53,6 @@ private:
std::unique_ptr<Ui_SketchOrientationDialog> ui;
};
}
}// namespace SketcherGui
#endif // SKETCHERGUI_SketchOrientationDialog_H
#endif// SKETCHERGUI_SketchOrientationDialog_H
@@ -22,34 +22,34 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QDialog>
#include <QDialog>
#endif
#include <Gui/MainWindow.h>
#include "ui_SketchRectangularArrayDialog.h"
#include "SketchRectangularArrayDialog.h"
#include "ui_SketchRectangularArrayDialog.h"
using namespace SketcherGui;
SketchRectangularArrayDialog::SketchRectangularArrayDialog()
: QDialog(Gui::getMainWindow()), ui(new Ui_SketchRectangularArrayDialog)
: QDialog(Gui::getMainWindow())
, ui(new Ui_SketchRectangularArrayDialog)
{
ui->setupUi(this);
ui->RowsQuantitySpinBox->onRestore();
ui->ColsQuantitySpinBox->onRestore();
ui->ConstraintSeparationCheckBox->onRestore();
ui->EqualVerticalHorizontalSpacingCheckBox->onRestore();
ui->CloneCheckBox->onRestore();
updateValues();
}
SketchRectangularArrayDialog::~SketchRectangularArrayDialog()
{
}
{}
void SketchRectangularArrayDialog::accept()
{
@@ -58,9 +58,9 @@ void SketchRectangularArrayDialog::accept()
ui->ConstraintSeparationCheckBox->onSave();
ui->EqualVerticalHorizontalSpacingCheckBox->onSave();
ui->CloneCheckBox->onSave();
updateValues();
QDialog::accept();
}
@@ -70,7 +70,7 @@ void SketchRectangularArrayDialog::updateValues()
Cols = ui->ColsQuantitySpinBox->value();
ConstraintSeparation = ui->ConstraintSeparationCheckBox->isChecked();
EqualVerticalHorizontalSpacing = ui->EqualVerticalHorizontalSpacingCheckBox->isChecked();
Clone = ui->CloneCheckBox->isChecked();
Clone = ui->CloneCheckBox->isChecked();
}
#include "moc_SketchRectangularArrayDialog.cpp"
@@ -26,10 +26,11 @@
#include <QDialog>
namespace SketcherGui {
namespace SketcherGui
{
class Ui_SketchRectangularArrayDialog;
class SketchRectangularArrayDialog : public QDialog
class SketchRectangularArrayDialog: public QDialog
{
Q_OBJECT
@@ -38,7 +39,7 @@ public:
~SketchRectangularArrayDialog() override;
void accept() override;
int Rows;
int Cols;
bool ConstraintSeparation;
@@ -47,10 +48,11 @@ public:
protected:
void updateValues();
private:
std::unique_ptr<Ui_SketchRectangularArrayDialog> ui;
};
}
}// namespace SketcherGui
#endif // SKETCHERGUI_SketchRectangularArrayDialog_H
#endif// SKETCHERGUI_SketchRectangularArrayDialog_H
@@ -22,19 +22,20 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QDialog>
#include <QDialog>
#endif
#include <Gui/MainWindow.h>
#include "ui_SketcherRegularPolygonDialog.h"
#include "SketcherRegularPolygonDialog.h"
#include "ui_SketcherRegularPolygonDialog.h"
using namespace SketcherGui;
SketcherRegularPolygonDialog::SketcherRegularPolygonDialog()
: QDialog(Gui::getMainWindow()), ui(new Ui_SketcherRegularPolygonDialog)
: QDialog(Gui::getMainWindow())
, ui(new Ui_SketcherRegularPolygonDialog)
{
ui->setupUi(this);
@@ -44,8 +45,7 @@ SketcherRegularPolygonDialog::SketcherRegularPolygonDialog()
}
SketcherRegularPolygonDialog::~SketcherRegularPolygonDialog()
{
}
{}
void SketcherRegularPolygonDialog::accept()
{
@@ -26,10 +26,11 @@
#include <QDialog>
namespace SketcherGui {
namespace SketcherGui
{
class Ui_SketcherRegularPolygonDialog;
class SketcherRegularPolygonDialog : public QDialog
class SketcherRegularPolygonDialog: public QDialog
{
Q_OBJECT
@@ -43,10 +44,11 @@ public:
protected:
void updateValues();
private:
std::unique_ptr<Ui_SketcherRegularPolygonDialog> ui;
};
}
}// namespace SketcherGui
#endif // SKETCHERGUI_SketcherRegularPolygonDialog_H
#endif// SKETCHERGUI_SketcherRegularPolygonDialog_H
+50 -43
View File
@@ -22,9 +22,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QMessageBox>
# include <QPainter>
# include <QPixmap>
#include <QMessageBox>
#include <QPainter>
#include <QPixmap>
#endif
#include <App/Application.h>
@@ -34,10 +34,9 @@
#include "SketcherSettings.h"
#include "ui_SketcherSettings.h"
#include "ui_SketcherSettingsGrid.h"
#include "ui_SketcherSettingsDisplay.h"
#include "ui_SketcherSettingsColors.h"
#include "ui_SketcherSettingsDisplay.h"
#include "ui_SketcherSettingsGrid.h"
using namespace SketcherGui;
@@ -45,7 +44,8 @@ using namespace SketcherGui;
/* TRANSLATOR SketcherGui::SketcherSettings */
SketcherSettings::SketcherSettings(QWidget* parent)
: PreferencePage(parent), ui(new Ui_SketcherSettings)
: PreferencePage(parent)
, ui(new Ui_SketcherSettings)
{
ui->setupUi(this);
}
@@ -81,7 +81,7 @@ void SketcherSettings::loadSettings()
/**
* Sets the strings of the subwidgets using the current language.
*/
void SketcherSettings::changeEvent(QEvent *e)
void SketcherSettings::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -94,18 +94,18 @@ void SketcherSettings::changeEvent(QEvent *e)
/* TRANSLATOR SketcherGui::SketcherSettingsGrid */
SketcherSettingsGrid::SketcherSettingsGrid(QWidget* parent)
: PreferencePage(parent), ui(new Ui_SketcherSettingsGrid)
: PreferencePage(parent)
, ui(new Ui_SketcherSettingsGrid)
{
ui->setupUi(this);
QList < QPair<Qt::PenStyle, int> > styles;
styles << qMakePair(Qt::SolidLine, 0xffff)
<< qMakePair(Qt::DashLine, 0x0f0f)
<< qMakePair(Qt::DotLine, 0xaaaa);
QList<QPair<Qt::PenStyle, int>> styles;
styles << qMakePair(Qt::SolidLine, 0xffff) << qMakePair(Qt::DashLine, 0x0f0f)
<< qMakePair(Qt::DotLine, 0xaaaa);
ui->gridLinePattern->setIconSize(QSize(80, 12));
ui->gridDivLinePattern->setIconSize(QSize(80, 12));
for (QList < QPair<Qt::PenStyle, int> >::iterator it = styles.begin(); it != styles.end(); ++it) {
for (QList<QPair<Qt::PenStyle, int>>::iterator it = styles.begin(); it != styles.end(); ++it) {
QPixmap px(ui->gridLinePattern->iconSize());
px.fill(Qt::transparent);
QBrush brush(Qt::black);
@@ -141,7 +141,8 @@ void SketcherSettingsGrid::saveSettings()
ui->gridDivLineWidth->onSave();
ui->gridNumberSubdivision->onSave();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
QVariant data = ui->gridLinePattern->itemData(ui->gridLinePattern->currentIndex());
int pattern = data.toInt();
hGrp->SetInt("GridLinePattern", pattern);
@@ -163,14 +164,17 @@ void SketcherSettingsGrid::loadSettings()
ui->gridDivLineWidth->onRestore();
ui->gridNumberSubdivision->onRestore();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
int pattern = hGrp->GetInt("GridLinePattern", 0x0f0f);
int index = ui->gridLinePattern->findData(QVariant(pattern));
if (index < 0) index = 1;
if (index < 0)
index = 1;
ui->gridLinePattern->setCurrentIndex(index);
pattern = hGrp->GetInt("GridDivLinePattern", 0xffff);
index = ui->gridDivLinePattern->findData(QVariant(pattern));
if (index < 0) index = 0;
if (index < 0)
index = 0;
ui->gridDivLinePattern->setCurrentIndex(index);
}
@@ -190,11 +194,13 @@ void SketcherSettingsGrid::changeEvent(QEvent* e)
/* TRANSLATOR SketcherGui::SketcherSettingsDisplay */
SketcherSettingsDisplay::SketcherSettingsDisplay(QWidget* parent)
: PreferencePage(parent), ui(new Ui_SketcherSettingsDisplay)
: PreferencePage(parent)
, ui(new Ui_SketcherSettingsDisplay)
{
ui->setupUi(this);
connect(ui->btnTVApply, &QPushButton::clicked, this, &SketcherSettingsDisplay::onBtnTVApplyClicked);
connect(
ui->btnTVApply, &QPushButton::clicked, this, &SketcherSettingsDisplay::onBtnTVApplyClicked);
}
/**
@@ -251,7 +257,7 @@ void SketcherSettingsDisplay::loadSettings()
/**
* Sets the strings of the subwidgets using the current language.
*/
void SketcherSettingsDisplay::changeEvent(QEvent *e)
void SketcherSettingsDisplay::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -264,40 +270,42 @@ void SketcherSettingsDisplay::changeEvent(QEvent *e)
void SketcherSettingsDisplay::onBtnTVApplyClicked(bool)
{
QString errMsg;
try{
try {
Gui::Command::doCommand(Gui::Command::Gui,
"for name,doc in App.listDocuments().items():\n"
" for sketch in doc.findObjects('Sketcher::SketchObject'):\n"
" sketch.ViewObject.HideDependent = %s\n"
" sketch.ViewObject.ShowLinks = %s\n"
" sketch.ViewObject.ShowSupport = %s\n"
" sketch.ViewObject.RestoreCamera = %s\n"
" sketch.ViewObject.ForceOrtho = %s\n"
" sketch.ViewObject.SectionView = %s\n",
this->ui->checkBoxTVHideDependent->isChecked() ? "True": "False",
this->ui->checkBoxTVShowLinks->isChecked() ? "True": "False",
this->ui->checkBoxTVShowSupport->isChecked() ? "True": "False",
this->ui->checkBoxTVRestoreCamera->isChecked() ? "True": "False",
this->ui->checkBoxTVForceOrtho->isChecked() ? "True": "False",
this->ui->checkBoxTVSectionView->isChecked() ? "True": "False");
} catch (Base::PyException &e){
"for name,doc in App.listDocuments().items():\n"
" for sketch in doc.findObjects('Sketcher::SketchObject'):\n"
" sketch.ViewObject.HideDependent = %s\n"
" sketch.ViewObject.ShowLinks = %s\n"
" sketch.ViewObject.ShowSupport = %s\n"
" sketch.ViewObject.RestoreCamera = %s\n"
" sketch.ViewObject.ForceOrtho = %s\n"
" sketch.ViewObject.SectionView = %s\n",
this->ui->checkBoxTVHideDependent->isChecked() ? "True" : "False",
this->ui->checkBoxTVShowLinks->isChecked() ? "True" : "False",
this->ui->checkBoxTVShowSupport->isChecked() ? "True" : "False",
this->ui->checkBoxTVRestoreCamera->isChecked() ? "True" : "False",
this->ui->checkBoxTVForceOrtho->isChecked() ? "True" : "False",
this->ui->checkBoxTVSectionView->isChecked() ? "True" : "False");
}
catch (Base::PyException& e) {
Base::Console().DeveloperError("SketcherSettings", "error in onBtnTVApplyClicked:\n");
e.ReportException();
errMsg = QString::fromLatin1(e.what());
} catch (...) {
}
catch (...) {
errMsg = tr("Unexpected C++ exception");
}
if(errMsg.length()>0){
QMessageBox::warning(this, tr("Sketcher"),errMsg);
if (errMsg.length() > 0) {
QMessageBox::warning(this, tr("Sketcher"), errMsg);
}
}
/* TRANSLATOR SketcherGui::SketcherSettingsColors */
SketcherSettingsColors::SketcherSettingsColors(QWidget* parent)
: PreferencePage(parent), ui(new Ui_SketcherSettingsColors)
: PreferencePage(parent)
, ui(new Ui_SketcherSettingsColors)
{
ui->setupUi(this);
}
@@ -369,7 +377,7 @@ void SketcherSettingsColors::loadSettings()
/**
* Sets the strings of the subwidgets using the current language.
*/
void SketcherSettingsColors::changeEvent(QEvent *e)
void SketcherSettingsColors::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -380,4 +388,3 @@ void SketcherSettingsColors::changeEvent(QEvent *e)
}
#include "moc_SketcherSettings.cpp"
+13 -12
View File
@@ -23,11 +23,12 @@
#ifndef SKETCHERGUI_SKETCHERSETTINGS_H
#define SKETCHERGUI_SKETCHERSETTINGS_H
#include <memory>
#include <Gui/PropertyPage.h>
#include <memory>
namespace SketcherGui {
namespace SketcherGui
{
class Ui_SketcherSettings;
class Ui_SketcherSettingsGrid;
class Ui_SketcherSettingsDisplay;
@@ -37,7 +38,7 @@ class SketcherGeneralWidget;
* The SketcherSettings class implements a preference page to change sketcher settings.
* @author Werner Mayer
*/
class SketcherSettings : public Gui::Dialog::PreferencePage
class SketcherSettings: public Gui::Dialog::PreferencePage
{
Q_OBJECT
@@ -49,7 +50,7 @@ public:
void loadSettings() override;
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
std::unique_ptr<Ui_SketcherSettings> ui;
@@ -58,7 +59,7 @@ private:
/**
* The SketcherSettings class implements a preference page to change sketcher grid settings.
*/
class SketcherSettingsGrid : public Gui::Dialog::PreferencePage
class SketcherSettingsGrid: public Gui::Dialog::PreferencePage
{
Q_OBJECT
@@ -70,7 +71,7 @@ public:
void loadSettings() override;
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
std::unique_ptr<Ui_SketcherSettingsGrid> ui;
@@ -80,7 +81,7 @@ private:
* The SketcherSettings class implements a preference page to change sketcher display settings.
* @author Werner Mayer
*/
class SketcherSettingsDisplay : public Gui::Dialog::PreferencePage
class SketcherSettingsDisplay: public Gui::Dialog::PreferencePage
{
Q_OBJECT
@@ -92,7 +93,7 @@ public:
void loadSettings() override;
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private Q_SLOTS:
void onBtnTVApplyClicked(bool);
@@ -105,7 +106,7 @@ private:
* The SketcherSettings class implements a preference page to change sketcher settings.
* @author Werner Mayer
*/
class SketcherSettingsColors : public Gui::Dialog::PreferencePage
class SketcherSettingsColors: public Gui::Dialog::PreferencePage
{
Q_OBJECT
@@ -117,12 +118,12 @@ public:
void loadSettings() override;
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
std::unique_ptr<Ui_SketcherSettingsColors> ui;
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_SKETCHERSETTINGS_H
#endif// SKETCHERGUI_SKETCHERSETTINGS_H
+52 -31
View File
@@ -23,7 +23,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#endif // #ifndef _PreComp_
#endif// #ifndef _PreComp_
#include <Mod/Sketcher/App/SketchObject.h>
@@ -52,7 +52,8 @@ inline int ViewProviderSketchSnapAttorney::getPreselectCurve(const ViewProviderS
}
/**************************** ParameterObserver nested class *****************************/
SnapManager::ParameterObserver::ParameterObserver(SnapManager& client) : client(client)
SnapManager::ParameterObserver::ParameterObserver(SnapManager& client)
: client(client)
{
initParameters();
subscribeToParameters();
@@ -71,13 +72,21 @@ void SnapManager::ParameterObserver::initParameters()
// key->second => Update function to be called for the parameter,
str2updatefunction = {
{"Snap",
[this](const std::string& param) {updateSnapParameter(param); }},
[this](const std::string& param) {
updateSnapParameter(param);
}},
{"SnapToObjects",
[this](const std::string& param) {updateSnapToObjectParameter(param); }},
[this](const std::string& param) {
updateSnapToObjectParameter(param);
}},
{"SnapToGrid",
[this](const std::string& param) {updateSnapToGridParameter(param); }},
[this](const std::string& param) {
updateSnapToGridParameter(param);
}},
{"SnapAngle",
[this](const std::string& param) {updateSnapAngleParameter(param); }},
[this](const std::string& param) {
updateSnapAngleParameter(param);
}},
};
for (auto& val : str2updatefunction) {
@@ -122,7 +131,8 @@ void SnapManager::ParameterObserver::subscribeToParameters()
ParameterGrp::handle hGrp = getParameterGrpHandle();
hGrp->Attach(this);
}
catch (const Base::ValueError& e) { // ensure that if parameter strings are not well-formed, the exception is not propagated
catch (const Base::ValueError& e) {// ensure that if parameter strings are not well-formed, the
// exception is not propagated
Base::Console().DeveloperError("SnapManager", "Malformed parameter string: %s\n", e.what());
}
}
@@ -133,12 +143,15 @@ void SnapManager::ParameterObserver::unsubscribeToParameters()
ParameterGrp::handle hGrp = getParameterGrpHandle();
hGrp->Detach(this);
}
catch (const Base::ValueError& e) {// ensure that if parameter strings are not well-formed, the program is not terminated when calling the noexcept destructor.
catch (const Base::ValueError&
e) {// ensure that if parameter strings are not well-formed, the program is not
// terminated when calling the noexcept destructor.
Base::Console().DeveloperError("SnapManager", "Malformed parameter string: %s\n", e.what());
}
}
void SnapManager::ParameterObserver::OnChange(Base::Subject<const char*>& rCaller, const char* sReason)
void SnapManager::ParameterObserver::OnChange(Base::Subject<const char*>& rCaller,
const char* sReason)
{
(void)rCaller;
@@ -153,27 +166,32 @@ void SnapManager::ParameterObserver::OnChange(Base::Subject<const char*>& rCalle
ParameterGrp::handle SnapManager::ParameterObserver::getParameterGrpHandle()
{
return App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/Snap");
return App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/Snap");
}
//**************************** SnapManager class ******************************
SnapManager::SnapManager(ViewProviderSketch &vp):viewProvider(vp), angleSnapRequested(false), referencePoint(Base::Vector2d(0.,0.)), lastMouseAngle(0.0)
SnapManager::SnapManager(ViewProviderSketch& vp)
: viewProvider(vp)
, angleSnapRequested(false)
, referencePoint(Base::Vector2d(0., 0.))
, lastMouseAngle(0.0)
{
// Create parameter observer and initialise watched parameters
pObserver = std::make_unique<SnapManager::ParameterObserver>(*this);
}
SnapManager::~SnapManager() {}
SnapManager::~SnapManager()
{}
bool SnapManager::snap(double& x, double& y)
{
if (!snapRequested)
{
if (!snapRequested) {
return false;
}
//In order of priority :
// In order of priority :
// 1 - Snap at an angle
if (angleSnapRequested && QApplication::keyboardModifiers() == Qt::ControlModifier) {
@@ -184,13 +202,14 @@ bool SnapManager::snap(double& x, double& y)
}
// 2 - Snap to objects
if (snapToObjectsRequested
&& snapToObject(x, y)) {
if (snapToObjectsRequested && snapToObject(x, y)) {
return true;
}
// 3 - Snap to grid
if (snapToGridRequested /*&& viewProvider.ShowGrid.getValue() */ ) { //Snap to grid is enabled even if the grid is not visible.
if (snapToGridRequested /*&& viewProvider.ShowGrid.getValue() */) {// Snap to grid is enabled
// even if the grid is not
// visible.
return snapToGrid(x, y);
}
@@ -237,15 +256,15 @@ bool SnapManager::snapToObject(double& x, double& y)
y = Obj->getPoint(geoId, posId).y;
return true;
}
else if (CrsId == 1) { //H_Axis
else if (CrsId == 1) {// H_Axis
y = 0;
return true;
}
else if (CrsId == 2) { //V_Axis
else if (CrsId == 2) {// V_Axis
x = 0;
return true;
}
else if (CrvId >= 0 || CrvId <= Sketcher::GeoEnum::RefExt) { //Curves
else if (CrvId >= 0 || CrvId <= Sketcher::GeoEnum::RefExt) {// Curves
const Part::Geometry* geo = Obj->getGeometry(CrvId);
@@ -263,13 +282,13 @@ bool SnapManager::snapToObject(double& x, double& y)
return false;
}
//If it is a line, then we check if we need to snap to the middle.
// If it is a line, then we check if we need to snap to the middle.
if (geo->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
const Part::GeomLineSegment* line = static_cast<const Part::GeomLineSegment*>(geo);
snapToLineMiddle(pointToOverride, line);
}
//If it is an arc, then we check if we need to snap to the middle (not the center).
// If it is an arc, then we check if we need to snap to the middle (not the center).
if (geo->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
snapToArcMiddle(pointToOverride, arc);
@@ -298,26 +317,27 @@ bool SnapManager::snapToGrid(double& x, double& y)
// Check if x within snap tolerance
if (x < tmpX + snapTol && x > tmpX - snapTol) {
x = tmpX; // Snap X Mouse Position
x = tmpX;// Snap X Mouse Position
snapped = true;
}
// Check if y within snap tolerance
// Check if y within snap tolerance
if (y < tmpY + snapTol && y > tmpY - snapTol) {
y = tmpY; // Snap Y Mouse Position
y = tmpY;// Snap Y Mouse Position
snapped = true;
}
return snapped;
}
bool SnapManager::snapToLineMiddle(Base::Vector3d& pointToOverride, const Part::GeomLineSegment* line)
bool SnapManager::snapToLineMiddle(Base::Vector3d& pointToOverride,
const Part::GeomLineSegment* line)
{
Base::Vector3d startPoint = line->getStartPoint();
Base::Vector3d endPoint = line->getEndPoint();
Base::Vector3d midPoint = (startPoint + endPoint) / 2;
//Check if we are at middle of the line and if so snap to it.
// Check if we are at middle of the line and if so snap to it.
if ((pointToOverride - midPoint).Length() < (endPoint - startPoint).Length() * 0.05) {
pointToOverride = midPoint;
return true;
@@ -353,8 +373,9 @@ bool SnapManager::snapToArcMiddle(Base::Vector3d& pointToOverride, const Part::G
int revert = angle < M_PI ? 1 : -1;
/*To know if we are close to the middle of the arc, we are going to compare the angle of the
* (mouse cursor - center) to the angle of the middle of the arc. If it's less than 10% of the arc angle, then we snap.
*/
* (mouse cursor - center) to the angle of the middle of the arc. If it's less than 10% of the
* arc angle, then we snap.
*/
if (fabs(pVec.Angle() - (revert * mVec).Angle()) < 0.10 * angle) {
pointToOverride = centerPoint + middleVec * revert;
return true;
+21 -21
View File
@@ -28,14 +28,15 @@
#include <App/Application.h>
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class ViewProviderSketchSnapAttorney {
class ViewProviderSketchSnapAttorney
{
private:
static inline int getPreselectPoint(const ViewProviderSketch& vp);
static inline int getPreselectCross(const ViewProviderSketch& vp);
static inline int getPreselectCurve(const ViewProviderSketch& vp);
@@ -44,23 +45,23 @@ private:
};
/* This class is used to manage the overriding of mouse pointer coordinates in Sketcher
* (in Edit-Mode) depending on the situation. Those situations are in priority order :
* 1 - Snap at angle: For tools like Slot, Arc, Line, Ellipse, this enables to constrain the angle at steps of 5° (or customized angle).
* This is useful to make features at a certain angle (45° for example)
* 2 - Snap to object: This snaps the mouse pointer onto objects.
* 3 - Snap to grid: This snaps the mouse pointer on the grid.
*/
* (in Edit-Mode) depending on the situation. Those situations are in priority order :
* 1 - Snap at angle: For tools like Slot, Arc, Line, Ellipse, this enables to constrain the angle
* at steps of 5° (or customized angle). This is useful to make features at a certain angle (45° for
* example) 2 - Snap to object: This snaps the mouse pointer onto objects. 3 - Snap to grid: This
* snaps the mouse pointer on the grid.
*/
class SnapManager
{
/** @brief Class for monitoring changes in parameters affecting Snapping
* @details
*
* This nested class is a helper responsible for attaching to the parameters relevant for
* SnapManager, initialising the SnapManager to the current configuration
* and handle in real time any change to their values.
*/
class ParameterObserver : public ParameterGrp::ObserverType
* @details
*
* This nested class is a helper responsible for attaching to the parameters relevant for
* SnapManager, initialising the SnapManager to the current configuration
* and handle in real time any change to their values.
*/
class ParameterObserver: public ParameterGrp::ObserverType
{
public:
explicit ParameterObserver(SnapManager& client);
@@ -88,7 +89,7 @@ class SnapManager
};
public:
explicit SnapManager(ViewProviderSketch &vp);
explicit SnapManager(ViewProviderSketch& vp);
~SnapManager();
bool snap(double& x, double& y);
@@ -103,7 +104,7 @@ public:
private:
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
ViewProviderSketch & viewProvider;
ViewProviderSketch& viewProvider;
bool angleSnapRequested;
bool snapRequested;
@@ -120,8 +121,7 @@ private:
};
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_SnapManager_H
#endif// SKETCHERGUI_SnapManager_H
+34 -29
View File
@@ -22,15 +22,15 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cfloat>
# include <cmath>
#include <cfloat>
#include <cmath>
# include <Inventor/actions/SoGetMatrixAction.h>
# include <Inventor/actions/SoGLRenderAction.h>
# include <Inventor/elements/SoModelMatrixElement.h>
# include <Inventor/elements/SoViewportRegionElement.h>
# include <Inventor/elements/SoViewVolumeElement.h>
# include <Inventor/nodes/SoCamera.h>
#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/actions/SoGetMatrixAction.h>
#include <Inventor/elements/SoModelMatrixElement.h>
#include <Inventor/elements/SoViewVolumeElement.h>
#include <Inventor/elements/SoViewportRegionElement.h>
#include <Inventor/nodes/SoCamera.h>
#endif
#include "SoZoomTranslation.h"
@@ -71,28 +71,31 @@ float SoZoomTranslation::calculateScaleFactor(SoAction* action) const
// Dividing by 5 seems to work well
SbViewVolume vv = SoViewVolumeElement::get(action->getState());
float aspectRatio = SoViewportRegionElement::get(action->getState()).getViewportAspectRatio();
scaleFactor = vv.getWorldToScreenScale(SbVec3f(0.f, 0.f, 0.f), 0.1f) / (5*aspectRatio);
scaleFactor = vv.getWorldToScreenScale(SbVec3f(0.f, 0.f, 0.f), 0.1f) / (5 * aspectRatio);
return scaleFactor;
}
SoZoomTranslation::SoZoomTranslation(): scaleFactor(0)
SoZoomTranslation::SoZoomTranslation()
: scaleFactor(0)
{
SO_NODE_CONSTRUCTOR(SoZoomTranslation);
SO_NODE_ADD_FIELD(abPos, (SbVec3f(0.f,0.f,0.f)));
SO_NODE_ADD_FIELD(abPos, (SbVec3f(0.f, 0.f, 0.f)));
}
void SoZoomTranslation::GLRender(SoGLRenderAction * action)
void SoZoomTranslation::GLRender(SoGLRenderAction* action)
{
SoZoomTranslation::doAction((SoAction *)action);
SoZoomTranslation::doAction((SoAction*)action);
}
// Doc in superclass.
void SoZoomTranslation::doAction(SoAction * action)
void SoZoomTranslation::doAction(SoAction* action)
{
SbVec3f v;
if (this->translation.getValue() == SbVec3f(0.0f, 0.0f, 0.0f) && this->abPos.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)) {
if (this->translation.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)
&& this->abPos.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)) {
return;
} else {
}
else {
SbVec3f absVtr = this->abPos.getValue();
SbVec3f relVtr = this->translation.getValue();
@@ -107,19 +110,21 @@ void SoZoomTranslation::doAction(SoAction * action)
SoModelMatrixElement::translateBy(action->getState(), this, v);
}
void SoZoomTranslation::getMatrix(SoGetMatrixAction * action)
void SoZoomTranslation::getMatrix(SoGetMatrixAction* action)
{
SbVec3f v;
if (this->translation.getValue() == SbVec3f(0.0f, 0.0f, 0.0f) && this->abPos.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)) {
if (this->translation.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)
&& this->abPos.getValue() == SbVec3f(0.0f, 0.0f, 0.0f)) {
return;
} else {
}
else {
SbVec3f absVtr = this->abPos.getValue();
SbVec3f relVtr = this->translation.getValue();
float sf = this->calculateScaleFactor(action);
// For Sketcher Keep Z value the same
relVtr[0] = (relVtr[0] != 0) ? sf * relVtr[0] : 0;
relVtr[1] = (relVtr[1] != 0) ? sf * relVtr[1] : 0;
relVtr[0] = (relVtr[0] != 0) ? sf * relVtr[0] : 0;
relVtr[1] = (relVtr[1] != 0) ? sf * relVtr[1] : 0;
v = absVtr + relVtr;
}
@@ -131,23 +136,23 @@ void SoZoomTranslation::getMatrix(SoGetMatrixAction * action)
action->getInverse().multRight(m);
}
void SoZoomTranslation::callback(SoCallbackAction * action)
void SoZoomTranslation::callback(SoCallbackAction* action)
{
SoZoomTranslation::doAction((SoAction *)action);
SoZoomTranslation::doAction((SoAction*)action);
}
void SoZoomTranslation::getBoundingBox(SoGetBoundingBoxAction * action)
void SoZoomTranslation::getBoundingBox(SoGetBoundingBoxAction* action)
{
SoZoomTranslation::doAction((SoAction *)action);
SoZoomTranslation::doAction((SoAction*)action);
}
void SoZoomTranslation::pick(SoPickAction * action)
void SoZoomTranslation::pick(SoPickAction* action)
{
SoZoomTranslation::doAction((SoAction *)action);
SoZoomTranslation::doAction((SoAction*)action);
}
// Doc in superclass.
void SoZoomTranslation::getPrimitiveCount(SoGetPrimitiveCountAction * action)
void SoZoomTranslation::getPrimitiveCount(SoGetPrimitiveCountAction* action)
{
SoZoomTranslation::doAction((SoAction *)action);
SoZoomTranslation::doAction((SoAction*)action);
}
+20 -14
View File
@@ -28,9 +28,11 @@
#include <Mod/Sketcher/SketcherGlobal.h>
namespace SketcherGui {
namespace SketcherGui
{
class SketcherGuiExport SoZoomTranslation : public SoTranslation {
class SketcherGuiExport SoZoomTranslation: public SoTranslation
{
using inherited = SoTranslation;
SO_NODE_HEADER(SoZoomTranslation);
@@ -39,21 +41,25 @@ public:
static void initClass();
SoZoomTranslation();
SoSFVec3f abPos;
float getScaleFactor() const { return scaleFactor;}
float getScaleFactor() const
{
return scaleFactor;
}
protected:
~SoZoomTranslation() override {}
void doAction(SoAction * action) override;
void getPrimitiveCount(SoGetPrimitiveCountAction * action) override;
void getMatrix(SoGetMatrixAction * action) override;
void GLRender(SoGLRenderAction *action) override;
void getBoundingBox(SoGetBoundingBoxAction * action) override;
void callback(SoCallbackAction * action) override;
void pick(SoPickAction * action) override;
float calculateScaleFactor (SoAction * action) const;
~SoZoomTranslation() override
{}
void doAction(SoAction* action) override;
void getPrimitiveCount(SoGetPrimitiveCountAction* action) override;
void getMatrix(SoGetMatrixAction* action) override;
void GLRender(SoGLRenderAction* action) override;
void getBoundingBox(SoGetBoundingBoxAction* action) override;
void callback(SoCallbackAction* action) override;
void pick(SoPickAction* action) override;
float calculateScaleFactor(SoAction* action) const;
mutable float scaleFactor;
};
}
#endif // SKETCHERGUI_SOZOOMTRANSLATION_H
}// namespace SketcherGui
#endif// SKETCHERGUI_SOZOOMTRANSLATION_H
+23 -22
View File
@@ -35,8 +35,9 @@ using namespace SketcherGui;
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgEditSketch::TaskDlgEditSketch(ViewProviderSketch *sketchView)
: TaskDialog(),sketchView(sketchView)
TaskDlgEditSketch::TaskDlgEditSketch(ViewProviderSketch* sketchView)
: TaskDialog()
, sketchView(sketchView)
{
assert(sketchView);
Constraints = new TaskSketcherConstraints(sketchView);
@@ -44,25 +45,26 @@ TaskDlgEditSketch::TaskDlgEditSketch(ViewProviderSketch *sketchView)
Messages = new TaskSketcherMessages(sketchView);
SolverAdvanced = new TaskSketcherSolverAdvanced(sketchView);
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
setEscapeButtonEnabled(hGrp->GetBool("LeaveSketchWithEscape", true));
Content.push_back(Messages);
if (hGrp->GetBool("ShowSolverAdvancedWidget",false)) {
if (hGrp->GetBool("ShowSolverAdvancedWidget", false)) {
Content.push_back(SolverAdvanced);
}
Content.push_back(Constraints);
Content.push_back(Elements);
if (!hGrp->GetBool("ExpandedMessagesWidget",true))
if (!hGrp->GetBool("ExpandedMessagesWidget", true))
Messages->hideGroupBox();
if (!hGrp->GetBool("ExpandedSolverAdvancedWidget",false))
if (!hGrp->GetBool("ExpandedSolverAdvancedWidget", false))
SolverAdvanced->hideGroupBox();
if (!hGrp->GetBool("ExpandedConstraintsWidget",true))
if (!hGrp->GetBool("ExpandedConstraintsWidget", true))
Constraints->hideGroupBox();
if (!hGrp->GetBool("ExpandedElementsWidget",true))
if (!hGrp->GetBool("ExpandedElementsWidget", true))
Elements->hideGroupBox();
}
@@ -79,14 +81,10 @@ TaskDlgEditSketch::~TaskDlgEditSketch()
void TaskDlgEditSketch::open()
{
}
{}
void TaskDlgEditSketch::clicked(int)
{
}
{}
bool TaskDlgEditSketch::accept()
{
@@ -95,15 +93,18 @@ bool TaskDlgEditSketch::accept()
bool TaskDlgEditSketch::reject()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
hGrp->SetBool("ExpandedMessagesWidget",Messages->isGroupVisible());
hGrp->SetBool("ExpandedSolverAdvancedWidget",SolverAdvanced->isGroupVisible());
hGrp->SetBool("ExpandedConstraintsWidget",Constraints->isGroupVisible());
hGrp->SetBool("ExpandedElementsWidget",Elements->isGroupVisible());
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
hGrp->SetBool("ExpandedMessagesWidget", Messages->isGroupVisible());
hGrp->SetBool("ExpandedSolverAdvancedWidget", SolverAdvanced->isGroupVisible());
hGrp->SetBool("ExpandedConstraintsWidget", Constraints->isGroupVisible());
hGrp->SetBool("ExpandedElementsWidget", Elements->isGroupVisible());
std::string document = getDocumentName(); // needed because resetEdit() deletes this instance
Gui::Command::doCommand(Gui::Command::Gui,"Gui.getDocument('%s').resetEdit()", document.c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument('%s').recompute()", document.c_str());
std::string document = getDocumentName();// needed because resetEdit() deletes this instance
Gui::Command::doCommand(
Gui::Command::Gui, "Gui.getDocument('%s').resetEdit()", document.c_str());
Gui::Command::doCommand(
Gui::Command::Doc, "App.getDocument('%s').recompute()", document.c_str());
return true;
}
+20 -14
View File
@@ -36,19 +36,22 @@
using Connection = boost::signals2::connection;
namespace SketcherGui {
namespace SketcherGui
{
/// simulation dialog for the TaskView
class SketcherGuiExport TaskDlgEditSketch : public Gui::TaskView::TaskDialog
class SketcherGuiExport TaskDlgEditSketch: public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
explicit TaskDlgEditSketch(ViewProviderSketch *sketchView);
explicit TaskDlgEditSketch(ViewProviderSketch* sketchView);
~TaskDlgEditSketch() override;
ViewProviderSketch* getSketchView() const
{ return sketchView; }
{
return sketchView;
}
public:
/// is called the TaskView when the dialog is opened
@@ -60,26 +63,29 @@ public:
/// is called by the framework if the dialog is rejected (Cancel)
bool reject() override;
bool isAllowedAlterDocument() const override
{ return false; }
{
return false;
}
/// returns for Close and Help button
QDialogButtonBox::StandardButtons getStandardButtons() const override
{ return QDialogButtonBox::Close; }
{
return QDialogButtonBox::Close;
}
protected:
void slotUndoDocument(const App::Document&);
void slotRedoDocument(const App::Document&);
protected:
ViewProviderSketch *sketchView;
TaskSketcherConstraints *Constraints;
TaskSketcherElements *Elements;
TaskSketcherMessages *Messages;
TaskSketcherSolverAdvanced *SolverAdvanced;
ViewProviderSketch* sketchView;
TaskSketcherConstraints* Constraints;
TaskSketcherElements* Elements;
TaskSketcherMessages* Messages;
TaskSketcherSolverAdvanced* SolverAdvanced;
};
}// namespace SketcherGui
} //namespace SketcherGui
#endif // SKETCHERGUI_TaskDlgEditSketch_H
#endif// SKETCHERGUI_TaskDlgEditSketch_H
File diff suppressed because it is too large Load Diff
+68 -60
View File
@@ -33,35 +33,38 @@
#include "ConstraintFilters.h"
namespace App {
namespace App
{
class Property;
}
namespace Gui {
class ViewProvider;
namespace Gui
{
class ViewProvider;
}
namespace SketcherGui {
namespace SketcherGui
{
using namespace ConstraintFilter;
class ViewProviderSketch;
class Ui_TaskSketcherConstraints;
class ConstraintView : public QListWidget
class ConstraintView: public QListWidget
{
Q_OBJECT
public:
explicit ConstraintView(QWidget *parent = nullptr);
explicit ConstraintView(QWidget* parent = nullptr);
~ConstraintView() override;
protected:
void contextMenuEvent (QContextMenuEvent* event) override;
void contextMenuEvent(QContextMenuEvent* event) override;
Q_SIGNALS:
void onUpdateDrivingStatus(QListWidgetItem *item, bool status);
void onUpdateActiveStatus(QListWidgetItem *item, bool status);
void onUpdateDrivingStatus(QListWidgetItem* item, bool status);
void onUpdateActiveStatus(QListWidgetItem* item, bool status);
void emitCenterSelectedItems();
void emitHideSelection3DVisibility();
void emitShowSelection3DVisibility();
@@ -79,7 +82,7 @@ protected Q_SLOTS:
void hideConstraints();
};
class ConstraintFilterList : public QListWidget
class ConstraintFilterList: public QListWidget
{
Q_OBJECT
@@ -91,7 +94,7 @@ public:
FilterValueBitset getMultiFilter();
int normalFilterCount; //All filters but selected and associated
int normalFilterCount;// All filters but selected and associated
int selectedFilterIndex;
int associatedFilterIndex;
@@ -100,82 +103,84 @@ protected:
virtual void languageChange();
private:
using filterItemRepr = std::pair<const char*, const int>; // {filter item text, filter item level}
using filterItemRepr =
std::pair<const char*, const int>;// {filter item text, filter item level}
inline static const std::vector<filterItemRepr> filterItems = {
{QT_TR_NOOP("All"),0},
{QT_TR_NOOP("Geometric"),0},
{QT_TR_NOOP("Coincident"),1},
{QT_TR_NOOP("Point on Object"),1},
{QT_TR_NOOP("Vertical"),1},
{QT_TR_NOOP("Horizontal"),1},
{QT_TR_NOOP("Parallel"),1},
{QT_TR_NOOP("Perpendicular"),1},
{QT_TR_NOOP("Tangent"),1},
{QT_TR_NOOP("Equality"),1},
{QT_TR_NOOP("Symmetric"),1},
{QT_TR_NOOP("Block"),1},
{QT_TR_NOOP("Internal Alignment"),1},
{QT_TR_NOOP("Datums"),0},
{QT_TR_NOOP("Horizontal Distance"),1},
{QT_TR_NOOP("Vertical Distance"),1},
{QT_TR_NOOP("Distance"),1},
{QT_TR_NOOP("Radius"),1},
{QT_TR_NOOP("Weight"),1},
{QT_TR_NOOP("Diameter"),1},
{QT_TR_NOOP("Angle"),1},
{QT_TR_NOOP("Snell's Law"),1},
{QT_TR_NOOP("Named"),0},
{QT_TR_NOOP("Reference"),0},
{QT_TR_NOOP("Selected constraints"),0},
{QT_TR_NOOP("Associated constraints"),0},
{QT_TR_NOOP("All"), 0},
{QT_TR_NOOP("Geometric"), 0},
{QT_TR_NOOP("Coincident"), 1},
{QT_TR_NOOP("Point on Object"), 1},
{QT_TR_NOOP("Vertical"), 1},
{QT_TR_NOOP("Horizontal"), 1},
{QT_TR_NOOP("Parallel"), 1},
{QT_TR_NOOP("Perpendicular"), 1},
{QT_TR_NOOP("Tangent"), 1},
{QT_TR_NOOP("Equality"), 1},
{QT_TR_NOOP("Symmetric"), 1},
{QT_TR_NOOP("Block"), 1},
{QT_TR_NOOP("Internal Alignment"), 1},
{QT_TR_NOOP("Datums"), 0},
{QT_TR_NOOP("Horizontal Distance"), 1},
{QT_TR_NOOP("Vertical Distance"), 1},
{QT_TR_NOOP("Distance"), 1},
{QT_TR_NOOP("Radius"), 1},
{QT_TR_NOOP("Weight"), 1},
{QT_TR_NOOP("Diameter"), 1},
{QT_TR_NOOP("Angle"), 1},
{QT_TR_NOOP("Snell's Law"), 1},
{QT_TR_NOOP("Named"), 0},
{QT_TR_NOOP("Reference"), 0},
{QT_TR_NOOP("Selected constraints"), 0},
{QT_TR_NOOP("Associated constraints"), 0},
};
};
class TaskSketcherConstraints :
public Gui::TaskView::TaskBox,
public Gui::SelectionObserver,
public ParameterGrp::ObserverType
class TaskSketcherConstraints: public Gui::TaskView::TaskBox,
public Gui::SelectionObserver,
public ParameterGrp::ObserverType
{
Q_OBJECT
enum class ActionTarget {
enum class ActionTarget
{
All,
Selected
};
enum class SpecialFilterType {
enum class SpecialFilterType
{
None,
Associated,
Selected
};
public:
explicit TaskSketcherConstraints(ViewProviderSketch *sketchView);
explicit TaskSketcherConstraints(ViewProviderSketch* sketchView);
~TaskSketcherConstraints() override;
/// Observer message from the Selection
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
void OnChange(Base::Subject<const char*> &rCaller,const char* rcReason) override;
void OnChange(Base::Subject<const char*>& rCaller, const char* rcReason) override;
SpecialFilterType specialFilterMode;
private:
void slotConstraintsChanged();
bool isConstraintFiltered(QListWidgetItem * item);
bool isConstraintFiltered(QListWidgetItem* item);
void change3DViewVisibilityToTrackFilter();
void changeFilteredVisibility(bool show, ActionTarget target = ActionTarget::All);
void updateSelectionFilter();
void updateAssociatedConstraintsFilter();
void updateList();
void getSelectionGeoId(QString expr, int & geoid, Sketcher::PointPos & pos);
void getSelectionGeoId(QString expr, int& geoid, Sketcher::PointPos& pos);
public:
void onListWidgetConstraintsItemSelectionChanged();
void onListWidgetConstraintsItemActivated(QListWidgetItem *item);
void onListWidgetConstraintsItemChanged(QListWidgetItem * item);
void onListWidgetConstraintsUpdateDrivingStatus(QListWidgetItem *item, bool status);
void onListWidgetConstraintsUpdateActiveStatus(QListWidgetItem *item, bool status);
void onListWidgetConstraintsItemActivated(QListWidgetItem* item);
void onListWidgetConstraintsItemChanged(QListWidgetItem* item);
void onListWidgetConstraintsUpdateDrivingStatus(QListWidgetItem* item, bool status);
void onListWidgetConstraintsUpdateActiveStatus(QListWidgetItem* item, bool status);
void onListWidgetConstraintsEmitCenterSelectedItems();
void onListWidgetConstraintsEmitShowSelection3DVisibility();
void onListWidgetConstraintsEmitHideSelection3DVisibility();
@@ -189,8 +194,8 @@ public:
void onFilterListItemChanged(QListWidgetItem* item);
protected:
void changeEvent(QEvent *e) override;
ViewProviderSketch *sketchView;
void changeEvent(QEvent* e) override;
ViewProviderSketch* sketchView;
using Connection = boost::signals2::connection;
Connection connectionConstraintsChanged;
@@ -201,14 +206,17 @@ private:
QWidget* proxy;
bool inEditMode;
std::unique_ptr<Ui_TaskSketcherConstraints> ui;
ConstraintFilter::FilterValueBitset multiFilterStatus; // Stores the filters to be aggregated to form the multifilter.
std::vector<unsigned int> selectionFilter; // holds the constraint ids of the selected constraints
std::vector<unsigned int> associatedConstraintsFilter; // holds the constraint ids of the constraints associated with the selected geometry
ConstraintFilter::FilterValueBitset
multiFilterStatus;// Stores the filters to be aggregated to form the multifilter.
std::vector<unsigned int>
selectionFilter;// holds the constraint ids of the selected constraints
std::vector<unsigned int>
associatedConstraintsFilter;// holds the constraint ids of the constraints associated with
// the selected geometry
ConstraintFilterList* filterList;
boost::signals2::scoped_connection changedSketchView;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H
#endif// GUI_TASKVIEW_TASKAPPERANCE_H
@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QEvent>
#include <QEvent>
#endif
#include <Gui/BitmapFactory.h>
@@ -32,55 +32,52 @@
using namespace Gui::TaskView;
TaskSketcherCreateCommands::TaskSketcherCreateCommands(QWidget *parent)
: TaskBox(Gui::BitmapFactory().pixmap("document-new"),tr("Appearance"),true, parent)
TaskSketcherCreateCommands::TaskSketcherCreateCommands(QWidget* parent)
: TaskBox(Gui::BitmapFactory().pixmap("document-new"), tr("Appearance"), true, parent)
{
// we need a separate container widget to add all controls to
//proxy = new QWidget(this);
//ui = new Ui_TaskAppearance();
//ui->setupUi(proxy);
//ui->textLabel1_3->hide();
//ui->changePlot->hide();
//QMetaObject::connectSlotsByName(this);
// proxy = new QWidget(this);
// ui = new Ui_TaskAppearance();
// ui->setupUi(proxy);
// ui->textLabel1_3->hide();
// ui->changePlot->hide();
// QMetaObject::connectSlotsByName(this);
//this->groupLayout()->addWidget(proxy);
// this->groupLayout()->addWidget(proxy);
//std::vector<Gui::ViewProvider*> views;
//setDisplayModes(views);
//setPointSize(views);
//setLineWidth(views);
//setTransparency(views);
// std::vector<Gui::ViewProvider*> views;
// setDisplayModes(views);
// setPointSize(views);
// setLineWidth(views);
// setTransparency(views);
Gui::Selection().Attach(this);
}
TaskSketcherCreateCommands::~TaskSketcherCreateCommands()
{
//delete ui;
// delete ui;
Gui::Selection().Detach(this);
}
void TaskSketcherCreateCommands::changeEvent(QEvent *e)
void TaskSketcherCreateCommands::changeEvent(QEvent* e)
{
TaskBox::changeEvent(e);
//if (e->type() == QEvent::LanguageChange) {
// ui->retranslateUi(proxy);
//}
// if (e->type() == QEvent::LanguageChange) {
// ui->retranslateUi(proxy);
// }
}
/// @cond DOXERR
void TaskSketcherCreateCommands::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason)
void TaskSketcherCreateCommands::OnChange(Gui::SelectionSingleton::SubjectType& rCaller,
Gui::SelectionSingleton::MessageType Reason)
{
Q_UNUSED(rCaller);
if (Reason.Type == SelectionChanges::AddSelection ||
Reason.Type == SelectionChanges::RmvSelection ||
Reason.Type == SelectionChanges::SetSelection ||
Reason.Type == SelectionChanges::ClrSelection) {
}
if (Reason.Type == SelectionChanges::AddSelection
|| Reason.Type == SelectionChanges::RmvSelection
|| Reason.Type == SelectionChanges::SetSelection
|| Reason.Type == SelectionChanges::ClrSelection) {}
}
/// @endcond DOXERR
#include "moc_TaskSketcherCreateCommands.cpp"
@@ -27,38 +27,40 @@
#include <Gui/TaskView/TaskView.h>
namespace App {
namespace App
{
class Property;
}
namespace Gui {
namespace Gui
{
class ViewProvider;
namespace TaskView {
namespace TaskView
{
class TaskSketcherCreateCommands : public TaskBox, public Gui::SelectionSingleton::ObserverType
class TaskSketcherCreateCommands: public TaskBox, public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
explicit TaskSketcherCreateCommands(QWidget *parent = nullptr);
explicit TaskSketcherCreateCommands(QWidget* parent = nullptr);
~TaskSketcherCreateCommands() override;
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
void OnChange(Gui::SelectionSingleton::SubjectType& rCaller,
Gui::SelectionSingleton::MessageType Reason) override;
private Q_SLOTS:
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
//QWidget* proxy;
// QWidget* proxy;
};
} //namespace TaskView
} //namespace Gui
}// namespace TaskView
}// namespace Gui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H
#endif// GUI_TASKVIEW_TASKAPPERANCE_H
File diff suppressed because it is too large Load Diff
+19 -17
View File
@@ -23,8 +23,8 @@
#ifndef GUI_TASKVIEW_TaskSketcherElements_H
#define GUI_TASKVIEW_TaskSketcherElements_H
#include <QStyledItemDelegate>
#include <QListWidget>
#include <QStyledItemDelegate>
#include <boost_signals2.hpp>
@@ -32,22 +32,24 @@
#include <Gui/TaskView/TaskView.h>
namespace App {
namespace App
{
class Property;
}
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class Ui_TaskSketcherElements;
class ElementItem;
class ElementView;
// Struct to identify the selection/preselection of a subelement of the item
enum class SubElementType {
enum class SubElementType
{
edge,
start,
end,
@@ -55,17 +57,17 @@ enum class SubElementType {
none
};
class ElementView : public QListWidget
class ElementView: public QListWidget
{
Q_OBJECT
public:
explicit ElementView(QWidget *parent = nullptr);
explicit ElementView(QWidget* parent = nullptr);
~ElementView() override;
ElementItem* itemFromIndex(const QModelIndex& index);
protected:
void contextMenuEvent (QContextMenuEvent* event) override;
void contextMenuEvent(QContextMenuEvent* event) override;
protected Q_SLOTS:
// Constraints
@@ -103,7 +105,7 @@ protected Q_SLOTS:
void onIndexChecked(QModelIndex, Qt::CheckState state);
Q_SIGNALS:
void onItemHovered(QListWidgetItem *);
void onItemHovered(QListWidgetItem*);
private:
void changeLayer(int layer);
@@ -111,12 +113,12 @@ private:
class ElementFilterList;
class TaskSketcherElements : public Gui::TaskView::TaskBox, public Gui::SelectionObserver
class TaskSketcherElements: public Gui::TaskView::TaskBox, public Gui::SelectionObserver
{
Q_OBJECT
public:
explicit TaskSketcherElements(ViewProviderSketch *sketchView);
explicit TaskSketcherElements(ViewProviderSketch* sketchView);
~TaskSketcherElements() override;
/// Observer message from the Selection
@@ -133,16 +135,16 @@ private:
public Q_SLOTS:
void onListWidgetElementsItemPressed(QListWidgetItem* item);
void onListWidgetElementsItemEntered(QListWidgetItem *item);
void onListWidgetElementsItemEntered(QListWidgetItem* item);
void onListWidgetElementsMouseMoveOnItem(QListWidgetItem* item);
void onSettingsExtendedInformationChanged();
void onFilterBoxStateChanged(int val);
void onListMultiFilterItemChanged(QListWidgetItem* item);
protected:
void changeEvent(QEvent *e) override;
void leaveEvent ( QEvent * event ) override;
ViewProviderSketch *sketchView;
void changeEvent(QEvent* e) override;
void leaveEvent(QEvent* event) override;
ViewProviderSketch* sketchView;
using Connection = boost::signals2::connection;
Connection connectionElementsChanged;
@@ -159,6 +161,6 @@ private:
bool isNamingBoxChecked;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // GUI_TASKVIEW_TASKAPPERANCE_H
#endif// GUI_TASKVIEW_TASKAPPERANCE_H
+82 -56
View File
@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QAction>
#include <QAction>
#endif
#include <Gui/Application.h>
@@ -30,19 +30,19 @@
#include <Gui/Command.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ui_TaskSketcherMessages.h"
#include "TaskSketcherMessages.h"
#include "ViewProviderSketch.h"
#include "ui_TaskSketcherMessages.h"
using namespace SketcherGui;
using namespace Gui::TaskView;
namespace bp = boost::placeholders;
TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
TaskBox(Gui::BitmapFactory().pixmap("document-new"), tr("Solver messages"), true, nullptr),
sketchView(sketchView),
ui(new Ui_TaskSketcherMessages)
TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch* sketchView)
: TaskBox(Gui::BitmapFactory().pixmap("document-new"), tr("Solver messages"), true, nullptr)
, sketchView(sketchView)
, ui(new Ui_TaskSketcherMessages)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
@@ -51,25 +51,44 @@ TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
this->groupLayout()->addWidget(proxy);
connectionSetUp = sketchView->signalSetUp.connect(boost::bind(&SketcherGui::TaskSketcherMessages::slotSetUp, this, bp::_1, bp::_2, bp::_3, bp::_4));
connectionSetUp = sketchView->signalSetUp.connect(boost::bind(
&SketcherGui::TaskSketcherMessages::slotSetUp, this, bp::_1, bp::_2, bp::_3, bp::_4));
ui->labelConstrainStatus->setOpenExternalLinks(false);
// Set up the possible state values for the status label
ui->labelConstrainStatus->setParameterGroup("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ui->labelConstrainStatus->registerState(QString::fromUtf8("empty_sketch"), palette().windowText().color(), std::string("EmptySketchMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("under_constrained"), palette().windowText().color(), std::string("UnderconstrainedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("malformed_constraints"), QColor("red"), std::string("MalformedConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("conflicting_constraints"), QColor("orangered"), std::string("ConflictingConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("redundant_constraints"), QColor("red"), std::string("RedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("partially_redundant_constraints"), QColor("royalblue"), std::string("PartiallyRedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("solver_failed"), QColor("red"), std::string("SolverFailedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("fully_constrained"), QColor("green"), std::string("FullyConstrainedMessageColor"));
ui->labelConstrainStatus->setParameterGroup(
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ui->labelConstrainStatus->registerState(QString::fromUtf8("empty_sketch"),
palette().windowText().color(),
std::string("EmptySketchMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("under_constrained"),
palette().windowText().color(),
std::string("UnderconstrainedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("malformed_constraints"),
QColor("red"),
std::string("MalformedConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("conflicting_constraints"),
QColor("orangered"),
std::string("ConflictingConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("redundant_constraints"),
QColor("red"),
std::string("RedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(
QString::fromUtf8("partially_redundant_constraints"),
QColor("royalblue"),
std::string("PartiallyRedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(
QString::fromUtf8("solver_failed"), QColor("red"), std::string("SolverFailedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("fully_constrained"),
QColor("green"),
std::string("FullyConstrainedMessageColor"));
ui->labelConstrainStatusLink->setLaunchExternal(false);
//Set Auto Update in the 'Manual Update' button menu.
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
// Set Auto Update in the 'Manual Update' button menu.
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
bool state = hGrp->GetBool("AutoRecompute", false);
sketchView->getSketchObject()->noRecomputes = !state;
@@ -80,10 +99,10 @@ TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
action->setChecked(state);
ui->manualUpdate->addAction(action);
QObject::connect(
qAsConst(ui->manualUpdate)->actions()[0], &QAction::changed,
this, &TaskSketcherMessages::onAutoUpdateStateChanged
);
QObject::connect(qAsConst(ui->manualUpdate)->actions()[0],
&QAction::changed,
this,
&TaskSketcherMessages::onAutoUpdateStateChanged);
}
TaskSketcherMessages::~TaskSketcherMessages()
@@ -93,13 +112,18 @@ TaskSketcherMessages::~TaskSketcherMessages()
void TaskSketcherMessages::setupConnections()
{
connect(ui->labelConstrainStatusLink, &Gui::UrlLabel::linkClicked,
this, &TaskSketcherMessages::onLabelConstrainStatusLinkClicked);
connect(ui->manualUpdate, &QToolButton::clicked,
this, &TaskSketcherMessages::onManualUpdateClicked);
connect(ui->labelConstrainStatusLink,
&Gui::UrlLabel::linkClicked,
this,
&TaskSketcherMessages::onLabelConstrainStatusLinkClicked);
connect(ui->manualUpdate,
&QToolButton::clicked,
this,
&TaskSketcherMessages::onManualUpdateClicked);
}
void TaskSketcherMessages::slotSetUp(const QString& state, const QString& msg, const QString& link, const QString& linkText)
void TaskSketcherMessages::slotSetUp(const QString& state, const QString& msg, const QString& link,
const QString& linkText)
{
ui->labelConstrainStatus->setState(state);
ui->labelConstrainStatus->setText(msg);
@@ -110,46 +134,48 @@ void TaskSketcherMessages::slotSetUp(const QString& state, const QString& msg, c
void TaskSketcherMessages::updateToolTip(const QString& link)
{
if( link == QString::fromLatin1("#conflicting"))
ui->labelConstrainStatusLink->setToolTip(tr("Click to select the conflicting constraints."));
else
if( link == QString::fromLatin1("#redundant"))
if (link == QString::fromLatin1("#conflicting"))
ui->labelConstrainStatusLink->setToolTip(
tr("Click to select the conflicting constraints."));
else if (link == QString::fromLatin1("#redundant"))
ui->labelConstrainStatusLink->setToolTip(tr("Click to select the redundant constraints."));
else
if( link == QString::fromLatin1("#dofs"))
ui->labelConstrainStatusLink->setToolTip(tr("The sketch has unconstrained elements giving rise to those Degrees Of Freedom. Click to select the unconstrained elements."));
else
if( link == QString::fromLatin1("#malformed"))
else if (link == QString::fromLatin1("#dofs"))
ui->labelConstrainStatusLink->setToolTip(
tr("The sketch has unconstrained elements giving rise to those Degrees Of Freedom. "
"Click to select the unconstrained elements."));
else if (link == QString::fromLatin1("#malformed"))
ui->labelConstrainStatusLink->setToolTip(tr("Click to select the malformed constraints."));
else
if( link == QString::fromLatin1("#partiallyredundant"))
ui->labelConstrainStatusLink->setToolTip(tr("Some constraints in combination are partially redundant. Click to select the partially redundant constraints."));
else if (link == QString::fromLatin1("#partiallyredundant"))
ui->labelConstrainStatusLink->setToolTip(
tr("Some constraints in combination are partially redundant. Click to select the "
"partially redundant constraints."));
}
void TaskSketcherMessages::onLabelConstrainStatusLinkClicked(const QString &str)
void TaskSketcherMessages::onLabelConstrainStatusLinkClicked(const QString& str)
{
if( str == QString::fromLatin1("#conflicting"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectConflictingConstraints");
else
if( str == QString::fromLatin1("#redundant"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectRedundantConstraints");
else
if( str == QString::fromLatin1("#dofs"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectElementsWithDoFs");
else
if( str == QString::fromLatin1("#malformed"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectMalformedConstraints");
else
if( str == QString::fromLatin1("#partiallyredundant"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectPartiallyRedundantConstraints");
if (str == QString::fromLatin1("#conflicting"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectConflictingConstraints");
else if (str == QString::fromLatin1("#redundant"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectRedundantConstraints");
else if (str == QString::fromLatin1("#dofs"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectElementsWithDoFs");
else if (str == QString::fromLatin1("#malformed"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectMalformedConstraints");
else if (str == QString::fromLatin1("#partiallyredundant"))
Gui::Application::Instance->commandManager().runCommandByName(
"Sketcher_SelectPartiallyRedundantConstraints");
}
void TaskSketcherMessages::onAutoUpdateStateChanged()
{
bool state = qAsConst(ui->manualUpdate)->actions()[0]->isChecked();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher");
hGrp->SetBool("AutoRecompute", state);
sketchView->getSketchObject()->noRecomputes = !state;
}
+13 -10
View File
@@ -31,34 +31,37 @@
class Ui_TaskSketcherMessages;
using Connection = boost::signals2::connection;
namespace App {
namespace App
{
class Property;
}
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class TaskSketcherMessages : public Gui::TaskView::TaskBox
class TaskSketcherMessages: public Gui::TaskView::TaskBox
{
Q_OBJECT
public:
explicit TaskSketcherMessages(ViewProviderSketch *sketchView);
explicit TaskSketcherMessages(ViewProviderSketch* sketchView);
~TaskSketcherMessages() override;
void slotSetUp(const QString& state, const QString& msg, const QString& link, const QString& linkText);
void slotSetUp(const QString& state, const QString& msg, const QString& link,
const QString& linkText);
private:
void setupConnections();
void onLabelConstrainStatusLinkClicked(const QString &);
void onLabelConstrainStatusLinkClicked(const QString&);
void onAutoUpdateStateChanged();
void onManualUpdateClicked(bool checked);
void updateToolTip(const QString& link);
protected:
ViewProviderSketch *sketchView;
ViewProviderSketch* sketchView;
Connection connectionSetUp;
private:
@@ -66,6 +69,6 @@ private:
std::unique_ptr<Ui_TaskSketcherMessages> ui;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // GUI_TASKVIEW_TaskSketcherMessages_H
#endif// GUI_TASKVIEW_TaskSketcherMessages_H
@@ -22,41 +22,42 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QString>
#include <QString>
#endif
#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ui_TaskSketcherSolverAdvanced.h"
#include "TaskSketcherSolverAdvanced.h"
#include "ViewProviderSketch.h"
#include "ui_TaskSketcherSolverAdvanced.h"
#define LM_EPS 1E-10
#define LM_EPS 1E-10
#define LM_EPS1 1E-80
#define LM_TAU 1E-3
#define LM_TAU 1E-3
#define DL_TOLG 1E-80
#define DL_TOLX 1E-80
#define DL_TOLF 1E-10
#define CONVERGENCE 1E-10
#define MAX_ITER 100
#define DEFAULT_SOLVER 2 // DL=2, LM=1, BFGS=0
#define DEFAULT_RSOLVER 2 // DL=2, LM=1, BFGS=0
#define DEFAULT_QRSOLVER 1 // DENSE=0, SPARSEQR=1
#define QR_PIVOT_THRESHOLD 1E-13 // under this value a Jacobian value is regarded as zero
#define DEFAULT_SOLVER_DEBUG 1 // None=0, Minimal=1, IterationLevel=2
#define DEFAULT_SOLVER 2 // DL=2, LM=1, BFGS=0
#define DEFAULT_RSOLVER 2 // DL=2, LM=1, BFGS=0
#define DEFAULT_QRSOLVER 1 // DENSE=0, SPARSEQR=1
#define QR_PIVOT_THRESHOLD 1E-13// under this value a Jacobian value is regarded as zero
#define DEFAULT_SOLVER_DEBUG 1 // None=0, Minimal=1, IterationLevel=2
#define MAX_ITER_MULTIPLIER false
#define DEFAULT_DOGLEG_GAUSS_STEP 0 // FullPivLU = 0, LeastNormFullPivLU = 1, LeastNormLdlt = 2
#define DEFAULT_DOGLEG_GAUSS_STEP 0// FullPivLU = 0, LeastNormFullPivLU = 1, LeastNormLdlt = 2
using namespace SketcherGui;
using namespace Gui::TaskView;
TaskSketcherSolverAdvanced::TaskSketcherSolverAdvanced(ViewProviderSketch *sketchView) :
TaskBox(Gui::BitmapFactory().pixmap("document-new"), tr("Advanced solver control"), true, nullptr),
sketchView(sketchView),
ui(new Ui_TaskSketcherSolverAdvanced)
TaskSketcherSolverAdvanced::TaskSketcherSolverAdvanced(ViewProviderSketch* sketchView)
: TaskBox(Gui::BitmapFactory().pixmap("document-new"), tr("Advanced solver control"), true,
nullptr)
, sketchView(sketchView)
, ui(new Ui_TaskSketcherSolverAdvanced)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
@@ -82,68 +83,107 @@ TaskSketcherSolverAdvanced::TaskSketcherSolverAdvanced(ViewProviderSketch *sketc
}
TaskSketcherSolverAdvanced::~TaskSketcherSolverAdvanced()
{
}
{}
void TaskSketcherSolverAdvanced::setupConnections()
{
connect(ui->comboBoxDefaultSolver, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskSketcherSolverAdvanced::onComboBoxDefaultSolverCurrentIndexChanged);
connect(ui->comboBoxDogLegGaussStep, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskSketcherSolverAdvanced::onComboBoxDogLegGaussStepCurrentIndexChanged);
connect(ui->spinBoxMaxIter, qOverload<int>(&QSpinBox::valueChanged),
this, &TaskSketcherSolverAdvanced::onSpinBoxMaxIterValueChanged);
connect(ui->checkBoxSketchSizeMultiplier, &QCheckBox::stateChanged,
this, &TaskSketcherSolverAdvanced::onCheckBoxSketchSizeMultiplierStateChanged);
connect(ui->lineEditConvergence, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditConvergenceEditingFinished);
connect(ui->comboBoxQRMethod, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskSketcherSolverAdvanced::onComboBoxQRMethodCurrentIndexChanged);
connect(ui->lineEditQRPivotThreshold, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditQRPivotThresholdEditingFinished);
connect(ui->comboBoxRedundantDefaultSolver, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskSketcherSolverAdvanced::onComboBoxRedundantDefaultSolverCurrentIndexChanged);
connect(ui->lineEditRedundantConvergence, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditRedundantConvergenceEditingFinished);
connect(ui->spinBoxRedundantSolverMaxIterations, qOverload<int>(&QSpinBox::valueChanged),
this, &TaskSketcherSolverAdvanced::onSpinBoxRedundantSolverMaxIterationsValueChanged);
connect(ui->checkBoxRedundantSketchSizeMultiplier, &QCheckBox::stateChanged,
this, &TaskSketcherSolverAdvanced::onCheckBoxRedundantSketchSizeMultiplierStateChanged);
connect(ui->comboBoxDebugMode, qOverload<int>(&QComboBox::currentIndexChanged),
this, &TaskSketcherSolverAdvanced::onComboBoxDebugModeCurrentIndexChanged);
connect(ui->lineEditSolverParam1, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditSolverParam1EditingFinished);
connect(ui->lineEditRedundantSolverParam1, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam1EditingFinished);
connect(ui->lineEditSolverParam2, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditSolverParam2EditingFinished);
connect(ui->lineEditRedundantSolverParam2, &Gui::PrefLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam2EditingFinished);
connect(ui->lineEditSolverParam3, &QLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditSolverParam3EditingFinished);
connect(ui->lineEditRedundantSolverParam3, &Gui::PrefLineEdit::editingFinished,
this, &TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam3EditingFinished);
connect(ui->pushButtonDefaults, &QPushButton::clicked,
this, &TaskSketcherSolverAdvanced::onPushButtonDefaultsClicked);
connect(ui->pushButtonSolve, &QPushButton::clicked,
this, &TaskSketcherSolverAdvanced::onPushButtonSolveClicked);
connect(ui->comboBoxDefaultSolver,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskSketcherSolverAdvanced::onComboBoxDefaultSolverCurrentIndexChanged);
connect(ui->comboBoxDogLegGaussStep,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskSketcherSolverAdvanced::onComboBoxDogLegGaussStepCurrentIndexChanged);
connect(ui->spinBoxMaxIter,
qOverload<int>(&QSpinBox::valueChanged),
this,
&TaskSketcherSolverAdvanced::onSpinBoxMaxIterValueChanged);
connect(ui->checkBoxSketchSizeMultiplier,
&QCheckBox::stateChanged,
this,
&TaskSketcherSolverAdvanced::onCheckBoxSketchSizeMultiplierStateChanged);
connect(ui->lineEditConvergence,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditConvergenceEditingFinished);
connect(ui->comboBoxQRMethod,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskSketcherSolverAdvanced::onComboBoxQRMethodCurrentIndexChanged);
connect(ui->lineEditQRPivotThreshold,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditQRPivotThresholdEditingFinished);
connect(ui->comboBoxRedundantDefaultSolver,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskSketcherSolverAdvanced::onComboBoxRedundantDefaultSolverCurrentIndexChanged);
connect(ui->lineEditRedundantConvergence,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditRedundantConvergenceEditingFinished);
connect(ui->spinBoxRedundantSolverMaxIterations,
qOverload<int>(&QSpinBox::valueChanged),
this,
&TaskSketcherSolverAdvanced::onSpinBoxRedundantSolverMaxIterationsValueChanged);
connect(ui->checkBoxRedundantSketchSizeMultiplier,
&QCheckBox::stateChanged,
this,
&TaskSketcherSolverAdvanced::onCheckBoxRedundantSketchSizeMultiplierStateChanged);
connect(ui->comboBoxDebugMode,
qOverload<int>(&QComboBox::currentIndexChanged),
this,
&TaskSketcherSolverAdvanced::onComboBoxDebugModeCurrentIndexChanged);
connect(ui->lineEditSolverParam1,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditSolverParam1EditingFinished);
connect(ui->lineEditRedundantSolverParam1,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam1EditingFinished);
connect(ui->lineEditSolverParam2,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditSolverParam2EditingFinished);
connect(ui->lineEditRedundantSolverParam2,
&Gui::PrefLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam2EditingFinished);
connect(ui->lineEditSolverParam3,
&QLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditSolverParam3EditingFinished);
connect(ui->lineEditRedundantSolverParam3,
&Gui::PrefLineEdit::editingFinished,
this,
&TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam3EditingFinished);
connect(ui->pushButtonDefaults,
&QPushButton::clicked,
this,
&TaskSketcherSolverAdvanced::onPushButtonDefaultsClicked);
connect(ui->pushButtonSolve,
&QPushButton::clicked,
this,
&TaskSketcherSolverAdvanced::onPushButtonSolveClicked);
}
void TaskSketcherSolverAdvanced::updateDefaultMethodParameters()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
int currentindex = ui->comboBoxDefaultSolver->currentIndex();
int redundantcurrentindex = ui->comboBoxRedundantDefaultSolver->currentIndex();
if(redundantcurrentindex == 2 || currentindex == 2)
if (redundantcurrentindex == 2 || currentindex == 2)
ui->comboBoxDogLegGaussStep->setEnabled(true);
else
ui->comboBoxDogLegGaussStep->setEnabled(false);
switch(currentindex)
{
case 0: // BFGS
switch (currentindex) {
case 0:// BFGS
ui->labelSolverParam1->setText(QString::fromLatin1(""));
ui->labelSolverParam2->setText(QString::fromLatin1(""));
ui->labelSolverParam3->setText(QString::fromLatin1(""));
@@ -154,7 +194,7 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters()
ui->lineEditSolverParam2->setDisabled(true);
ui->lineEditSolverParam3->setDisabled(true);
break;
case 1: // LM
case 1:// LM
{
ui->labelSolverParam1->setText(QString::fromLatin1("Eps"));
ui->labelSolverParam2->setText(QString::fromLatin1("Eps1"));
@@ -162,21 +202,36 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters()
ui->lineEditSolverParam1->setEnabled(true);
ui->lineEditSolverParam2->setEnabled(true);
ui->lineEditSolverParam3->setEnabled(true);
double eps = ::atof(hGrp->GetASCII("LM_eps",QString::number(LM_EPS).toUtf8()).c_str());
double eps1 = ::atof(hGrp->GetASCII("LM_eps1",QString::number(LM_EPS1).toUtf8()).c_str());
double tau = ::atof(hGrp->GetASCII("LM_tau",QString::number(LM_TAU).toUtf8()).c_str());
ui->lineEditSolverParam1->setText(QString::number(eps).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditSolverParam2->setText(QString::number(eps1).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditSolverParam3->setText(QString::number(tau).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
// SketchObject has encapsulated write-access. The current use of const_cast just for configuration is
// deemed acceptable. Eventually this dialog should be rewritten to include only useful information and the configuration
// centralised in an individual configuration object, possibly compatible with several solvers (e.g. DeepSOIC's ConstraintSolver)
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps(eps);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1(eps1);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_tau(tau);
double eps = ::atof(hGrp->GetASCII("LM_eps", QString::number(LM_EPS).toUtf8()).c_str());
double eps1 =
::atof(hGrp->GetASCII("LM_eps1", QString::number(LM_EPS1).toUtf8()).c_str());
double tau = ::atof(hGrp->GetASCII("LM_tau", QString::number(LM_TAU).toUtf8()).c_str());
ui->lineEditSolverParam1->setText(QString::number(eps).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditSolverParam2->setText(QString::number(eps1).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditSolverParam3->setText(QString::number(tau).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
// SketchObject has encapsulated write-access. The current use of const_cast just for
// configuration is deemed acceptable. Eventually this dialog should be rewritten to
// include only useful information and the configuration centralised in an individual
// configuration object, possibly compatible with several solvers (e.g. DeepSOIC's
// ConstraintSolver)
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps(eps);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps1(eps1);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_tau(tau);
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
ui->labelSolverParam1->setText(QString::fromLatin1("Tolg"));
ui->labelSolverParam2->setText(QString::fromLatin1("Tolx"));
@@ -184,15 +239,30 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters()
ui->lineEditSolverParam1->setEnabled(true);
ui->lineEditSolverParam2->setEnabled(true);
ui->lineEditSolverParam3->setEnabled(true);
double tolg = ::atof(hGrp->GetASCII("DL_tolg",QString::number(DL_TOLG).toUtf8()).c_str());
double tolx = ::atof(hGrp->GetASCII("DL_tolx",QString::number(DL_TOLX).toUtf8()).c_str());
double tolf = ::atof(hGrp->GetASCII("DL_tolf",QString::number(DL_TOLF).toUtf8()).c_str());
ui->lineEditSolverParam1->setText(QString::number(tolg).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditSolverParam2->setText(QString::number(tolx).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditSolverParam3->setText(QString::number(tolf).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolg(tolg);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolf(tolf);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolx(tolx);
double tolg =
::atof(hGrp->GetASCII("DL_tolg", QString::number(DL_TOLG).toUtf8()).c_str());
double tolx =
::atof(hGrp->GetASCII("DL_tolx", QString::number(DL_TOLX).toUtf8()).c_str());
double tolf =
::atof(hGrp->GetASCII("DL_tolf", QString::number(DL_TOLF).toUtf8()).c_str());
ui->lineEditSolverParam1->setText(QString::number(tolg).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditSolverParam2->setText(QString::number(tolx).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditSolverParam3->setText(QString::number(tolf).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolg(tolg);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolf(tolf);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolx(tolx);
break;
}
}
@@ -200,19 +270,19 @@ void TaskSketcherSolverAdvanced::updateDefaultMethodParameters()
void TaskSketcherSolverAdvanced::updateRedundantMethodParameters()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
int currentindex = ui->comboBoxDefaultSolver->currentIndex();
int redundantcurrentindex = ui->comboBoxRedundantDefaultSolver->currentIndex();
if(redundantcurrentindex == 2 || currentindex == 2)
if (redundantcurrentindex == 2 || currentindex == 2)
ui->comboBoxDogLegGaussStep->setEnabled(true);
else
ui->comboBoxDogLegGaussStep->setEnabled(false);
switch(redundantcurrentindex)
{
case 0: // BFGS
switch (redundantcurrentindex) {
case 0:// BFGS
ui->labelRedundantSolverParam1->setText(QString::fromLatin1(""));
ui->labelRedundantSolverParam2->setText(QString::fromLatin1(""));
ui->labelRedundantSolverParam3->setText(QString::fromLatin1(""));
@@ -223,7 +293,7 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters()
ui->lineEditRedundantSolverParam2->setDisabled(true);
ui->lineEditRedundantSolverParam3->setDisabled(true);
break;
case 1: // LM
case 1:// LM
{
ui->labelRedundantSolverParam1->setText(QString::fromLatin1("R.Eps"));
ui->labelRedundantSolverParam2->setText(QString::fromLatin1("R.Eps1"));
@@ -231,18 +301,33 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters()
ui->lineEditRedundantSolverParam1->setEnabled(true);
ui->lineEditRedundantSolverParam2->setEnabled(true);
ui->lineEditRedundantSolverParam3->setEnabled(true);
double eps = ::atof(hGrp->GetASCII("Redundant_LM_eps",QString::number(LM_EPS).toUtf8()).c_str());
double eps1 = ::atof(hGrp->GetASCII("Redundant_LM_eps1",QString::number(LM_EPS1).toUtf8()).c_str());
double tau = ::atof(hGrp->GetASCII("Redundant_LM_tau",QString::number(LM_TAU).toUtf8()).c_str());
ui->lineEditRedundantSolverParam1->setText(QString::number(eps).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditRedundantSolverParam2->setText(QString::number(eps1).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditRedundantSolverParam3->setText(QString::number(tau).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_epsRedundant(eps);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1Redundant(eps1);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_tauRedundant(eps1);
double eps = ::atof(
hGrp->GetASCII("Redundant_LM_eps", QString::number(LM_EPS).toUtf8()).c_str());
double eps1 = ::atof(
hGrp->GetASCII("Redundant_LM_eps1", QString::number(LM_EPS1).toUtf8()).c_str());
double tau = ::atof(
hGrp->GetASCII("Redundant_LM_tau", QString::number(LM_TAU).toUtf8()).c_str());
ui->lineEditRedundantSolverParam1->setText(QString::number(eps).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditRedundantSolverParam2->setText(QString::number(eps1).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditRedundantSolverParam3->setText(QString::number(tau).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_epsRedundant(eps);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps1Redundant(eps1);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_tauRedundant(eps1);
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
ui->labelRedundantSolverParam1->setText(QString::fromLatin1("R.Tolg"));
ui->labelRedundantSolverParam2->setText(QString::fromLatin1("R.Tolx"));
@@ -250,15 +335,30 @@ void TaskSketcherSolverAdvanced::updateRedundantMethodParameters()
ui->lineEditRedundantSolverParam1->setEnabled(true);
ui->lineEditRedundantSolverParam2->setEnabled(true);
ui->lineEditRedundantSolverParam3->setEnabled(true);
double tolg = ::atof(hGrp->GetASCII("Redundant_DL_tolg",QString::number(DL_TOLG).toUtf8()).c_str());
double tolx = ::atof(hGrp->GetASCII("Redundant_DL_tolx",QString::number(DL_TOLX).toUtf8()).c_str());
double tolf = ::atof(hGrp->GetASCII("Redundant_DL_tolf",QString::number(DL_TOLF).toUtf8()).c_str());
ui->lineEditRedundantSolverParam1->setText(QString::number(tolg).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditRedundantSolverParam2->setText(QString::number(tolx).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
ui->lineEditRedundantSolverParam3->setText(QString::number(tolf).remove(QString::fromLatin1("+").replace(QString::fromLatin1("e0"),QString::fromLatin1("E")).toUpper()));
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolgRedundant(tolg);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolfRedundant(tolf);
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolxRedundant(tolx);
double tolg = ::atof(
hGrp->GetASCII("Redundant_DL_tolg", QString::number(DL_TOLG).toUtf8()).c_str());
double tolx = ::atof(
hGrp->GetASCII("Redundant_DL_tolx", QString::number(DL_TOLX).toUtf8()).c_str());
double tolf = ::atof(
hGrp->GetASCII("Redundant_DL_tolf", QString::number(DL_TOLF).toUtf8()).c_str());
ui->lineEditRedundantSolverParam1->setText(QString::number(tolg).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditRedundantSolverParam2->setText(QString::number(tolx).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
ui->lineEditRedundantSolverParam3->setText(QString::number(tolf).remove(
QString::fromLatin1("+")
.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"))
.toUpper()));
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolgRedundant(tolg);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolfRedundant(tolf);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolxRedundant(tolx);
break;
}
}
@@ -270,21 +370,22 @@ void TaskSketcherSolverAdvanced::onLineEditSolverParam1EditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditSolverParam1->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps(val);
ui->lineEditSolverParam1->setEntryName("LM_eps");
ui->lineEditSolverParam1->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolg(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolg(val);
ui->lineEditSolverParam1->setEntryName("DL_tolg");
ui->lineEditSolverParam1->onSave();
break;
@@ -298,21 +399,22 @@ void TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam1EditingFinished(
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditRedundantSolverParam1->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_epsRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_epsRedundant(val);
ui->lineEditRedundantSolverParam1->setEntryName("Redundant_LM_eps");
ui->lineEditRedundantSolverParam1->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolgRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolgRedundant(val);
ui->lineEditRedundantSolverParam1->setEntryName("Redundant_DL_tolg");
ui->lineEditRedundantSolverParam1->onSave();
break;
@@ -326,21 +428,22 @@ void TaskSketcherSolverAdvanced::onLineEditSolverParam2EditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditSolverParam2->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps1(val);
ui->lineEditSolverParam2->setEntryName("LM_eps1");
ui->lineEditSolverParam2->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolx(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolx(val);
ui->lineEditSolverParam2->setEntryName("DL_tolx");
ui->lineEditSolverParam2->onSave();
break;
@@ -354,21 +457,22 @@ void TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam2EditingFinished(
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditRedundantSolverParam2->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_eps1Redundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_eps1Redundant(val);
ui->lineEditRedundantSolverParam2->setEntryName("Redundant_LM_eps1");
ui->lineEditRedundantSolverParam2->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolxRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolxRedundant(val);
ui->lineEditRedundantSolverParam2->setEntryName("Redundant_DL_tolx");
ui->lineEditRedundantSolverParam2->onSave();
break;
@@ -382,21 +486,22 @@ void TaskSketcherSolverAdvanced::onLineEditSolverParam3EditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditSolverParam3->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_tau(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_tau(val);
ui->lineEditSolverParam3->setEntryName("LM_tau");
ui->lineEditSolverParam3->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolf(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolf(val);
ui->lineEditSolverParam3->setEntryName("DL_tolf");
ui->lineEditSolverParam3->onSave();
break;
@@ -410,21 +515,22 @@ void TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam3EditingFinished(
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditRedundantSolverParam3->setText(sci.toUpper());
switch(ui->comboBoxDefaultSolver->currentIndex())
{
case 1: // LM
switch (ui->comboBoxDefaultSolver->currentIndex()) {
case 1:// LM
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setLM_tauRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setLM_tauRedundant(val);
ui->lineEditRedundantSolverParam3->setEntryName("Redundant_LM_tau");
ui->lineEditRedundantSolverParam3->onSave();
break;
}
case 2: // DogLeg
case 2:// DogLeg
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDL_tolfRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDL_tolfRedundant(val);
ui->lineEditRedundantSolverParam3->setEntryName("Redundant_DL_tolf");
ui->lineEditRedundantSolverParam3->onSave();
break;
@@ -435,32 +541,36 @@ void TaskSketcherSolverAdvanced::onLineEditRedundantSolverParam3EditingFinished(
void TaskSketcherSolverAdvanced::onComboBoxDefaultSolverCurrentIndexChanged(int index)
{
ui->comboBoxDefaultSolver->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver = static_cast<GCS::Algorithm>(index);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver =
static_cast<GCS::Algorithm>(index);
updateDefaultMethodParameters();
}
void TaskSketcherSolverAdvanced::onComboBoxDogLegGaussStepCurrentIndexChanged(int index)
{
ui->comboBoxDogLegGaussStep->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDogLegGaussStep((GCS::DogLegGaussStep) index);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDogLegGaussStep((GCS::DogLegGaussStep)index);
updateDefaultMethodParameters();
}
void TaskSketcherSolverAdvanced::onSpinBoxMaxIterValueChanged(int i)
{
ui->spinBoxMaxIter->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setMaxIter(i);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch()).setMaxIter(i);
}
void TaskSketcherSolverAdvanced::onCheckBoxSketchSizeMultiplierStateChanged(int state)
{
if(state==Qt::Checked) {
if (state == Qt::Checked) {
ui->checkBoxSketchSizeMultiplier->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(true);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplier(true);
}
else if (state==Qt::Unchecked) {
else if (state == Qt::Unchecked) {
ui->checkBoxSketchSizeMultiplier->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(false);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplier(false);
}
}
@@ -470,12 +580,13 @@ void TaskSketcherSolverAdvanced::onLineEditQRPivotThresholdEditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditQRPivotThreshold->setText(sci.toUpper());
ui->lineEditQRPivotThreshold->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setQRPivotThreshold(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setQRPivotThreshold(val);
}
void TaskSketcherSolverAdvanced::onLineEditConvergenceEditingFinished()
@@ -484,12 +595,13 @@ void TaskSketcherSolverAdvanced::onLineEditConvergenceEditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditConvergence->setText(sci.toUpper());
ui->lineEditConvergence->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setConvergence(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setConvergence(val);
}
void TaskSketcherSolverAdvanced::onLineEditRedundantConvergenceEditingFinished()
@@ -498,88 +610,96 @@ void TaskSketcherSolverAdvanced::onLineEditRedundantConvergenceEditingFinished()
double val = text.toDouble();
QString sci = QString::number(val);
sci.remove(QString::fromLatin1("+"));
sci.replace(QString::fromLatin1("e0"),QString::fromLatin1("E"));
sci.replace(QString::fromLatin1("e0"), QString::fromLatin1("E"));
ui->lineEditRedundantConvergence->setText(sci.toUpper());
ui->lineEditRedundantConvergence->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setConvergenceRedundant(val);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setConvergenceRedundant(val);
}
void TaskSketcherSolverAdvanced::onComboBoxQRMethodCurrentIndexChanged(int index)
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setQRAlgorithm((GCS::QRAlgorithm) index);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setQRAlgorithm((GCS::QRAlgorithm)index);
ui->comboBoxQRMethod->onSave();
}
void TaskSketcherSolverAdvanced::onComboBoxRedundantDefaultSolverCurrentIndexChanged(int index)
{
ui->comboBoxRedundantDefaultSolver->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolverRedundant = static_cast<GCS::Algorithm>(index);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.defaultSolverRedundant = static_cast<GCS::Algorithm>(index);
updateRedundantMethodParameters();
}
void TaskSketcherSolverAdvanced::onSpinBoxRedundantSolverMaxIterationsValueChanged(int i)
{
ui->spinBoxRedundantSolverMaxIterations->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setMaxIterRedundant(i);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setMaxIterRedundant(i);
}
void TaskSketcherSolverAdvanced::onCheckBoxRedundantSketchSizeMultiplierStateChanged(int state)
{
if(state==Qt::Checked) {
if (state == Qt::Checked) {
ui->checkBoxRedundantSketchSizeMultiplier->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(true);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplierRedundant(true);
}
else if (state==Qt::Unchecked) {
else if (state == Qt::Unchecked) {
ui->checkBoxRedundantSketchSizeMultiplier->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(true);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplierRedundant(true);
}
}
void TaskSketcherSolverAdvanced::onComboBoxDebugModeCurrentIndexChanged(int index)
{
ui->comboBoxDebugMode->onSave();
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDebugMode((GCS::DebugMode) index);
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDebugMode((GCS::DebugMode)index);
}
void TaskSketcherSolverAdvanced::onPushButtonSolveClicked(bool checked/* = false*/)
void TaskSketcherSolverAdvanced::onPushButtonSolveClicked(bool checked /* = false*/)
{
Q_UNUSED(checked);
sketchView->getSketchObject()->solve();
}
void TaskSketcherSolverAdvanced::onPushButtonDefaultsClicked(bool checked/* = false*/)
void TaskSketcherSolverAdvanced::onPushButtonDefaultsClicked(bool checked /* = false*/)
{
Q_UNUSED(checked);
// Algorithm params for default solvers
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
hGrp->SetASCII("LM_eps",QString::number(LM_EPS).toUtf8());
hGrp->SetASCII("LM_eps1",QString::number(LM_EPS1).toUtf8());
hGrp->SetASCII("LM_tau",QString::number(LM_TAU).toUtf8());
hGrp->SetASCII("DL_tolg",QString::number(DL_TOLG).toUtf8());
hGrp->SetASCII("DL_tolx",QString::number(DL_TOLX).toUtf8());
hGrp->SetASCII("DL_tolf",QString::number(DL_TOLF).toUtf8());
hGrp->SetASCII("Redundant_LM_eps",QString::number(LM_EPS).toUtf8());
hGrp->SetASCII("Redundant_LM_eps1",QString::number(LM_EPS1).toUtf8());
hGrp->SetASCII("Redundant_LM_tau",QString::number(LM_TAU).toUtf8());
hGrp->SetASCII("Redundant_DL_tolg",QString::number(DL_TOLG).toUtf8());
hGrp->SetASCII("Redundant_DL_tolx",QString::number(DL_TOLX).toUtf8());
hGrp->SetASCII("Redundant_DL_tolf",QString::number(DL_TOLF).toUtf8());
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/Mod/Sketcher/SolverAdvanced");
hGrp->SetASCII("LM_eps", QString::number(LM_EPS).toUtf8());
hGrp->SetASCII("LM_eps1", QString::number(LM_EPS1).toUtf8());
hGrp->SetASCII("LM_tau", QString::number(LM_TAU).toUtf8());
hGrp->SetASCII("DL_tolg", QString::number(DL_TOLG).toUtf8());
hGrp->SetASCII("DL_tolx", QString::number(DL_TOLX).toUtf8());
hGrp->SetASCII("DL_tolf", QString::number(DL_TOLF).toUtf8());
hGrp->SetASCII("Redundant_LM_eps", QString::number(LM_EPS).toUtf8());
hGrp->SetASCII("Redundant_LM_eps1", QString::number(LM_EPS1).toUtf8());
hGrp->SetASCII("Redundant_LM_tau", QString::number(LM_TAU).toUtf8());
hGrp->SetASCII("Redundant_DL_tolg", QString::number(DL_TOLG).toUtf8());
hGrp->SetASCII("Redundant_DL_tolx", QString::number(DL_TOLX).toUtf8());
hGrp->SetASCII("Redundant_DL_tolf", QString::number(DL_TOLF).toUtf8());
// Set other settings
hGrp->SetInt("DefaultSolver",DEFAULT_SOLVER);
hGrp->SetInt("DogLegGaussStep",DEFAULT_DOGLEG_GAUSS_STEP);
hGrp->SetInt("DefaultSolver", DEFAULT_SOLVER);
hGrp->SetInt("DogLegGaussStep", DEFAULT_DOGLEG_GAUSS_STEP);
hGrp->SetInt("RedundantDefaultSolver",DEFAULT_RSOLVER);
hGrp->SetInt("MaxIter",MAX_ITER);
hGrp->SetInt("RedundantSolverMaxIterations",MAX_ITER);
hGrp->SetBool("SketchSizeMultiplier",MAX_ITER_MULTIPLIER);
hGrp->SetBool("RedundantSketchSizeMultiplier",MAX_ITER_MULTIPLIER);
hGrp->SetASCII("Convergence",QString::number(CONVERGENCE).toUtf8());
hGrp->SetASCII("RedundantConvergence",QString::number(CONVERGENCE).toUtf8());
hGrp->SetInt("QRMethod",DEFAULT_QRSOLVER);
hGrp->SetASCII("QRPivotThreshold",QString::number(QR_PIVOT_THRESHOLD).toUtf8());
hGrp->SetInt("DebugMode",DEFAULT_SOLVER_DEBUG);
hGrp->SetInt("RedundantDefaultSolver", DEFAULT_RSOLVER);
hGrp->SetInt("MaxIter", MAX_ITER);
hGrp->SetInt("RedundantSolverMaxIterations", MAX_ITER);
hGrp->SetBool("SketchSizeMultiplier", MAX_ITER_MULTIPLIER);
hGrp->SetBool("RedundantSketchSizeMultiplier", MAX_ITER_MULTIPLIER);
hGrp->SetASCII("Convergence", QString::number(CONVERGENCE).toUtf8());
hGrp->SetASCII("RedundantConvergence", QString::number(CONVERGENCE).toUtf8());
hGrp->SetInt("QRMethod", DEFAULT_QRSOLVER);
hGrp->SetASCII("QRPivotThreshold", QString::number(QR_PIVOT_THRESHOLD).toUtf8());
hGrp->SetInt("DebugMode", DEFAULT_SOLVER_DEBUG);
ui->comboBoxDefaultSolver->onRestore();
ui->comboBoxDogLegGaussStep->onRestore();
@@ -599,18 +719,31 @@ void TaskSketcherSolverAdvanced::onPushButtonDefaultsClicked(bool checked/* = fa
void TaskSketcherSolverAdvanced::updateSketchObject()
{
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDebugMode((GCS::DebugMode) ui->comboBoxDebugMode->currentIndex());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplierRedundant(ui->checkBoxRedundantSketchSizeMultiplier->isChecked());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setMaxIterRedundant(ui->spinBoxRedundantSolverMaxIterations->value());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolverRedundant = static_cast<GCS::Algorithm>(ui->comboBoxRedundantDefaultSolver->currentIndex());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setQRAlgorithm((GCS::QRAlgorithm) ui->comboBoxQRMethod->currentIndex());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setQRPivotThreshold(ui->lineEditQRPivotThreshold->text().toDouble());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setConvergenceRedundant(ui->lineEditRedundantConvergence->text().toDouble());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setConvergence(ui->lineEditConvergence->text().toDouble());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setSketchSizeMultiplier(ui->checkBoxSketchSizeMultiplier->isChecked());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setMaxIter(ui->spinBoxMaxIter->value());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver = static_cast<GCS::Algorithm>(ui->comboBoxDefaultSolver->currentIndex());
const_cast<Sketcher::Sketch &>(sketchView->getSketchObject()->getSolvedSketch()).setDogLegGaussStep((GCS::DogLegGaussStep) ui->comboBoxDogLegGaussStep->currentIndex());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDebugMode((GCS::DebugMode)ui->comboBoxDebugMode->currentIndex());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplierRedundant(ui->checkBoxRedundantSketchSizeMultiplier->isChecked());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setMaxIterRedundant(ui->spinBoxRedundantSolverMaxIterations->value());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.defaultSolverRedundant =
static_cast<GCS::Algorithm>(ui->comboBoxRedundantDefaultSolver->currentIndex());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setQRAlgorithm((GCS::QRAlgorithm)ui->comboBoxQRMethod->currentIndex());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setQRPivotThreshold(ui->lineEditQRPivotThreshold->text().toDouble());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setConvergenceRedundant(ui->lineEditRedundantConvergence->text().toDouble());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setConvergence(ui->lineEditConvergence->text().toDouble());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setSketchSizeMultiplier(ui->checkBoxSketchSizeMultiplier->isChecked());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setMaxIter(ui->spinBoxMaxIter->value());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch()).defaultSolver =
static_cast<GCS::Algorithm>(ui->comboBoxDefaultSolver->currentIndex());
const_cast<Sketcher::Sketch&>(sketchView->getSketchObject()->getSolvedSketch())
.setDogLegGaussStep((GCS::DogLegGaussStep)ui->comboBoxDogLegGaussStep->currentIndex());
updateDefaultMethodParameters();
updateRedundantMethodParameters();
@@ -28,20 +28,22 @@
class Ui_TaskSketcherSolverAdvanced;
namespace App {
namespace App
{
class Property;
}
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
class TaskSketcherSolverAdvanced : public Gui::TaskView::TaskBox
class TaskSketcherSolverAdvanced: public Gui::TaskView::TaskBox
{
Q_OBJECT
public:
explicit TaskSketcherSolverAdvanced(ViewProviderSketch *sketchView);
explicit TaskSketcherSolverAdvanced(ViewProviderSketch* sketchView);
~TaskSketcherSolverAdvanced() override;
private:
@@ -71,14 +73,15 @@ protected:
void updateDefaultMethodParameters();
void updateRedundantMethodParameters();
void updateSketchObject();
protected:
ViewProviderSketch *sketchView;
ViewProviderSketch* sketchView;
private:
QWidget* proxy;
std::unique_ptr<Ui_TaskSketcherSolverAdvanced> ui;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // GUI_TASKVIEW_TaskSketcherSolverAdvanced_H
#endif// GUI_TASKVIEW_TaskSketcherSolverAdvanced_H
+155 -124
View File
@@ -22,30 +22,30 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <QDoubleValidator>
# include <QLocale>
# include <QMessageBox>
# include <Precision.hxx>
#include <Precision.hxx>
#include <QDoubleValidator>
#include <QLocale>
#include <QMessageBox>
#include <algorithm>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoMarkerSet.h>
#include <Inventor/nodes/SoSeparator.h>
#endif
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Inventor/MarkerBitmaps.h>
#include <Gui/Notifications.h>
#include <Gui/TaskView/TaskView.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Inventor/MarkerBitmaps.h>
#include <Gui/TaskView/TaskView.h>
#include <Mod/Sketcher/App/SketchObject.h>
#include "ui_TaskSketcherValidation.h"
#include "TaskSketcherValidation.h"
#include "ui_TaskSketcherValidation.h"
using namespace SketcherGui;
@@ -54,7 +54,11 @@ using namespace Gui::TaskView;
/* TRANSLATOR SketcherGui::SketcherValidation */
SketcherValidation::SketcherValidation(Sketcher::SketchObject* Obj, QWidget* parent)
: QWidget(parent), ui(new Ui_TaskSketcherValidation()), sketch(Obj), sketchAnalyser(Obj), coincidenceRoot(nullptr)
: QWidget(parent)
, ui(new Ui_TaskSketcherValidation())
, sketch(Obj)
, sketchAnalyser(Obj)
, coincidenceRoot(nullptr)
{
ui->setupUi(this);
setupConnections();
@@ -64,25 +68,22 @@ SketcherValidation::SketcherValidation(Sketcher::SketchObject* Obj, QWidget* par
ui->fixDegenerated->setEnabled(false);
ui->swapReversed->setEnabled(false);
ui->checkBoxIgnoreConstruction->setEnabled(true);
double tolerances[8] = {
Precision::Confusion() / 100,
Precision::Confusion() / 10,
Precision::Confusion(),
Precision::Confusion() * 10,
Precision::Confusion() * 100,
Precision::Confusion() * 1000,
Precision::Confusion() * 10000,
Precision::Confusion() * 100000
};
double tolerances[8] = {Precision::Confusion() / 100,
Precision::Confusion() / 10,
Precision::Confusion(),
Precision::Confusion() * 10,
Precision::Confusion() * 100,
Precision::Confusion() * 1000,
Precision::Confusion() * 10000,
Precision::Confusion() * 100000};
QLocale loc;
for (int i=0; i<8; i++) {
for (int i = 0; i < 8; i++) {
ui->comboBoxTolerance->addItem(loc.toString(tolerances[i]), QVariant(tolerances[i]));
}
ui->comboBoxTolerance->setCurrentIndex(5);
ui->comboBoxTolerance->setEditable(true);
ui->comboBoxTolerance->setValidator(new QDoubleValidator(0,10,10,this));
ui->comboBoxTolerance->setValidator(new QDoubleValidator(0, 10, 10, this));
}
SketcherValidation::~SketcherValidation()
@@ -92,33 +93,47 @@ SketcherValidation::~SketcherValidation()
void SketcherValidation::setupConnections()
{
connect(ui->findButton, &QPushButton::clicked,
this, &SketcherValidation::onFindButtonClicked);
connect(ui->fixButton, &QPushButton::clicked,
this, &SketcherValidation::onFixButtonClicked);
connect(ui->highlightButton, &QPushButton::clicked,
this, &SketcherValidation::onHighlightButtonClicked);
connect(ui->findConstraint, &QPushButton::clicked,
this, &SketcherValidation::onFindConstraintClicked);
connect(ui->fixConstraint, &QPushButton::clicked,
this, &SketcherValidation::onFixConstraintClicked);
connect(ui->findReversed, &QPushButton::clicked,
this, &SketcherValidation::onFindReversedClicked);
connect(ui->swapReversed, &QPushButton::clicked,
this, &SketcherValidation::onSwapReversedClicked);
connect(ui->orientLockEnable, &QPushButton::clicked,
this, &SketcherValidation::onOrientLockEnableClicked);
connect(ui->orientLockDisable, &QPushButton::clicked,
this, &SketcherValidation::onOrientLockDisableClicked);
connect(ui->delConstrExtr, &QPushButton::clicked,
this, &SketcherValidation::onDelConstrExtrClicked);
connect(ui->findDegenerated, &QPushButton::clicked,
this, &SketcherValidation::onFindDegeneratedClicked);
connect(ui->fixDegenerated, &QPushButton::clicked,
this, &SketcherValidation::onFixDegeneratedClicked);
connect(ui->findButton, &QPushButton::clicked, this, &SketcherValidation::onFindButtonClicked);
connect(ui->fixButton, &QPushButton::clicked, this, &SketcherValidation::onFixButtonClicked);
connect(ui->highlightButton,
&QPushButton::clicked,
this,
&SketcherValidation::onHighlightButtonClicked);
connect(ui->findConstraint,
&QPushButton::clicked,
this,
&SketcherValidation::onFindConstraintClicked);
connect(ui->fixConstraint,
&QPushButton::clicked,
this,
&SketcherValidation::onFixConstraintClicked);
connect(
ui->findReversed, &QPushButton::clicked, this, &SketcherValidation::onFindReversedClicked);
connect(
ui->swapReversed, &QPushButton::clicked, this, &SketcherValidation::onSwapReversedClicked);
connect(ui->orientLockEnable,
&QPushButton::clicked,
this,
&SketcherValidation::onOrientLockEnableClicked);
connect(ui->orientLockDisable,
&QPushButton::clicked,
this,
&SketcherValidation::onOrientLockDisableClicked);
connect(ui->delConstrExtr,
&QPushButton::clicked,
this,
&SketcherValidation::onDelConstrExtrClicked);
connect(ui->findDegenerated,
&QPushButton::clicked,
this,
&SketcherValidation::onFindDegeneratedClicked);
connect(ui->fixDegenerated,
&QPushButton::clicked,
this,
&SketcherValidation::onFixDegeneratedClicked);
}
void SketcherValidation::changeEvent(QEvent *e)
void SketcherValidation::changeEvent(QEvent* e)
{
if (e->type() == QEvent::LanguageChange) {
ui->retranslateUi(this);
@@ -135,9 +150,9 @@ void SketcherValidation::onFindButtonClicked()
bool ok;
double conv;
conv = QLocale::system().toDouble(ui->comboBoxTolerance->currentText(),&ok);
conv = QLocale::system().toDouble(ui->comboBoxTolerance->currentText(), &ok);
if(ok) {
if (ok) {
prec = conv;
}
else {
@@ -147,9 +162,11 @@ void SketcherValidation::onFindButtonClicked()
}
}
sketchAnalyser.detectMissingPointOnPointConstraints(prec,!ui->checkBoxIgnoreConstruction->isChecked());
sketchAnalyser.detectMissingPointOnPointConstraints(
prec, !ui->checkBoxIgnoreConstruction->isChecked());
std::vector<Sketcher::ConstraintIds> & vertexConstraints = sketchAnalyser.getMissingPointOnPointConstraints();
std::vector<Sketcher::ConstraintIds>& vertexConstraints =
sketchAnalyser.getMissingPointOnPointConstraints();
std::vector<Base::Vector3d> points;
points.reserve(vertexConstraints.size());
@@ -160,17 +177,17 @@ void SketcherValidation::onFindButtonClicked()
hidePoints();
if (vertexConstraints.empty()) {
Gui::TranslatedNotification(*sketch,
tr("No missing coincidences"),
tr("No missing coincidences found"));
Gui::TranslatedNotification(
*sketch, tr("No missing coincidences"), tr("No missing coincidences found"));
ui->fixButton->setEnabled(false);
}
else {
showPoints(points);
Gui::TranslatedUserWarning(*sketch,
tr("Missing coincidences"),
tr("%1 missing coincidences found").arg(vertexConstraints.size()));
Gui::TranslatedUserWarning(
*sketch,
tr("Missing coincidences"),
tr("%1 missing coincidences found").arg(vertexConstraints.size()));
ui->fixButton->setEnabled(true);
}
@@ -216,16 +233,14 @@ void SketcherValidation::onFindConstraintClicked()
return;
if (sketch->evaluateConstraints()) {
Gui::TranslatedNotification(*sketch,
tr("No invalid constraints"),
tr("No invalid constraints found"));
Gui::TranslatedNotification(
*sketch, tr("No invalid constraints"), tr("No invalid constraints found"));
ui->fixConstraint->setEnabled(false);
}
else {
Gui::TranslatedUserError(*sketch,
tr("Invalid constraints"),
tr("Invalid constraints found"));
Gui::TranslatedUserError(
*sketch, tr("Invalid constraints"), tr("Invalid constraints found"));
ui->fixConstraint->setEnabled(true);
}
@@ -246,12 +261,13 @@ void SketcherValidation::onFindReversedClicked()
return;
std::vector<Base::Vector3d> points;
const std::vector<Part::Geometry *>& geom = sketch->getExternalGeometry();
for (std::size_t i=0; i<geom.size(); i++) {
const std::vector<Part::Geometry*>& geom = sketch->getExternalGeometry();
for (std::size_t i = 0; i < geom.size(); i++) {
Part::Geometry* g = geom[i];
//only arcs of circles need to be repaired. Arcs of ellipse were so broken there should be nothing to repair from.
// only arcs of circles need to be repaired. Arcs of ellipse were so broken there should be
// nothing to repair from.
if (g->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
const Part::GeomArcOfCircle *segm = static_cast<const Part::GeomArcOfCircle*>(g);
const Part::GeomArcOfCircle* segm = static_cast<const Part::GeomArcOfCircle*>(g);
if (segm->isReversed()) {
points.push_back(segm->getStartPoint(/*emulateCCW=*/true));
points.push_back(segm->getEndPoint(/*emulateCCW=*/true));
@@ -259,35 +275,40 @@ void SketcherValidation::onFindReversedClicked()
}
}
hidePoints();
if(!points.empty()){
if (!points.empty()) {
int nc = sketch->port_reversedExternalArcs(/*justAnalyze=*/true);
showPoints(points);
if(nc>0){
Gui::TranslatedUserWarning(*sketch,
tr("Reversed external geometry"),
tr("%1 reversed external-geometry arcs were found. Their endpoints are"
if (nc > 0) {
Gui::TranslatedUserWarning(
*sketch,
tr("Reversed external geometry"),
tr("%1 reversed external-geometry arcs were found. Their endpoints are"
" encircled in 3d view.\n\n"
"%2 constraints are linking to the endpoints. The constraints have"
" been listed in Report view (menu View -> Panels -> Report view).\n\n"
"Click \"Swap endpoints in constraints\" button to reassign endpoints."
" Do this only once to sketches created in FreeCAD older than v0.15"
).arg(points.size()/2).arg(nc)
);
" Do this only once to sketches created in FreeCAD older than v0.15")
.arg(points.size() / 2)
.arg(nc));
ui->swapReversed->setEnabled(true);
} else {
Gui::TranslatedUserWarning(*sketch,
tr("Reversed external geometry"),
tr("%1 reversed external-geometry arcs were found. Their endpoints are "
}
else {
Gui::TranslatedUserWarning(
*sketch,
tr("Reversed external geometry"),
tr("%1 reversed external-geometry arcs were found. Their endpoints are "
"encircled in 3d view.\n\n"
"However, no constraints linking to the endpoints were found.").arg(points.size()/2));
"However, no constraints linking to the endpoints were found.")
.arg(points.size() / 2));
ui->swapReversed->setEnabled(false);
}
} else {
}
else {
Gui::TranslatedNotification(*sketch,
tr("Reversed external geometry"),
tr("No reversed external-geometry arcs were found."));
tr("Reversed external geometry"),
tr("No reversed external-geometry arcs were found."));
}
}
@@ -300,9 +321,10 @@ void SketcherValidation::onSwapReversedClicked()
doc->openTransaction("Sketch porting");
int n = sketch->port_reversedExternalArcs(/*justAnalyze=*/false);
Gui::TranslatedNotification(*sketch,
tr("Reversed external geometry"),
tr("%1 changes were made to constraints linking to endpoints of reversed arcs.").arg(n));
Gui::TranslatedNotification(
*sketch,
tr("Reversed external geometry"),
tr("%1 changes were made to constraints linking to endpoints of reversed arcs.").arg(n));
hidePoints();
ui->swapReversed->setEnabled(false);
@@ -319,11 +341,13 @@ void SketcherValidation::onOrientLockEnableClicked()
doc->openTransaction("Constraint orientation lock");
int n = sketch->changeConstraintsLocking(/*bLock=*/true);
Gui::TranslatedNotification(*sketch,
tr("Constraint orientation locking"),
tr("Orientation locking was enabled and recomputed for %1 constraints. The"
Gui::TranslatedNotification(
*sketch,
tr("Constraint orientation locking"),
tr("Orientation locking was enabled and recomputed for %1 constraints. The"
" constraints have been listed in Report view (menu View -> Panels ->"
" Report view).").arg(n));
" Report view).")
.arg(n));
doc->commitTransaction();
}
@@ -337,12 +361,14 @@ void SketcherValidation::onOrientLockDisableClicked()
doc->openTransaction("Constraint orientation unlock");
int n = sketch->changeConstraintsLocking(/*bLock=*/false);
Gui::TranslatedNotification(*sketch,
tr("Constraint orientation locking"),
tr("Orientation locking was disabled for %1 constraints. The"
Gui::TranslatedNotification(
*sketch,
tr("Constraint orientation locking"),
tr("Orientation locking was disabled for %1 constraints. The"
" constraints have been listed in Report view (menu View -> Panels ->"
" Report view). Note that for all future constraints, the locking still"
" defaults to ON.").arg(n));
" defaults to ON.")
.arg(n));
doc->commitTransaction();
}
@@ -353,11 +379,15 @@ void SketcherValidation::onDelConstrExtrClicked()
return;
int reply;
reply = QMessageBox::question(this,
tr("Delete constraints to external geom."),
tr("You are about to delete ALL constraints that deal with external geometry. This is useful to rescue a sketch with broken/changed links to external geometry. Are you sure you want to delete the constraints?"),
QMessageBox::No|QMessageBox::Yes,QMessageBox::No);
if(reply!=QMessageBox::Yes)
reply = QMessageBox::question(
this,
tr("Delete constraints to external geom."),
tr("You are about to delete ALL constraints that deal with external geometry. This is "
"useful to rescue a sketch with broken/changed links to external geometry. Are you sure "
"you want to delete the constraints?"),
QMessageBox::No | QMessageBox::Yes,
QMessageBox::No);
if (reply != QMessageBox::Yes)
return;
App::Document* doc = sketch->getDocument();
@@ -367,16 +397,16 @@ void SketcherValidation::onDelConstrExtrClicked()
doc->commitTransaction();
Gui::TranslatedNotification(*sketch,
tr("Delete constraints to external geom."),
tr("All constraints that deal with external geometry were deleted."));
Gui::TranslatedNotification(
*sketch,
tr("Delete constraints to external geom."),
tr("All constraints that deal with external geometry were deleted."));
}
void SketcherValidation::showPoints(const std::vector<Base::Vector3d>& pts)
{
SoCoordinate3 * coords = new SoCoordinate3();
SoDrawStyle * drawStyle = new SoDrawStyle();
SoCoordinate3* coords = new SoCoordinate3();
SoDrawStyle* drawStyle = new SoDrawStyle();
drawStyle->pointSize = 6;
SoPointSet* pcPoints = new SoPointSet();
@@ -384,7 +414,7 @@ void SketcherValidation::showPoints(const std::vector<Base::Vector3d>& pts)
coincidenceRoot->addChild(drawStyle);
SoSeparator* pointsep = new SoSeparator();
SoBaseColor * basecol = new SoBaseColor();
SoBaseColor* basecol = new SoBaseColor();
basecol->rgb.setValue(1.0f, 0.5f, 0.0f);
pointsep->addChild(basecol);
pointsep->addChild(coords);
@@ -392,10 +422,14 @@ void SketcherValidation::showPoints(const std::vector<Base::Vector3d>& pts)
coincidenceRoot->addChild(pointsep);
// Draw markers
SoBaseColor * markcol = new SoBaseColor();
SoBaseColor* markcol = new SoBaseColor();
markcol->rgb.setValue(1.0f, 1.0f, 0.0f);
SoMarkerSet* marker = new SoMarkerSet();
marker->markerIndex=Gui::Inventor::MarkerBitmaps::getMarkerIndex("PLUS", App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View")->GetInt("MarkerSize", 9));
marker->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex(
"PLUS",
App::GetApplication()
.GetParameterGroupByPath("User parameter:BaseApp/Preferences/View")
->GetInt("MarkerSize", 9));
pointsep->addChild(markcol);
pointsep->addChild(marker);
@@ -404,7 +438,7 @@ void SketcherValidation::showPoints(const std::vector<Base::Vector3d>& pts)
SbVec3f* c = coords->point.startEditing();
for (int i = 0; i < pts_size; i++) {
const Base::Vector3d& v = pts[i];
c[i].setValue((float)v.x,(float)v.y,(float)v.z);
c[i].setValue((float)v.x, (float)v.y, (float)v.z);
}
coords->point.finishEditing();
@@ -434,16 +468,14 @@ void SketcherValidation::onFindDegeneratedClicked()
int count = sketchAnalyser.detectDegeneratedGeometries(prec);
if (count == 0) {
Gui::TranslatedNotification(*sketch,
tr("No degenerated geometry"),
tr("No degenerated geometry found"));
Gui::TranslatedNotification(
*sketch, tr("No degenerated geometry"), tr("No degenerated geometry found"));
ui->fixDegenerated->setEnabled(false);
}
else {
Gui::TranslatedUserWarning(*sketch,
tr("Degenerated geometry"),
tr("%1 degenerated geometry found").arg(count));
Gui::TranslatedUserWarning(
*sketch, tr("Degenerated geometry"), tr("%1 degenerated geometry found").arg(count));
ui->fixDegenerated->setEnabled(true);
}
@@ -475,14 +507,13 @@ void SketcherValidation::onFixDegeneratedClicked()
TaskSketcherValidation::TaskSketcherValidation(Sketcher::SketchObject* Obj)
{
QWidget* widget = new SketcherValidation(Obj);
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
QPixmap(), widget->windowTitle(), true, nullptr);
Gui::TaskView::TaskBox* taskbox =
new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(), true, nullptr);
taskbox->groupLayout()->addWidget(widget);
Content.push_back(taskbox);
}
TaskSketcherValidation::~TaskSketcherValidation()
{
}
{}
#include "moc_TaskSketcherValidation.cpp"
+14 -8
View File
@@ -33,12 +33,16 @@
class SoGroup;
namespace Sketcher { class SketchObject; }
namespace Sketcher
{
class SketchObject;
}
namespace SketcherGui {
namespace SketcherGui
{
class Ui_TaskSketcherValidation;
class SketcherValidation : public QWidget
class SketcherValidation: public QWidget
{
Q_OBJECT
@@ -47,7 +51,7 @@ public:
~SketcherValidation() override;
protected:
void changeEvent(QEvent *e) override;
void changeEvent(QEvent* e) override;
private:
void setupConnections();
@@ -75,7 +79,7 @@ private:
SoGroup* coincidenceRoot;
};
class TaskSketcherValidation : public Gui::TaskView::TaskDialog
class TaskSketcherValidation: public Gui::TaskView::TaskDialog
{
Q_OBJECT
@@ -83,9 +87,11 @@ public:
explicit TaskSketcherValidation(Sketcher::SketchObject* Obj);
~TaskSketcherValidation() override;
QDialogButtonBox::StandardButtons getStandardButtons(void) const override
{ return QDialogButtonBox::Close; }
{
return QDialogButtonBox::Close;
}
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_TASKSKETCHERVALIDATION_H
#endif// SKETCHERGUI_TASKSKETCHERVALIDATION_H
+114 -102
View File
@@ -55,8 +55,8 @@ bool SketcherGui::tryAutoRecompute(Sketcher::SketchObject* obj, bool& autoremove
bool autoRecompute = hGrp->GetBool("AutoRecompute", false);
bool autoRemoveRedundants = hGrp->GetBool("AutoRemoveRedundants", false);
// We need to make sure the solver has right redundancy information before trying to remove the redundants.
// for example if a non-driving constraint has been added.
// We need to make sure the solver has right redundancy information before trying to remove the
// redundants. for example if a non-driving constraint has been added.
if (autoRemoveRedundants && autoRecompute)
obj->solve();
@@ -146,16 +146,18 @@ void SketcherGui::getIdsFromName(const std::string& name, const Sketcher::Sketch
}
}
std::vector<int> SketcherGui::getGeoIdsOfEdgesFromNames(const Sketcher::SketchObject* Obj, const std::vector<std::string> & names)
std::vector<int> SketcherGui::getGeoIdsOfEdgesFromNames(const Sketcher::SketchObject* Obj,
const std::vector<std::string>& names)
{
std::vector<int> geoids;
for(const auto & name : names) {
for (const auto& name : names) {
if (name.size() > 4 && name.substr(0, 4) == "Edge") {
geoids.push_back(std::atoi(name.substr(4, 4000).c_str()) - 1);
}
else if (name.size() > 12 && name.substr(0, 12) == "ExternalEdge") {
geoids.push_back(Sketcher::GeoEnum::RefExt + 1 - std::atoi(name.substr(12, 4000).c_str()));
geoids.push_back(Sketcher::GeoEnum::RefExt + 1
- std::atoi(name.substr(12, 4000).c_str()));
}
else if (name.size() > 6 && name.substr(0, 6) == "Vertex") {
int VtId = std::atoi(name.substr(6, 4000).c_str()) - 1;
@@ -163,7 +165,7 @@ std::vector<int> SketcherGui::getGeoIdsOfEdgesFromNames(const Sketcher::SketchOb
Sketcher::PointPos PosId;
Obj->getGeoVertexIndex(VtId, GeoId, PosId);
const Part::Geometry* geo = Obj->getGeometry(GeoId);
if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()){
if (geo->getTypeId() == Part::GeomPoint::getClassTypeId()) {
geoids.push_back(GeoId);
}
}
@@ -260,16 +262,17 @@ bool SketcherGui::isBsplineKnotOrEndPoint(const Sketcher::SketchObject* Obj, int
bool SketcherGui::IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint,
Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj)
{
//This func is a "smartness" behind three-element tangent-, perp.- and angle-via-point.
//We want to find out, if the point supplied by user is already on
// both of the curves. If not, necessary point-on-object constraints
// are to be added automatically.
//Simple geometric test seems to be the best, because a point can be
// constrained to a curve in a number of ways (e.g. it is an endpoint of an
// arc, or is coincident to endpoint of an arc, or it is an endpoint of an
// ellipse's major diameter line). Testing all those possibilities is way
// too much trouble, IMO(DeepSOIC).
// One exception: check for knots on their B-splines, at least until point on B-spline is implemented. (Ajinkya)
// This func is a "smartness" behind three-element tangent-, perp.- and angle-via-point.
// We want to find out, if the point supplied by user is already on
// both of the curves. If not, necessary point-on-object constraints
// are to be added automatically.
// Simple geometric test seems to be the best, because a point can be
// constrained to a curve in a number of ways (e.g. it is an endpoint of an
// arc, or is coincident to endpoint of an arc, or it is an endpoint of an
// ellipse's major diameter line). Testing all those possibilities is way
// too much trouble, IMO(DeepSOIC).
// One exception: check for knots on their B-splines, at least until point on B-spline is
// implemented. (Ajinkya)
if (isBsplineKnot(Obj, GeoIdPoint)) {
const Part::Geometry* geoCurve = Obj->getGeometry(GeoIdCurve);
if (geoCurve->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) {
@@ -329,7 +332,9 @@ double SketcherGui::GetPointAngle(const Base::Vector2d& p1, const Base::Vector2d
// Set the two points on circles at minimal distance
// in concentric case set points on relative X axis
void SketcherGui::GetCirclesMinimalDistance(const Part::GeomCircle *circle1, const Part::GeomCircle *circle2, Base::Vector3d &point1, Base::Vector3d &point2)
void SketcherGui::GetCirclesMinimalDistance(const Part::GeomCircle* circle1,
const Part::GeomCircle* circle2, Base::Vector3d& point1,
Base::Vector3d& point2)
{
double radius1 = circle1->getRadius();
double radius2 = circle2->getRadius();
@@ -340,20 +345,23 @@ void SketcherGui::GetCirclesMinimalDistance(const Part::GeomCircle *circle1, con
Base::Vector3d v = point2 - point1;
double length = v.Length();
if (length == 0) { //concentric case
if (length == 0) {// concentric case
point1.x += radius1;
point2.x += radius2;
} else {
}
else {
v = v.Normalize();
if (length <= std::max(radius1, radius2)){ //inner case
if (radius1 > radius2){
if (length <= std::max(radius1, radius2)) {// inner case
if (radius1 > radius2) {
point1 += v * radius1;
point2 += v * radius2;
} else {
}
else {
point1 += -v * radius1;
point2 += -v * radius2;
}
} else { //outer case
}
else {// outer case
point1 += v * radius1;
point2 += -v * radius2;
}
@@ -374,7 +382,8 @@ void SketcherGui::ActivateHandler(Gui::Document* doc, DrawSketchHandler* handler
}
}
bool SketcherGui::isSketchInEdit(Gui::Document* doc) {
bool SketcherGui::isSketchInEdit(Gui::Document* doc)
{
if (doc) {
// checks if a Sketch Viewprovider is in Edit and is in no special mode
auto* vp = dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
@@ -385,16 +394,18 @@ bool SketcherGui::isSketchInEdit(Gui::Document* doc) {
bool SketcherGui::isCommandActive(Gui::Document* doc, bool actsOnSelection)
{
if(isSketchInEdit(doc)) {
auto mode = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())->getSketchMode();
if (isSketchInEdit(doc)) {
auto mode =
static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit())->getSketchMode();
if (mode == ViewProviderSketch::STATUS_NONE ||
mode == ViewProviderSketch::STATUS_SKETCH_UseHandler) {
if (mode == ViewProviderSketch::STATUS_NONE
|| mode == ViewProviderSketch::STATUS_SKETCH_UseHandler) {
if (!actsOnSelection) {
return true;
}
else if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId()) > 0) {
else if (Gui::Selection().countObjectsOfType(Sketcher::SketchObject::getClassTypeId())
> 0) {
return true;
}
}
@@ -403,9 +414,10 @@ bool SketcherGui::isCommandActive(Gui::Document* doc, bool actsOnSelection)
return false;
}
SketcherGui::ViewProviderSketch* SketcherGui::getInactiveHandlerEditModeSketchViewProvider(Gui::Document* doc)
SketcherGui::ViewProviderSketch*
SketcherGui::getInactiveHandlerEditModeSketchViewProvider(Gui::Document* doc)
{
if(doc) {
if (doc) {
return dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
}
@@ -414,7 +426,7 @@ SketcherGui::ViewProviderSketch* SketcherGui::getInactiveHandlerEditModeSketchVi
SketcherGui::ViewProviderSketch* SketcherGui::getInactiveHandlerEditModeSketchViewProvider()
{
Gui::Document *doc = Gui::Application::Instance->activeDocument();
Gui::Document* doc = Gui::Application::Instance->activeDocument();
return getInactiveHandlerEditModeSketchViewProvider(doc);
}
@@ -430,44 +442,44 @@ void SketcherGui::removeRedundantHorizontalVertical(Sketcher::SketchObject* pske
// we look for:
// 1. Coincident to external on both endpoints
// 2. Coincident in one endpoint to origin and pointonobject/tangent to an axis on the other
auto detectredundant = [psketch](std::vector<AutoConstraint>& sug,
bool& ext,
bool& orig,
bool& axis) {
ext = false;
orig = false;
axis = false;
auto detectredundant =
[psketch](std::vector<AutoConstraint>& sug, bool& ext, bool& orig, bool& axis) {
ext = false;
orig = false;
axis = false;
for (std::vector<AutoConstraint>::const_iterator it = sug.begin(); it != sug.end();
++it) {
if ((*it).Type == Sketcher::Coincident && !ext) {
const std::map<int, Sketcher::PointPos> coincidents =
psketch->getAllCoincidentPoints((*it).GeoId, (*it).PosId);
for (std::vector<AutoConstraint>::const_iterator it = sug.begin(); it != sug.end();
++it) {
if ((*it).Type == Sketcher::Coincident && !ext) {
const std::map<int, Sketcher::PointPos> coincidents =
psketch->getAllCoincidentPoints((*it).GeoId, (*it).PosId);
if (!coincidents.empty()) {
// the keys are ordered, so if the first is negative, it is coincident with external
ext = coincidents.begin()->first < 0;
if (!coincidents.empty()) {
// the keys are ordered, so if the first is negative, it is coincident
// with external
ext = coincidents.begin()->first < 0;
std::map<int, Sketcher::PointPos>::const_iterator geoId1iterator;
std::map<int, Sketcher::PointPos>::const_iterator geoId1iterator;
geoId1iterator = coincidents.find(-1);
geoId1iterator = coincidents.find(-1);
if (geoId1iterator != coincidents.end()) {
if ((*geoId1iterator).second == Sketcher::PointPos::start)
orig = true;
if (geoId1iterator != coincidents.end()) {
if ((*geoId1iterator).second == Sketcher::PointPos::start)
orig = true;
}
}
else {// it may be that there is no constraint at all, but there is external
// geometry
ext = (*it).GeoId < 0;
orig = ((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::start);
}
}
else {// it may be that there is no constraint at all, but there is external geometry
ext = (*it).GeoId < 0;
orig = ((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::start);
else if ((*it).Type == Sketcher::PointOnObject && !axis) {
axis = (((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::none)
|| ((*it).GeoId == -2 && (*it).PosId == Sketcher::PointPos::none));
}
}
else if ((*it).Type == Sketcher::PointOnObject && !axis) {
axis = (((*it).GeoId == -1 && (*it).PosId == Sketcher::PointPos::none)
|| ((*it).GeoId == -2 && (*it).PosId == Sketcher::PointPos::none));
}
}
};
};
bool firstext = false, secondext = false, firstorig = false, secondorig = false,
firstaxis = false, secondaxis = false;
@@ -534,7 +546,7 @@ void SketcherGui::ConstraintToAttachment(Sketcher::GeoElementId element,
}
//convenience functions for cursor display
// convenience functions for cursor display
bool SketcherGui::hideUnits()
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication()
@@ -552,7 +564,7 @@ bool SketcherGui::showCursorCoords()
.GetGroup("BaseApp")
->GetGroup("Preferences")
->GetGroup("Mod/Sketcher");
return hGrp->GetBool("ShowCursorCoords", true);//true for testing. set to false for prod.
return hGrp->GetBool("ShowCursorCoords", true);// true for testing. set to false for prod.
}
bool SketcherGui::useSystemDecimals()
@@ -565,12 +577,12 @@ bool SketcherGui::useSystemDecimals()
return hGrp->GetBool("UseSystemDecimals", true);
}
//convert value to display format %0.[digits]f. Units are displayed if
//preference "ShowUnits" is true, or if the unit schema in effect uses
//multiple units (ex. Ft/In). Digits parameter is ignored for multi-unit
//schemata
//TODO:: if the user string is delivered in 1.23e45 format, this might not work
// correctly.
// convert value to display format %0.[digits]f. Units are displayed if
// preference "ShowUnits" is true, or if the unit schema in effect uses
// multiple units (ex. Ft/In). Digits parameter is ignored for multi-unit
// schemata
// TODO:: if the user string is delivered in 1.23e45 format, this might not work
// correctly.
std::string SketcherGui::lengthToDisplayFormat(double value, int digits)
{
Base::Quantity asQuantity;
@@ -578,28 +590,28 @@ std::string SketcherGui::lengthToDisplayFormat(double value, int digits)
asQuantity.setUnit(Base::Unit::Length);
QString qUserString = asQuantity.getUserString();
if (Base::UnitsApi::isMultiUnitLength() || (!hideUnits() && useSystemDecimals())) {
//just return the user string
// just return the user string
return Base::Tools::toStdString(qUserString);
}
//find the unit of measure
// find the unit of measure
double factor = 1.0;
QString qUnitString;
QString qtranslate = Base::UnitsApi::schemaTranslate(asQuantity, factor, qUnitString);
QString unitPart = QString::fromUtf8(" ") + qUnitString;
//get the numeric part of the user string
// get the numeric part of the user string
QRegularExpression rxNoUnits(
QString::fromUtf8("(.*) \\D*$"));// text before space + any non digits at end of string
QRegularExpressionMatch match = rxNoUnits.match(qUserString);
if (!match.hasMatch()) {
//no units in userString?
// no units in userString?
return Base::Tools::toStdString(qUserString);
}
QString matched = match.captured(1);//matched is the numeric part of user string
QString matched = match.captured(1);// matched is the numeric part of user string
int dpPos = matched.indexOf(QLocale().decimalPoint());
if (dpPos < 0) {
//no decimal separator (ie an integer), return all the digits
// no decimal separator (ie an integer), return all the digits
if (hideUnits()) {
return Base::Tools::toStdString(matched);
}
@@ -608,16 +620,16 @@ std::string SketcherGui::lengthToDisplayFormat(double value, int digits)
}
}
//real number
// real number
if (useSystemDecimals() && hideUnits()) {
//return just the numeric part of the user string
// return just the numeric part of the user string
return Base::Tools::toStdString(matched);
}
//real number and not using system decimals
// real number and not using system decimals
int requiredLength = dpPos + digits + 1;
if (requiredLength > matched.size()) {
//just take the whole thing
// just take the whole thing
requiredLength = matched.size();
}
QString numericPart = matched.left(requiredLength);
@@ -627,11 +639,11 @@ std::string SketcherGui::lengthToDisplayFormat(double value, int digits)
return Base::Tools::toStdString(numericPart + unitPart);
}
//convert value to display format %0.[digits]f. Units are always displayed for
//angles - 123.456° or 12°34'56". Digits parameter is ignored for multi-unit
//schemata. Note small differences between this method and lengthToDisplyFormat
//TODO:: if the user string is delivered in 1.23e45 format, this might not work
// correctly.
// convert value to display format %0.[digits]f. Units are always displayed for
// angles - 123.456° or 12°34'56". Digits parameter is ignored for multi-unit
// schemata. Note small differences between this method and lengthToDisplyFormat
// TODO:: if the user string is delivered in 1.23e45 format, this might not work
// correctly.
std::string SketcherGui::angleToDisplayFormat(double value, int digits)
{
Base::Quantity asQuantity;
@@ -639,47 +651,47 @@ std::string SketcherGui::angleToDisplayFormat(double value, int digits)
asQuantity.setUnit(Base::Unit::Angle);
QString qUserString = asQuantity.getUserString();
if (Base::UnitsApi::isMultiUnitAngle()) {
//just return the user string
//Coin SbString doesn't handle utf8 well, so we convert to ascii
QString schemeMinute = QString::fromUtf8("\xE2\x80\xB2");//prime symbol
QString schemeSecond = QString::fromUtf8("\xE2\x80\xB3");//double prime symbol
QString escapeMinute = QString::fromLatin1("\'"); //substitute ascii single quote
QString escapeSecond = QString::fromLatin1("\""); //substitute ascii double quote
// just return the user string
// Coin SbString doesn't handle utf8 well, so we convert to ascii
QString schemeMinute = QString::fromUtf8("\xE2\x80\xB2");// prime symbol
QString schemeSecond = QString::fromUtf8("\xE2\x80\xB3");// double prime symbol
QString escapeMinute = QString::fromLatin1("\'"); // substitute ascii single quote
QString escapeSecond = QString::fromLatin1("\""); // substitute ascii double quote
QString displayString = qUserString.replace(schemeMinute, escapeMinute);
displayString = displayString.replace(schemeSecond, escapeSecond);
return Base::Tools::toStdString(displayString);
}
//we always use use U+00B0 (°) as the unit of measure for angles in
//single unit schema. Will need a change to support rads or grads.
// we always use use U+00B0 (°) as the unit of measure for angles in
// single unit schema. Will need a change to support rads or grads.
auto qUnitString = QString::fromUtf8("°");
auto decimalSep = QLocale().decimalPoint();
//get the numeric part of the user string
QRegularExpression rxNoUnits(
QString::fromUtf8("(\\d*\\%1?\\d*)(\\D*)$").arg(decimalSep));// number + non digits at end of string
// get the numeric part of the user string
QRegularExpression rxNoUnits(QString::fromUtf8("(\\d*\\%1?\\d*)(\\D*)$")
.arg(decimalSep));// number + non digits at end of string
QRegularExpressionMatch match = rxNoUnits.match(qUserString);
if (!match.hasMatch()) {
//no units in userString?
// no units in userString?
return Base::Tools::toStdString(qUserString);
}
QString matched = match.captured(1);//matched is the numeric part of user string
QString matched = match.captured(1);// matched is the numeric part of user string
int dpPos = matched.indexOf(decimalSep);
if (dpPos < 0) {
//no decimal separator (ie an integer), return all the digits
// no decimal separator (ie an integer), return all the digits
return Base::Tools::toStdString(matched + qUnitString);
}
//real number
// real number
if (useSystemDecimals()) {
//return just the numeric part of the user string + degree symbol
// return just the numeric part of the user string + degree symbol
return Base::Tools::toStdString(matched + qUnitString);
}
//real number and not using system decimals
// real number and not using system decimals
int requiredLength = dpPos + digits + 1;
if (requiredLength > matched.size()) {
//just take the whole thing
// just take the whole thing
requiredLength = matched.size();
}
QString numericPart = matched.left(requiredLength);
+83 -57
View File
@@ -32,33 +32,38 @@
#include "ViewProviderSketchGeometryExtension.h"
namespace App {
class DocumentObject;
namespace App
{
class DocumentObject;
}
namespace Gui {
class DocumentObject;
class Document;
}
namespace Gui
{
class DocumentObject;
class Document;
}// namespace Gui
namespace Part {
class Geometry;
}
namespace Sketcher {
enum class PointPos : int;
class SketchObject;
namespace Part
{
class Geometry;
}
namespace Sketcher
{
enum class PointPos : int;
class SketchObject;
}// namespace Sketcher
namespace SketcherGui {
class DrawSketchHandler;
class ViewProviderSketch;
namespace SketcherGui
{
class DrawSketchHandler;
class ViewProviderSketch;
/// This function tries to auto-recompute the active document if the option
/// is set in the user parameter. If the option is not set nothing will be done
/// @return true if a recompute was undertaken, false if not.
bool tryAutoRecompute(Sketcher::SketchObject* obj);
/// Same as the other overload, but also returns whether redundants shall be removed or not
bool tryAutoRecompute(Sketcher::SketchObject* obj, bool &autoremoveredundants);
bool tryAutoRecompute(Sketcher::SketchObject* obj, bool& autoremoveredundants);
/// This function tries to auto-recompute as tryAutoRecompute. If tryAutoRecompute
/// is not enabled, then it solves the SketchObject.
@@ -70,10 +75,12 @@ bool ReleaseHandler(Gui::Document* doc);
std::string getStrippedPythonExceptionString(const Base::Exception&);
void getIdsFromName(const std::string &name, const Sketcher::SketchObject* Obj, int &GeoId, Sketcher::PointPos &PosId);
void getIdsFromName(const std::string& name, const Sketcher::SketchObject* Obj, int& GeoId,
Sketcher::PointPos& PosId);
/// Returns ONLY the geometry elements when the "Edge" is selected (including GeomPoints)
std::vector<int> getGeoIdsOfEdgesFromNames(const Sketcher::SketchObject* Obj, const std::vector<std::string> & names);
std::vector<int> getGeoIdsOfEdgesFromNames(const Sketcher::SketchObject* Obj,
const std::vector<std::string>& names);
bool checkBothExternal(int GeoId1, int GeoId2);
@@ -81,7 +88,8 @@ bool isPointOrSegmentFixed(const Sketcher::SketchObject* Obj, int GeoId);
bool areBothPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2);
bool areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2, int GeoId3);
bool areAllPointsOrSegmentsFixed(const Sketcher::SketchObject* Obj, int GeoId1, int GeoId2,
int GeoId3);
bool inline isVertex(int GeoId, Sketcher::PointPos PosId);
@@ -91,17 +99,22 @@ bool isSimpleVertex(const Sketcher::SketchObject* Obj, int GeoId, Sketcher::Poin
/// Checks if `GeoId` corresponds to a B-Spline knot
bool isBsplineKnot(const Sketcher::SketchObject* Obj, int GeoId);
/// Checks if the (`GeoId`, `PosId`) pair corresponds to a B-Spline knot, including first and last knots
bool isBsplineKnotOrEndPoint(const Sketcher::SketchObject* Obj, int GeoId, Sketcher::PointPos PosId);
/// Checks if the (`GeoId`, `PosId`) pair corresponds to a B-Spline knot, including first and last
/// knots
bool isBsplineKnotOrEndPoint(const Sketcher::SketchObject* Obj, int GeoId,
Sketcher::PointPos PosId);
bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint, Sketcher::SketchObject* Obj);
bool IsPointAlreadyOnCurve(int GeoIdCurve, int GeoIdPoint, Sketcher::PointPos PosIdPoint,
Sketcher::SketchObject* Obj);
bool isBsplinePole(const Part::Geometry * geo);
bool isBsplinePole(const Part::Geometry* geo);
bool isBsplinePole(const Sketcher::SketchObject* Obj, int GeoId);
/// Checks whether there is a constraint of the given type with a First element geoid and a FirstPos PosId
bool checkConstraint(const std::vector< Sketcher::Constraint * > &vals, Sketcher::ConstraintType type, int geoid, Sketcher::PointPos pos);
/// Checks whether there is a constraint of the given type with a First element geoid and a FirstPos
/// PosId
bool checkConstraint(const std::vector<Sketcher::Constraint*>& vals, Sketcher::ConstraintType type,
int geoid, Sketcher::PointPos pos);
inline bool isVertex(int GeoId, Sketcher::PointPos PosId)
{
@@ -117,63 +130,75 @@ inline bool isEdge(int GeoId, Sketcher::PointPos PosId)
/* helper functions ======================================================*/
// Return counter-clockwise angle from horizontal out of p1 to p2 in radians.
double GetPointAngle (const Base::Vector2d &p1, const Base::Vector2d &p2);
double GetPointAngle(const Base::Vector2d& p1, const Base::Vector2d& p2);
// Set the two points on circles at minimal distance
void GetCirclesMinimalDistance(const Part::GeomCircle *circle1, const Part::GeomCircle *circle2, Base::Vector3d &point1, Base::Vector3d &point2);
void GetCirclesMinimalDistance(const Part::GeomCircle* circle1, const Part::GeomCircle* circle2,
Base::Vector3d& point1, Base::Vector3d& point2);
void ActivateHandler(Gui::Document *doc, DrawSketchHandler *handler);
void ActivateHandler(Gui::Document* doc, DrawSketchHandler* handler);
/// Returns if a sketch is in edit mode
bool isSketchInEdit(Gui::Document* doc);
/// Returns whether an edit mode command should be activated or not. It is only activated if the sketcher is no special state or a sketchHandler is active.
bool isCommandActive(Gui::Document *doc, bool actsOnSelection = false);
/// Returns whether an edit mode command should be activated or not. It is only activated if the
/// sketcher is no special state or a sketchHandler is active.
bool isCommandActive(Gui::Document* doc, bool actsOnSelection = false);
SketcherGui::ViewProviderSketch* getInactiveHandlerEditModeSketchViewProvider(Gui::Document *doc);
SketcherGui::ViewProviderSketch* getInactiveHandlerEditModeSketchViewProvider(Gui::Document* doc);
SketcherGui::ViewProviderSketch* getInactiveHandlerEditModeSketchViewProvider();
void removeRedundantHorizontalVertical(Sketcher::SketchObject* psketch,
std::vector<AutoConstraint> &sug1,
std::vector<AutoConstraint> &sug2);
std::vector<AutoConstraint>& sug1,
std::vector<AutoConstraint>& sug2);
void ConstraintToAttachment(Sketcher::GeoElementId element, Sketcher::GeoElementId attachment, double distance, App::DocumentObject* obj);
void ConstraintToAttachment(Sketcher::GeoElementId element, Sketcher::GeoElementId attachment,
double distance, App::DocumentObject* obj);
//convenience functions for cursor coordinates
bool hideUnits();
bool showCursorCoords();
bool useSystemDecimals();
// convenience functions for cursor coordinates
bool hideUnits();
bool showCursorCoords();
bool useSystemDecimals();
std::string lengthToDisplayFormat(double value, int digits);
std::string angleToDisplayFormat(double value, int digits);
}
}// namespace SketcherGui
/// converts a 2D vector into a 3D vector in the XY plane
inline Base::Vector3d toVector3d(const Base::Vector2d & vector2d) {
inline Base::Vector3d toVector3d(const Base::Vector2d& vector2d)
{
return Base::Vector3d(vector2d.x, vector2d.y, 0.);
}
template <typename T>
auto toPointerVector(const std::vector<std::unique_ptr<T>> & vector) {
std::vector<T *> vp (vector.size());
template<typename T>
auto toPointerVector(const std::vector<std::unique_ptr<T>>& vector)
{
std::vector<T*> vp(vector.size());
std::transform(vector.begin(), vector.end(), vp.begin(), [](auto &p) {return p.get();});
std::transform(vector.begin(), vector.end(), vp.begin(), [](auto& p) {
return p.get();
});
return vp;
}
/** returns the visual layer id (not the one of the GeometryFacade, but the index to PropertyVisualLayerList) from a geometry or GeometryFacade.
* NOTE: If the geometry or geometryfacade does not have a corresponding ViewProviderSketchGeometryExtension, the default layer (layer 0) is returned.
/** returns the visual layer id (not the one of the GeometryFacade, but the index to
* PropertyVisualLayerList) from a geometry or GeometryFacade. NOTE: If the geometry or
* geometryfacade does not have a corresponding ViewProviderSketchGeometryExtension, the default
* layer (layer 0) is returned.
* */
template <typename T>
template<typename T>
auto getSafeGeomLayerId(T geom)
{
int layerId = 0;
if(geom->hasExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())) {
auto vpext = std::static_pointer_cast<const SketcherGui::ViewProviderSketchGeometryExtension>(
geom->getExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId()).lock());
if (geom->hasExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())) {
auto vpext =
std::static_pointer_cast<const SketcherGui::ViewProviderSketchGeometryExtension>(
geom->getExtension(
SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())
.lock());
layerId = vpext->getVisualLayerId();
}
@@ -181,22 +206,23 @@ auto getSafeGeomLayerId(T geom)
return layerId;
}
/** sets the visual layer id (not the one of the GeometryFacade, but the index to PropertyVisualLayerList) for a geometry or GeometryFacade.
* NOTE: If no ViewProviderSketchGeometryExtension is present, one is created.
/** sets the visual layer id (not the one of the GeometryFacade, but the index to
* PropertyVisualLayerList) for a geometry or GeometryFacade. NOTE: If no
* ViewProviderSketchGeometryExtension is present, one is created.
* */
template <typename T>
template<typename T>
void setSafeGeomLayerId(T geom, int layerindex)
{
// create extension if none existing
if(!geom->hasExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())) {
if (!geom->hasExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())) {
geom->setExtension(std::make_unique<SketcherGui::ViewProviderSketchGeometryExtension>());
}
auto vpext = std::static_pointer_cast<SketcherGui::ViewProviderSketchGeometryExtension>(
geom->getExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId()).lock());
geom->getExtension(SketcherGui::ViewProviderSketchGeometryExtension::getClassTypeId())
.lock());
vpext->setVisualLayerId(layerindex);
}
#endif // SKETCHERGUI_Recompute_H
#endif// SKETCHERGUI_Recompute_H
+10 -10
View File
@@ -22,7 +22,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSeparator.h>
#endif
#include <Gui/ViewProviderBuilder.h>
@@ -35,12 +35,10 @@ using namespace SketcherGui;
PROPERTY_SOURCE(SketcherGui::ViewProviderCustom, SketcherGui::ViewProviderSketch)
ViewProviderCustom::ViewProviderCustom()
{
}
{}
ViewProviderCustom::~ViewProviderCustom()
{
}
{}
void ViewProviderCustom::onChanged(const App::Property* prop)
{
@@ -65,9 +63,11 @@ void ViewProviderCustom::updateData(const App::Property* prop)
if (it == propView.end()) {
Gui::ViewProvider* view = Gui::ViewProviderBuilder::create(prop->getTypeId());
if (view) {
if (view->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId())) {
if (view->getTypeId().isDerivedFrom(
Gui::ViewProviderDocumentObject::getClassTypeId())) {
static_cast<Gui::ViewProviderDocumentObject*>(view)->attach(this->getObject());
static_cast<Gui::ViewProviderDocumentObject*>(view)->setDisplayMode(this->getActiveDisplayMode().c_str());
static_cast<Gui::ViewProviderDocumentObject*>(view)->setDisplayMode(
this->getActiveDisplayMode().c_str());
}
propView[prop] = view;
view->updateData(prop);
@@ -82,7 +82,8 @@ void ViewProviderCustom::updateData(const App::Property* prop)
// -----------------------------------------------------------------------
namespace Gui {
namespace Gui
{
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(SketcherGui::ViewProviderPython, SketcherGui::ViewProviderSketch)
/// @endcond
@@ -96,5 +97,4 @@ PROPERTY_SOURCE_TEMPLATE(SketcherGui::ViewProviderCustomPython, SketcherGui::Vie
// explicit template instantiation
template class SketcherGuiExport ViewProviderPythonFeatureT<SketcherGui::ViewProviderCustom>;
}
}// namespace Gui
+5 -5
View File
@@ -27,9 +27,10 @@
#include <Mod/Sketcher/Gui/ViewProviderSketch.h>
namespace SketcherGui {
namespace SketcherGui
{
class SketcherGuiExport ViewProviderCustom : public ViewProviderSketch
class SketcherGuiExport ViewProviderCustom: public ViewProviderSketch
{
PROPERTY_HEADER_WITH_OVERRIDE(SketcherGui::ViewProviderCustom);
@@ -48,8 +49,7 @@ protected:
using ViewProviderPython = Gui::ViewProviderPythonFeatureT<ViewProviderSketch>;
using ViewProviderCustomPython = Gui::ViewProviderPythonFeatureT<ViewProviderCustom>;
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SketcherGui_VIEWPROVIDERPYTHON_H
#endif// SketcherGui_VIEWPROVIDERPYTHON_H
File diff suppressed because it is too large Load Diff
+287 -200
View File
@@ -23,11 +23,11 @@
#ifndef SKETCHERGUI_VIEWPROVIDERSKETCH_H
#define SKETCHERGUI_VIEWPROVIDERSKETCH_H
#include <memory>
#include <QCoreApplication>
#include <boost_signals2.hpp>
#include <Inventor/SoRenderManager.h>
#include <Inventor/sensors/SoNodeSensor.h>
#include <QCoreApplication>
#include <boost_signals2.hpp>
#include <memory>
#include <Base/Parameter.h>
#include <Base/Placement.h>
@@ -35,8 +35,8 @@
#include <Gui/GLPainter.h>
#include <Gui/Selection.h>
#include <Mod/Part/Gui/ViewProvider2DObject.h>
#include <Mod/Part/Gui/ViewProviderGridExtension.h>
#include <Mod/Part/Gui/ViewProviderAttachExtension.h>
#include <Mod/Part/Gui/ViewProviderGridExtension.h>
#include <Mod/Sketcher/App/GeoList.h>
#include "PropertyVisualLayerList.h"
@@ -68,21 +68,25 @@ class SoTranslation;
class SbString;
class SbTime;
namespace Part {
class Geometry;
namespace Part
{
class Geometry;
}
namespace Gui {
class View3DInventorViewer;
namespace Gui
{
class View3DInventorViewer;
}
namespace Sketcher {
class Constraint;
class Sketch;
class SketchObject;
}
namespace Sketcher
{
class Constraint;
class Sketch;
class SketchObject;
}// namespace Sketcher
namespace SketcherGui {
namespace SketcherGui
{
class EditModeCoinManager;
class SnapManager;
@@ -131,18 +135,18 @@ using GeoListFacade = Sketcher::GeoListFacade;
* markers necessary to enable visual feedback to the user, as well as the UI interaction during
* such edits. This is its exclusive responsibility under the Single Responsibility Principle.
*
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing (see
* for example all the handlers for creation of new geometry). These derived classes do * not * have
* direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep coupling
* under control. However, generic functionality requiring access to the Attorney can be implemented
* in DrawSketchHandler and used from its derived classes by virtue of the inheritance. This promotes a
* concentrating the coupling in a single point (and code reuse).
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing
* (see for example all the handlers for creation of new geometry). These derived classes do * not *
* have direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep
* coupling under control. However, generic functionality requiring access to the Attorney can be
* implemented in DrawSketchHandler and used from its derived classes by virtue of the inheritance.
* This promotes a concentrating the coupling in a single point (and code reuse).
*
*/
class SketcherGuiExport ViewProviderSketch : public PartGui::ViewProvider2DObject
, public PartGui::ViewProviderGridExtension
, public PartGui::ViewProviderAttachExtension
, public Gui::SelectionObserver
class SketcherGuiExport ViewProviderSketch: public PartGui::ViewProvider2DObject,
public PartGui::ViewProviderGridExtension,
public PartGui::ViewProviderAttachExtension,
public Gui::SelectionObserver
{
Q_DECLARE_TR_FUNCTIONS(SketcherGui::ViewProviderSketch)
@@ -155,10 +159,10 @@ private:
* ViewProviderSketch, initialising the ViewProviderSketch to the current configuration
* and handle in real time any change to their values.
*/
class ParameterObserver : public ParameterGrp::ObserverType
class ParameterObserver: public ParameterGrp::ObserverType
{
public:
explicit ParameterObserver(ViewProviderSketch & client);
explicit ParameterObserver(ViewProviderSketch& client);
~ParameterObserver();
void initParameters();
@@ -168,25 +172,31 @@ private:
void unsubscribeToParameters();
/** Observer for parameter group. */
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
void OnChange(Base::Subject<const char*>& rCaller, const char* sReason) override;
private:
void updateBoolProperty(const std::string& string, App::Property* property,
bool defaultvalue);
void updateGridSize(const std::string& string, App::Property* property);
void updateBoolProperty(const std::string & string, App::Property * property, bool defaultvalue);
void updateGridSize(const std::string & string, App::Property * property);
// Only for colors outside of edit mode, edit mode colors are handled by
// EditModeCoinManager.
void updateColorProperty(const std::string& string, App::Property* property, float r,
float g, float b);
// Only for colors outside of edit mode, edit mode colors are handled by EditModeCoinManager.
void updateColorProperty(const std::string & string, App::Property * property, float r, float g, float b);
void updateEscapeKeyBehaviour(const std::string& string, App::Property* property);
void updateEscapeKeyBehaviour(const std::string & string, App::Property * property);
void updateAutoRecompute(const std::string& string, App::Property* property);
void updateAutoRecompute(const std::string & string, App::Property * property);
void updateRecalculateInitialSolutionWhileDragging(const std::string & string, App::Property * property);
void updateRecalculateInitialSolutionWhileDragging(const std::string& string,
App::Property* property);
private:
ViewProviderSketch &Client;
std::map<std::string, std::tuple<std::function<void(const std::string & string, App::Property *)>, App::Property * >> parameterMap;
ViewProviderSketch& Client;
std::map<std::string,
std::tuple<std::function<void(const std::string& string, App::Property*)>,
App::Property*>>
parameterMap;
};
/** @name Classes storing the state of Dragging, Selection and Preselection
@@ -212,108 +222,131 @@ private:
* (2) In SketchObject.cpp, the actual document object, both {GeoId, PointPos} and VertexId
* are used (see VertexId2GeoId and VertexId2GeoPosId).
*
* (3) In ViewProviderSketch, both {GeoId, PointPos} an Point indices are used (see these structures)
* (3) In ViewProviderSketch, both {GeoId, PointPos} an Point indices are used (see these
* structures)
*
* (4) At CoinManager level, {GeoId, PointPos}, Point indices (for selection) and MultiFieldIds (specific
* structure defining a coin multifield index and layer) are used.
* (4) At CoinManager level, {GeoId, PointPos}, Point indices (for selection) and MultiFieldIds
* (specific structure defining a coin multifield index and layer) are used.
*
* Using a single index instead of a multi-index field, allows mappings to be implemented via std::vectors
* instead of std::maps. Direct mappings using std::vectors are accessed in constant time. Multi-index mappings
* relying on std::maps involve a search for the key. This leads to a drop in performance.
* Using a single index instead of a multi-index field, allows mappings to be implemented via
* std::vectors instead of std::maps. Direct mappings using std::vectors are accessed in
* constant time. Multi-index mappings relying on std::maps involve a search for the key. This
* leads to a drop in performance.
*
* What are these indices and how do they relate each other?
* 1. PointId, VertexId depend on the order of the geometries in the sketch. GeoList and GeoListFacade enable to
* convert between indices.
* 1. PointId, VertexId depend on the order of the geometries in the sketch. GeoList and
* GeoListFacade enable to convert between indices.
* 2. CurveId is basically the GeoId assuming PointPos to be PointPos::none (edge)
* 3. Sometimes, Axes and root point are separated into a third index or enum. Legacy reasons aside, the root point
* is has GeoId=-1, which is sometimes used as invalid value in positive only indices. Additionally, root point and
* the Horizontal Axes both have GeoId=-1 (differing in PointPos only). Following the decision not to rely on PointPos,
* creating a separate index, best when enum-ed, appears justified.
* 3. Sometimes, Axes and root point are separated into a third index or enum. Legacy reasons
* aside, the root point is has GeoId=-1, which is sometimes used as invalid value in positive
* only indices. Additionally, root point and the Horizontal Axes both have GeoId=-1 (differing
* in PointPos only). Following the decision not to rely on PointPos, creating a separate index,
* best when enum-ed, appears justified.
*/
//@{
/** @brief Class to store vector and item Id for dragging.
*
* @details
* Ids are zero-indexed points and curves.
*
* The DragPoint indexing matches PreselectPoint indexing.
*
*/
class Drag {
*
* @details
* Ids are zero-indexed points and curves.
*
* The DragPoint indexing matches PreselectPoint indexing.
*
*/
class Drag
{
public:
enum SpecialValues {
enum SpecialValues
{
InvalidPoint = -1,
InvalidCurve = -1
};
Drag() {
Drag()
{
resetVector();
resetIds();
}
void resetVector() {
void resetVector()
{
xInit = 0;
yInit = 0;
relative = false;
}
void resetIds() {
void resetIds()
{
DragPoint = InvalidPoint;
DragCurve = InvalidCurve;
DragConstraintSet.clear();
}
bool isDragPointValid() { return DragPoint > InvalidPoint;}
bool isDragCurveValid() { return DragCurve > InvalidCurve;}
bool isDragPointValid()
{
return DragPoint > InvalidPoint;
}
bool isDragCurveValid()
{
return DragCurve > InvalidCurve;
}
double xInit, yInit; // starting point of the dragging operation
bool relative; // whether the dragging move vector is relative or absolute
double xInit, yInit;// starting point of the dragging operation
bool relative; // whether the dragging move vector is relative or absolute
int DragPoint; // dragged point id (only positive integers)
int DragCurve; // dragged curve id (only positive integers), negative external curves cannot be dragged.
std::set<int> DragConstraintSet; // dragged constraints ids
int DragPoint;// dragged point id (only positive integers)
int DragCurve;// dragged curve id (only positive integers), negative external curves cannot
// be dragged.
std::set<int> DragConstraintSet;// dragged constraints ids
};
// TODO: Selection and Preselection should use a same structure. Probably Drag should use the same structure too. To be refactored separately.
// TODO: Selection and Preselection should use a same structure. Probably Drag should use the
// same structure too. To be refactored separately.
/** @brief Class to store preselected element ids.
*
* @details
*
* PreselectPoint is the positive VertexId.
*
* PreselectCurve is the GeoID, but without the Axes (indices -1 and -2).
*
* VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root point)
*
* EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N = -PreselectCurve - 2
*
* The PreselectPoint indexing matches DragPoint indexing (it further includes negative edges, which are
* not meaningful for Dragging).
*
*/
class Preselection {
*
* @details
*
* PreselectPoint is the positive VertexId.
*
* PreselectCurve is the GeoID, but without the Axes (indices -1 and -2).
*
* VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root
* point)
*
* EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N =
* -PreselectCurve - 2
*
* The PreselectPoint indexing matches DragPoint indexing (it further includes negative edges,
* which are not meaningful for Dragging).
*
*/
class Preselection
{
public:
enum SpecialValues {
enum SpecialValues
{
InvalidPoint = -1,
InvalidCurve = -1,
ExternalCurve = -3
};
enum class Axes {
enum class Axes
{
None = -1,
RootPoint = 0,
HorizontalAxis = 1,
VerticalAxis = 2
};
Preselection() {
Preselection()
{
reset();
}
void reset(){
void reset()
{
PreselectPoint = InvalidPoint;
PreselectCurve = InvalidCurve;
PreselectCross = Axes::None;
@@ -321,80 +354,116 @@ private:
blockedPreselection = false;
}
bool isPreselectPointValid() const { return PreselectPoint > InvalidPoint;}
bool isPreselectCurveValid() const { return PreselectCurve > InvalidCurve || PreselectCurve <= ExternalCurve;}
bool isCrossPreselected() const { return PreselectCross != Axes::None;}
bool isEdge() const { return PreselectCurve > InvalidCurve;}
bool isExternalEdge() const { return PreselectCurve <= ExternalCurve;}
bool isPreselectPointValid() const
{
return PreselectPoint > InvalidPoint;
}
bool isPreselectCurveValid() const
{
return PreselectCurve > InvalidCurve || PreselectCurve <= ExternalCurve;
}
bool isCrossPreselected() const
{
return PreselectCross != Axes::None;
}
bool isEdge() const
{
return PreselectCurve > InvalidCurve;
}
bool isExternalEdge() const
{
return PreselectCurve <= ExternalCurve;
}
int getPreselectionVertexIndex() const { return PreselectPoint + 1;}
int getPreselectionEdgeIndex() const { return PreselectCurve + 1;}
int getPreselectionExternalEdgeIndex() const { return -PreselectCurve - 2;}
int getPreselectionVertexIndex() const
{
return PreselectPoint + 1;
}
int getPreselectionEdgeIndex() const
{
return PreselectCurve + 1;
}
int getPreselectionExternalEdgeIndex() const
{
return -PreselectCurve - 2;
}
int PreselectPoint; // VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root point)
int PreselectCurve; // EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N = -PreselectCurve - 2
Axes PreselectCross; // 0 => rootPoint, 1 => HAxis, 2 => VAxis
std::set<int> PreselectConstraintSet; // ConstraintN, N = index + 1
int PreselectPoint;// VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE
// -1 is NOT the root point)
int PreselectCurve;// EdgeN, with N = PreselectCurve + 1 for positive values ;
// ExternalEdgeN, with N = -PreselectCurve - 2
Axes PreselectCross; // 0 => rootPoint, 1 => HAxis, 2 => VAxis
std::set<int> PreselectConstraintSet;// ConstraintN, N = index + 1
bool blockedPreselection;
};
/** @brief Class to store selected element ids.
*
* @details
* Selection follows yet a different mechanism than preselection.
*
* SelPointSet indices as PreselectPoint, with the addition that -1 is indeed the rootpoint.
*
* SelCurvSet indices as PreselectCurve, with the addition that -1 is the HAxis and -2 is the VAxis
*
*/
class Selection {
*
* @details
* Selection follows yet a different mechanism than preselection.
*
* SelPointSet indices as PreselectPoint, with the addition that -1 is indeed the rootpoint.
*
* SelCurvSet indices as PreselectCurve, with the addition that -1 is the HAxis and -2 is the
* VAxis
*
*/
class Selection
{
public:
enum SpecialValues {
enum SpecialValues
{
RootPoint = -1,
HorizontalAxis = -1,
VerticalAxis = -2
};
Selection() {
Selection()
{
reset();
}
void reset() {
void reset()
{
SelPointSet.clear();
SelCurvSet.clear();
SelConstraintSet.clear();
}
std::set<int> SelPointSet; // Indices as PreselectPoint (and -1 for rootpoint)
std::set<int> SelCurvSet; // also holds cross axes at -1 and -2
std::set<int> SelConstraintSet; // ConstraintN, N = index + 1.
std::set<int> SelPointSet; // Indices as PreselectPoint (and -1 for rootpoint)
std::set<int> SelCurvSet; // also holds cross axes at -1 and -2
std::set<int> SelConstraintSet;// ConstraintN, N = index + 1.
};
//@}
/** @brief Private struct maintaining information necessary for detecting double click.
*/
struct DoubleClick {
struct DoubleClick
{
static SbTime prvClickTime;
static SbVec2s prvClickPos; //used by double-click-detector
static SbVec2s prvClickPos;// used by double-click-detector
static SbVec2s prvCursorPos;
static SbVec2s newCursorPos;
};
/** @brief Private struct grouping ViewProvider parameters and internal variables
*/
struct ViewProviderParameters {
struct ViewProviderParameters
{
bool handleEscapeButton = false;
bool autoRecompute = false;
bool recalculateInitialSolutionWhileDragging = false;
bool isShownVirtualSpace = false; // indicates whether the present virtual space view is the Real Space or the Virtual Space (virtual space 1 or 2)
bool isShownVirtualSpace = false;// indicates whether the present virtual space view is the
// Real Space or the Virtual Space (virtual space 1 or 2)
bool buttonPress = false;
};
/** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode sensor data
/** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode
* sensor data
*/
struct VPRender {
struct VPRender
{
ViewProviderSketch* vp;
SoRenderManager* renderMgr;
};
@@ -420,42 +489,50 @@ public:
SketcherGui::PropertyVisualLayerList VisualLayerList;
//@}
// TODO: It is difficult to imagine that these functions are necessary in the public interface. This requires review at a second stage and possibly
// refactor it.
// TODO: It is difficult to imagine that these functions are necessary in the public interface.
// This requires review at a second stage and possibly refactor it.
/** @name handler control */
//@{
/// sets an DrawSketchHandler in control
void activateHandler(DrawSketchHandler *newHandler);
void activateHandler(DrawSketchHandler* newHandler);
/// removes the active handler
void purgeHandler();
//@}
// TODO: SketchMode should be refactored. DrawSketchHandler, its inheritance and free functions should access this mode via the DrawSketchHandler
// Attorney. I will not refactor this at this moment, as the refactor will be even more extensive and difficult to review. But this should be done
// in a second stage.
// TODO: SketchMode should be refactored. DrawSketchHandler, its inheritance and free functions
// should access this mode via the DrawSketchHandler Attorney. I will not refactor this at this
// moment, as the refactor will be even more extensive and difficult to review. But this should
// be done in a second stage.
/** @name modus handling */
//@{
/// mode table
enum SketchMode{
STATUS_NONE, /**< enum value View provider is in neutral. */
STATUS_SELECT_Point, /**< enum value a point was selected. */
STATUS_SELECT_Edge, /**< enum value an edge was selected. */
STATUS_SELECT_Constraint, /**< enum value a constraint was selected. */
STATUS_SELECT_Cross, /**< enum value the base coordinate system was selected. */
STATUS_SKETCH_DragPoint, /**< enum value while dragging a point. */
STATUS_SKETCH_DragCurve, /**< enum value while dragging a curve. */
enum SketchMode
{
STATUS_NONE, /**< enum value View provider is in neutral. */
STATUS_SELECT_Point, /**< enum value a point was selected. */
STATUS_SELECT_Edge, /**< enum value an edge was selected. */
STATUS_SELECT_Constraint, /**< enum value a constraint was selected. */
STATUS_SELECT_Cross, /**< enum value the base coordinate system was selected. */
STATUS_SKETCH_DragPoint, /**< enum value while dragging a point. */
STATUS_SKETCH_DragCurve, /**< enum value while dragging a curve. */
STATUS_SKETCH_DragConstraint, /**< enum value while dragging a compatible constraint. */
STATUS_SKETCH_UseHandler, /**< enum value a DrawSketchHandler is in control. */
STATUS_SKETCH_UseHandler, /**< enum value a DrawSketchHandler is in control. */
STATUS_SKETCH_StartRubberBand, /**< enum value for initiating a rubber band selection */
STATUS_SKETCH_UseRubberBand /**< enum value when making a rubber band selection */
STATUS_SKETCH_UseRubberBand /**< enum value when making a rubber band selection */
};
/// is called by GuiCommands to set the drawing mode
void setSketchMode(SketchMode mode) {Mode = mode;}
void setSketchMode(SketchMode mode)
{
Mode = mode;
}
/// get the sketch mode
SketchMode getSketchMode() const {return Mode;}
SketchMode getSketchMode() const
{
return Mode;
}
//@}
/** @name Drawing functions */
@@ -463,7 +540,7 @@ public:
/// draw the sketch in the inventor nodes
/// temp => use temporary solver solution in SketchObject
/// recreateinformationscenography => forces a rebuild of the information overlay scenography
void draw(bool temp=false, bool rebuildinformationoverlay=true);
void draw(bool temp = false, bool rebuildinformationoverlay = true);
/// helper change the color of the sketch according to selection and solver status
void updateColor();
@@ -486,19 +563,22 @@ public:
/** @name Access to Sketch and Solver objects */
//@{
/// get the pointer to the sketch document object
Sketcher::SketchObject *getSketchObject() const;
Sketcher::SketchObject* getSketchObject() const;
/** returns a const reference to the last solved sketch object. It guarantees that
* the solver object does not lose synchronisation with the SketchObject properties.
*
* NOTE: Operations requiring * write * access to the solver must be done via SketchObject
* interface. See for example functions:
* -> inline void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
* -> inline void setRecalculateInitialSolutionWhileMovingPoint(bool
* recalculateInitialSolutionWhileMovingPoint)
* -> inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true)
* -> inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool relative=false)
* -> inline void updateSolverExtension(int geoId, std::unique_ptr<Part::GeometryExtension> && ext)
* -> inline int moveTemporaryPoint(int geoId, PointPos pos, Base::Vector3d toPoint, bool
* relative=false)
* -> inline void updateSolverExtension(int geoId, std::unique_ptr<Part::GeometryExtension> &&
* ext)
*/
const Sketcher::Sketch &getSolvedSketch() const;
const Sketcher::Sketch& getSolvedSketch() const;
//@}
/** @name miscelanea utilities */
@@ -515,7 +595,8 @@ public:
//@{
/// updates the visibility of the virtual space of constraints
void updateVirtualSpace();
/// determines whether the constraints in the normal space or the ones in the virtual are to be shown
/// determines whether the constraints in the normal space or the ones in the virtual are to be
/// shown
void setIsShownVirtualSpace(bool isshownvirtualspace);
/// returns whether the virtual space is being shown
bool getIsShownVirtualSpace() const;
@@ -523,39 +604,46 @@ public:
/** @name base class implementer */
//@{
void attach(App::DocumentObject *) override;
void updateData(const App::Property *) override;
void attach(App::DocumentObject*) override;
void updateData(const App::Property*) override;
void setupContextMenu(QMenu *menu, QObject *receiver, const char *member) override;
void setupContextMenu(QMenu* menu, QObject* receiver, const char* member) override;
/// is called when the Provider is in edit and a deletion request occurs
bool onDelete(const std::vector<std::string> &) override;
bool onDelete(const std::vector<std::string>&) override;
/// Is called by the tree if the user double clicks on the object. It returns the string
/// for the transaction that will be shown in the undo/redo dialog.
/// If null is returned then no transaction will be opened.
const char* getTransactionText() const override { return nullptr; }
const char* getTransactionText() const override
{
return nullptr;
}
/// is called by the tree if the user double clicks on the object
bool doubleClicked() override;
/// is called when the Provider is in edit and the mouse is moved
bool mouseMove(const SbVec2s &pos, Gui::View3DInventorViewer *viewer) override;
bool mouseMove(const SbVec2s& pos, Gui::View3DInventorViewer* viewer) override;
/// is called when the Provider is in edit and a key event ocours. Only ESC ends edit.
bool keyPressed(bool pressed, int key) override;
/// is called when the Provider is in edit and the mouse is clicked
bool mouseButtonPressed(int Button, bool pressed, const SbVec2s& cursorPos, const Gui::View3DInventorViewer* viewer) override;
bool mouseWheelEvent(int delta, const SbVec2s &cursorPos, const Gui::View3DInventorViewer* viewer) override;
bool mouseButtonPressed(int Button, bool pressed, const SbVec2s& cursorPos,
const Gui::View3DInventorViewer* viewer) override;
bool mouseWheelEvent(int delta, const SbVec2s& cursorPos,
const Gui::View3DInventorViewer* viewer) override;
//@}
/// Control the overlays appearing on the Tree and reflecting different sketcher states
QIcon mergeColorfulOverlayIcons (const QIcon & orig) const override;
QIcon mergeColorfulOverlayIcons(const QIcon& orig) const override;
/** @name Signals for controlling information in Task dialogs */
//@{
/// signals if the constraints list has changed
boost::signals2::signal<void ()> signalConstraintsChanged;
boost::signals2::signal<void()> signalConstraintsChanged;
/// signals if the sketch has been set up
boost::signals2::signal<void (const QString &state, const QString &msg, const QString &url, const QString &linkText)> signalSetUp;
boost::signals2::signal<void(const QString& state, const QString& msg, const QString& url,
const QString& linkText)>
signalSetUp;
/// signals if the elements list has changed
boost::signals2::signal<void ()> signalElementsChanged;
boost::signals2::signal<void()> signalElementsChanged;
//@}
/** @name Attorneys for collaboration with helper classes */
@@ -572,7 +660,7 @@ protected:
void unsetEdit(int ModNum) override;
void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override;
void unsetEditViewer(Gui::View3DInventorViewer*) override;
static void camSensCB(void *data, SoSensor *); // camera sensor callback
static void camSensCB(void* data, SoSensor*);// camera sensor callback
void onCameraChanged(SoCamera* cam);
//@}
@@ -589,10 +677,10 @@ protected:
/// update solver information based on last solving at SketchObject
void UpdateSolverInformation();
/// Auxiliary function to generate messages about conflicting, redundant and malformed constraints
static QString appendConstraintMsg( const QString & singularmsg,
const QString & pluralmsg,
const std::vector<int> &vector);
/// Auxiliary function to generate messages about conflicting, redundant and malformed
/// constraints
static QString appendConstraintMsg(const QString& singularmsg, const QString& pluralmsg,
const std::vector<int>& vector);
//@}
/** @name manage updates during undo/redo operations */
@@ -605,30 +693,28 @@ protected:
/** @name base class implementer */
//@{
/// get called by the container whenever a property has been changed
void onChanged(const App::Property *prop) override;
void onChanged(const App::Property* prop) override;
//@}
private:
/// function to handle OCCT BSpline weight calculation singularities and representation
void scaleBSplinePoleCirclesAndUpdateSolverAndSketchObjectGeometry(
GeoListFacade & geolist,
bool geometrywithmemoryallocation);
GeoListFacade& geolist, bool geometrywithmemoryallocation);
/** @name geometry and coordinates auxiliary functions */
//@{
/// give the coordinates of a line on the sketch plane in sketcher (2D) coordinates
void getCoordsOnSketchPlane(const SbVec3f &point, const SbVec3f &normal, double &u, double &v) const;
void getCoordsOnSketchPlane(const SbVec3f& point, const SbVec3f& normal, double& u,
double& v) const;
/// give projecting line of position
void getProjectingLine(const SbVec2s&,
const Gui::View3DInventorViewer *viewer,
SbLine&) const;
void getProjectingLine(const SbVec2s&, const Gui::View3DInventorViewer* viewer, SbLine&) const;
//@}
/** @name preselection functions */
//@{
/// helper to detect preselection
bool detectAndShowPreselection (SoPickedPoint * Point, const SbVec2s &cursorPos);
bool detectAndShowPreselection(SoPickedPoint* Point, const SbVec2s& cursorPos);
int getPreselectPoint() const;
int getPreselectCurve() const;
int getPreselectCross() const;
@@ -636,29 +722,29 @@ private:
void setPreselectRootPoint();
void resetPreselectPoint();
bool setPreselect(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
bool setPreselect(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0);
//@}
/** @name Selection functions */
//@{
/// box selection method
void doBoxSelection(const SbVec2s &startPos, const SbVec2s &endPos,
const Gui::View3DInventorViewer *viewer);
void doBoxSelection(const SbVec2s& startPos, const SbVec2s& endPos,
const Gui::View3DInventorViewer* viewer);
void addSelectPoint(int SelectPoint);
void removeSelectPoint(int SelectPoint);
void clearSelectPoints();
bool isSelected(const std::string & ss) const;
void rmvSelection(const std::string &subNameSuffix);
bool addSelection(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
bool addSelection2(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
bool isSelected(const std::string& ss) const;
void rmvSelection(const std::string& subNameSuffix);
bool addSelection(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0);
bool addSelection2(const std::string& subNameSuffix, float x = 0, float y = 0, float z = 0);
//@}
/** @name miscelanea utilities */
//@{
/// moves a selected constraint
void moveConstraint(int constNum, const Base::Vector2d &toPos);
void moveConstraint(int constNum, const Base::Vector2d& toPos);
/// returns whether the sketch is in edit mode.
bool isInEditMode() const;
@@ -675,7 +761,7 @@ private:
bool constraintHasExpression(int constrid) const;
const std::vector<Sketcher::Constraint *> getConstraints() const;
const std::vector<Sketcher::Constraint*> getConstraints() const;
// gets the list of geometry of the sketchobject or of the solver instance
const GeoList getGeoList() const;
@@ -702,15 +788,15 @@ private:
bool haveConstraintsInvalidGeometry() const;
void addNodeToRoot(SoSeparator * node);
void addNodeToRoot(SoSeparator* node);
void removeNodeFromRoot(SoSeparator * node);
void removeNodeFromRoot(SoSeparator* node);
bool isConstraintPreselected(int constraintId) const;
bool isPointSelected(int pointId) const;
void executeOnSelectionPointSet(std::function<void(const int)> && operation) const;
void executeOnSelectionPointSet(std::function<void(const int)>&& operation) const;
bool isCurveSelected(int curveId) const;
@@ -721,15 +807,16 @@ private:
//********* ViewProviderSketchDrawSketchHandlerAttorney **********//
void setConstraintSelectability(bool enabled = true);
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
void setPositionText(const Base::Vector2d &Pos);
void setPositionText(const Base::Vector2d& Pos, const SbString& txt);
void setPositionText(const Base::Vector2d& Pos);
void resetPositionText();
/// draw the edit curve
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>> &list);
void drawEdit(const std::vector<Base::Vector2d>& EditCurve);
void drawEdit(const std::list<std::vector<Base::Vector2d>>& list);
/// draw the edit markers
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
void drawEditMarkers(const std::vector<Base::Vector2d>& EditMarkers,
unsigned int augmentationlevel = 0);
/// set the pick style of the sketch coordinate axes
void setAxisPickStyle(bool on);
@@ -739,20 +826,21 @@ private:
//@}
private:
/** @name Solver message creation*/
/** @name Solver message creation*/
//@{
/* private functions to decouple Attorneys and Clients from the internal implementation of
the ViewProvider and its members, such as sketchObject (see friend attorney classes) and
improve encapsulation.
*/
/// generates a warning message about constraint conflicts and appends it to the given message
static QString appendConflictMsg(const std::vector<int> &conflicting);
static QString appendConflictMsg(const std::vector<int>& conflicting);
/// generates a warning message about redundant constraints and appends it to the given message
static QString appendRedundantMsg(const std::vector<int> &redundant);
/// generates a warning message about partially redundant constraints and appends it to the given message
static QString appendPartiallyRedundantMsg(const std::vector<int> &partiallyredundant);
static QString appendRedundantMsg(const std::vector<int>& redundant);
/// generates a warning message about partially redundant constraints and appends it to the
/// given message
static QString appendPartiallyRedundantMsg(const std::vector<int>& partiallyredundant);
/// generates a warning message about redundant constraints and appends it to the given message
static QString appendMalformedMsg(const std::vector<int> &redundant);
static QString appendMalformedMsg(const std::vector<int>& redundant);
//@}
private:
@@ -787,11 +875,10 @@ private:
ViewProviderParameters viewProviderParameters;
SoNodeSensor cameraSensor;
int viewOrientationFactor; // stores if sketch viewed from front or back
int viewOrientationFactor;// stores if sketch viewed from front or back
};
} // namespace PartGui
}// namespace SketcherGui
#endif // SKETCHERGUI_VIEWPROVIDERSKETCH_H
#endif// SKETCHERGUI_VIEWPROVIDERSKETCH_H
@@ -23,8 +23,8 @@
#ifndef SKETCHERGUI_ViewProviderSketchCoinAttorney_H
#define SKETCHERGUI_ViewProviderSketchCoinAttorney_H
#include <vector>
#include <QFont>
#include <vector>
#include <Inventor/SbVec2f.h>
#include <Inventor/SbVec3f.h>
@@ -33,25 +33,29 @@
#include "ViewProviderSketch.h"
namespace Base {
template< typename T >
class Vector3;
namespace Base
{
template<typename T>
class Vector3;
class Vector2d;
class Vector2d;
class Placement;
class Placement;
}// namespace Base
namespace Part
{
class Geometry;
}
namespace Part {
class Geometry;
}
namespace Sketcher
{
class Constraint;
class PropertyConstraintList;
};// namespace Sketcher
namespace Sketcher {
class Constraint;
class PropertyConstraintList;
};
namespace SketcherGui {
namespace SketcherGui
{
class ViewProviderSketch;
@@ -63,52 +67,58 @@ using GeoListFacade = Sketcher::GeoListFacade;
* ViewProviderSketch delegates a substantial part of coin related visualisation to
* ViewProviderSketchCoinAttorney during edit mode.
*
* Sometimes friend classes of ViewProviderSketchCoinAttorney need to access selected functionalities only available to ViewProviderSketch.
* Sometimes friend classes of ViewProviderSketchCoinAttorney need to access selected
* functionalities only available to ViewProviderSketch.
*
* This attorney class regulates which specific functionalities ViewProviderSketchCoinAttorney is able to access in
* ViewProviderSketch.
* This attorney class regulates which specific functionalities ViewProviderSketchCoinAttorney is
* able to access in ViewProviderSketch.
*
* The objective is:
* - to preserve as much as possible ViewProviderSketch encapsulation
* - to promote as much as reasonably possible loose coupling between tightly related classes.
* - to keep control over the interactions between these classes and easily identify the cooperation interface.
* - to keep control over the interactions between these classes and easily identify the
* cooperation interface.
*/
class ViewProviderSketchCoinAttorney {
class ViewProviderSketchCoinAttorney
{
private:
static inline bool constraintHasExpression(const ViewProviderSketch &vp, int constrid);
static inline const std::vector<Sketcher::Constraint *> getConstraints(const ViewProviderSketch & vp);
static inline const GeoList getGeoList(const ViewProviderSketch & vp);
static inline const GeoListFacade getGeoListFacade(const ViewProviderSketch & vp);
static inline Base::Placement getEditingPlacement(const ViewProviderSketch & vp);
static inline bool isShownVirtualSpace(const ViewProviderSketch & vp);
static inline std::unique_ptr<SoRayPickAction> getRayPickAction(const ViewProviderSketch & vp);
static inline bool constraintHasExpression(const ViewProviderSketch& vp, int constrid);
static inline const std::vector<Sketcher::Constraint*>
getConstraints(const ViewProviderSketch& vp);
static inline const GeoList getGeoList(const ViewProviderSketch& vp);
static inline const GeoListFacade getGeoListFacade(const ViewProviderSketch& vp);
static inline Base::Placement getEditingPlacement(const ViewProviderSketch& vp);
static inline bool isShownVirtualSpace(const ViewProviderSketch& vp);
static inline std::unique_ptr<SoRayPickAction> getRayPickAction(const ViewProviderSketch& vp);
static inline float getScaleFactor(const ViewProviderSketch & vp);
static inline SbVec2f getScreenCoordinates(const ViewProviderSketch & vp, SbVec2f sketchcoordinates);
static inline QFont getApplicationFont(const ViewProviderSketch & vp);
static inline double getRotation(const ViewProviderSketch & vp, SbVec3f pos0, SbVec3f pos1);
static inline int defaultApplicationFontSizePixels(const ViewProviderSketch & vp);
static inline int getApplicationLogicalDPIX(const ViewProviderSketch & vp);
static inline int getViewOrientationFactor(const ViewProviderSketch & vp);
static inline float getScaleFactor(const ViewProviderSketch& vp);
static inline SbVec2f getScreenCoordinates(const ViewProviderSketch& vp,
SbVec2f sketchcoordinates);
static inline QFont getApplicationFont(const ViewProviderSketch& vp);
static inline double getRotation(const ViewProviderSketch& vp, SbVec3f pos0, SbVec3f pos1);
static inline int defaultApplicationFontSizePixels(const ViewProviderSketch& vp);
static inline int getApplicationLogicalDPIX(const ViewProviderSketch& vp);
static inline int getViewOrientationFactor(const ViewProviderSketch& vp);
static inline bool isSketchInvalid(const ViewProviderSketch & vp);
static inline bool isSketchFullyConstrained(const ViewProviderSketch & vp);
static inline bool haveConstraintsInvalidGeometry(const ViewProviderSketch & vp);
static inline bool isSketchInvalid(const ViewProviderSketch& vp);
static inline bool isSketchFullyConstrained(const ViewProviderSketch& vp);
static inline bool haveConstraintsInvalidGeometry(const ViewProviderSketch& vp);
static inline void addNodeToRoot(ViewProviderSketch & vp, SoSeparator * node);
static inline void addNodeToRoot(ViewProviderSketch& vp, SoSeparator* node);
static inline void removeNodeFromRoot(ViewProviderSketch & vp, SoSeparator * node);
static inline void removeNodeFromRoot(ViewProviderSketch& vp, SoSeparator* node);
static inline int getPreselectPoint(const ViewProviderSketch &vp);
static inline int getPreselectCurve(const ViewProviderSketch &vp);
static inline int getPreselectCross(const ViewProviderSketch &vp);
static inline int getPreselectPoint(const ViewProviderSketch& vp);
static inline int getPreselectCurve(const ViewProviderSketch& vp);
static inline int getPreselectCross(const ViewProviderSketch& vp);
static inline bool isConstraintPreselected(const ViewProviderSketch &vp, int constraintId);
static inline bool isPointSelected(const ViewProviderSketch &vp, int pointId);
static inline bool isCurveSelected(const ViewProviderSketch &vp, int curveId);
static inline bool isConstraintSelected(const ViewProviderSketch &vp, int constraintId);
static inline bool isConstraintPreselected(const ViewProviderSketch& vp, int constraintId);
static inline bool isPointSelected(const ViewProviderSketch& vp, int pointId);
static inline bool isCurveSelected(const ViewProviderSketch& vp, int curveId);
static inline bool isConstraintSelected(const ViewProviderSketch& vp, int constraintId);
static inline void executeOnSelectionPointSet(const ViewProviderSketch &vp, std::function<void(const int)> && operation);
static inline void executeOnSelectionPointSet(const ViewProviderSketch& vp,
std::function<void(const int)>&& operation);
friend class EditModeCoinManager;
friend class EditModeConstraintCoinManager;
@@ -117,145 +127,156 @@ private:
friend class EditModeGeometryCoinConverter;
};
inline bool ViewProviderSketchCoinAttorney::constraintHasExpression(const ViewProviderSketch & vp, int constrid)
inline bool ViewProviderSketchCoinAttorney::constraintHasExpression(const ViewProviderSketch& vp,
int constrid)
{
return vp.constraintHasExpression(constrid);
};
inline const std::vector<Sketcher::Constraint *> ViewProviderSketchCoinAttorney::getConstraints(const ViewProviderSketch & vp)
inline const std::vector<Sketcher::Constraint*>
ViewProviderSketchCoinAttorney::getConstraints(const ViewProviderSketch& vp)
{
return vp.getConstraints();
}
inline const GeoList ViewProviderSketchCoinAttorney::getGeoList(const ViewProviderSketch & vp)
inline const GeoList ViewProviderSketchCoinAttorney::getGeoList(const ViewProviderSketch& vp)
{
return vp.getGeoList();
}
const GeoListFacade ViewProviderSketchCoinAttorney::getGeoListFacade(const ViewProviderSketch & vp)
const GeoListFacade ViewProviderSketchCoinAttorney::getGeoListFacade(const ViewProviderSketch& vp)
{
return vp.getGeoListFacade();
return vp.getGeoListFacade();
}
inline Base::Placement ViewProviderSketchCoinAttorney::getEditingPlacement(const ViewProviderSketch & vp)
inline Base::Placement
ViewProviderSketchCoinAttorney::getEditingPlacement(const ViewProviderSketch& vp)
{
return vp.getEditingPlacement();
}
inline bool ViewProviderSketchCoinAttorney::isShownVirtualSpace(const ViewProviderSketch & vp)
inline bool ViewProviderSketchCoinAttorney::isShownVirtualSpace(const ViewProviderSketch& vp)
{
return vp.viewProviderParameters.isShownVirtualSpace;
}
inline std::unique_ptr<SoRayPickAction> ViewProviderSketchCoinAttorney::getRayPickAction(const ViewProviderSketch & vp)
inline std::unique_ptr<SoRayPickAction>
ViewProviderSketchCoinAttorney::getRayPickAction(const ViewProviderSketch& vp)
{
return vp.getRayPickAction();
}
inline float ViewProviderSketchCoinAttorney::getScaleFactor(const ViewProviderSketch & vp)
inline float ViewProviderSketchCoinAttorney::getScaleFactor(const ViewProviderSketch& vp)
{
return vp.getScaleFactor();
}
inline SbVec2f ViewProviderSketchCoinAttorney::getScreenCoordinates(const ViewProviderSketch & vp, SbVec2f sketchcoordinates)
inline SbVec2f ViewProviderSketchCoinAttorney::getScreenCoordinates(const ViewProviderSketch& vp,
SbVec2f sketchcoordinates)
{
return vp.getScreenCoordinates(sketchcoordinates);
}
inline QFont ViewProviderSketchCoinAttorney::getApplicationFont(const ViewProviderSketch & vp)
inline QFont ViewProviderSketchCoinAttorney::getApplicationFont(const ViewProviderSketch& vp)
{
return vp.getApplicationFont();
}
inline double ViewProviderSketchCoinAttorney::getRotation(const ViewProviderSketch & vp, SbVec3f pos0, SbVec3f pos1)
inline double ViewProviderSketchCoinAttorney::getRotation(const ViewProviderSketch& vp,
SbVec3f pos0, SbVec3f pos1)
{
return vp.getRotation(pos0,pos1);
return vp.getRotation(pos0, pos1);
}
inline int ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(const ViewProviderSketch & vp)
inline int
ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(const ViewProviderSketch& vp)
{
return vp.defaultFontSizePixels();
}
inline int ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(const ViewProviderSketch & vp)
inline int ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(const ViewProviderSketch& vp)
{
return vp.getApplicationLogicalDPIX();
}
inline int ViewProviderSketchCoinAttorney::getViewOrientationFactor(const ViewProviderSketch & vp)
inline int ViewProviderSketchCoinAttorney::getViewOrientationFactor(const ViewProviderSketch& vp)
{
return vp.getViewOrientationFactor();
}
inline bool ViewProviderSketchCoinAttorney::isSketchInvalid(const ViewProviderSketch & vp)
inline bool ViewProviderSketchCoinAttorney::isSketchInvalid(const ViewProviderSketch& vp)
{
return vp.isSketchInvalid();
}
inline bool ViewProviderSketchCoinAttorney::isSketchFullyConstrained(const ViewProviderSketch & vp)
inline bool ViewProviderSketchCoinAttorney::isSketchFullyConstrained(const ViewProviderSketch& vp)
{
return vp.isSketchFullyConstrained();
}
inline bool ViewProviderSketchCoinAttorney::haveConstraintsInvalidGeometry(const ViewProviderSketch & vp)
inline bool
ViewProviderSketchCoinAttorney::haveConstraintsInvalidGeometry(const ViewProviderSketch& vp)
{
return vp.haveConstraintsInvalidGeometry();
}
inline void ViewProviderSketchCoinAttorney::addNodeToRoot(ViewProviderSketch & vp, SoSeparator * node)
inline void ViewProviderSketchCoinAttorney::addNodeToRoot(ViewProviderSketch& vp, SoSeparator* node)
{
vp.addNodeToRoot(node);
}
inline void ViewProviderSketchCoinAttorney::removeNodeFromRoot(ViewProviderSketch & vp, SoSeparator * node)
inline void ViewProviderSketchCoinAttorney::removeNodeFromRoot(ViewProviderSketch& vp,
SoSeparator* node)
{
vp.removeNodeFromRoot(node);
}
inline int ViewProviderSketchCoinAttorney::getPreselectPoint(const ViewProviderSketch &vp)
inline int ViewProviderSketchCoinAttorney::getPreselectPoint(const ViewProviderSketch& vp)
{
return vp.getPreselectPoint();
return vp.getPreselectPoint();
}
inline int ViewProviderSketchCoinAttorney::getPreselectCurve(const ViewProviderSketch &vp)
inline int ViewProviderSketchCoinAttorney::getPreselectCurve(const ViewProviderSketch& vp)
{
return vp.getPreselectCurve();
}
inline int ViewProviderSketchCoinAttorney::getPreselectCross(const ViewProviderSketch &vp)
inline int ViewProviderSketchCoinAttorney::getPreselectCross(const ViewProviderSketch& vp)
{
return vp.getPreselectCross();
}
inline bool ViewProviderSketchCoinAttorney::isConstraintPreselected(const ViewProviderSketch &vp, int constraintId)
inline bool ViewProviderSketchCoinAttorney::isConstraintPreselected(const ViewProviderSketch& vp,
int constraintId)
{
return vp.isConstraintPreselected(constraintId);
}
inline bool ViewProviderSketchCoinAttorney::isPointSelected(const ViewProviderSketch &vp, int pointId)
inline bool ViewProviderSketchCoinAttorney::isPointSelected(const ViewProviderSketch& vp,
int pointId)
{
return vp.isPointSelected(pointId);
}
inline bool ViewProviderSketchCoinAttorney::isCurveSelected(const ViewProviderSketch &vp, int curveId)
inline bool ViewProviderSketchCoinAttorney::isCurveSelected(const ViewProviderSketch& vp,
int curveId)
{
return vp.isCurveSelected(curveId);
}
inline bool ViewProviderSketchCoinAttorney::isConstraintSelected(const ViewProviderSketch &vp, int constraintId)
inline bool ViewProviderSketchCoinAttorney::isConstraintSelected(const ViewProviderSketch& vp,
int constraintId)
{
return vp.isConstraintSelected(constraintId);
}
inline void ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(const ViewProviderSketch &vp, std::function<void(const int)> && operation)
inline void ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(
const ViewProviderSketch& vp, std::function<void(const int)>&& operation)
{
vp.executeOnSelectionPointSet(std::move(operation));
}
} // namespace SketcherGui
#endif // SKETCHERGUI_ViewProviderSketchCoinAttorney_H
}// namespace SketcherGui
#endif// SKETCHERGUI_ViewProviderSketchCoinAttorney_H
@@ -34,19 +34,21 @@
using namespace SketcherGui;
//---------- Geometry Extension
TYPESYSTEM_SOURCE(SketcherGui::ViewProviderSketchGeometryExtension,Part::GeometryPersistenceExtension)
TYPESYSTEM_SOURCE(SketcherGui::ViewProviderSketchGeometryExtension,
Part::GeometryPersistenceExtension)
ViewProviderSketchGeometryExtension::ViewProviderSketchGeometryExtension():RepresentationFactor(1.0), VisualLayerId(0)
{
ViewProviderSketchGeometryExtension::ViewProviderSketchGeometryExtension()
: RepresentationFactor(1.0)
, VisualLayerId(0)
{}
}
void ViewProviderSketchGeometryExtension::copyAttributes(Part::GeometryExtension * cpy) const
void ViewProviderSketchGeometryExtension::copyAttributes(Part::GeometryExtension* cpy) const
{
Part::GeometryExtension::copyAttributes(cpy);
static_cast<ViewProviderSketchGeometryExtension *>(cpy)->RepresentationFactor = this->RepresentationFactor;
static_cast<ViewProviderSketchGeometryExtension *>(cpy)->VisualLayerId = this->VisualLayerId;
static_cast<ViewProviderSketchGeometryExtension*>(cpy)->RepresentationFactor =
this->RepresentationFactor;
static_cast<ViewProviderSketchGeometryExtension*>(cpy)->VisualLayerId = this->VisualLayerId;
}
std::unique_ptr<Part::GeometryExtension> ViewProviderSketchGeometryExtension::copy() const
@@ -55,30 +57,31 @@ std::unique_ptr<Part::GeometryExtension> ViewProviderSketchGeometryExtension::co
copyAttributes(cpy.get());
#if defined (__GNUC__) && (__GNUC__ <=4)
#if defined(__GNUC__) && (__GNUC__ <= 4)
return std::move(cpy);
#else
return cpy;
#endif
}
void ViewProviderSketchGeometryExtension::restoreAttributes(Base::XMLReader &reader)
void ViewProviderSketchGeometryExtension::restoreAttributes(Base::XMLReader& reader)
{
Part::GeometryPersistenceExtension::restoreAttributes(reader);
if(reader.hasAttribute("visualLayerId"))
if (reader.hasAttribute("visualLayerId"))
VisualLayerId = reader.getAttributeAsInteger("visualLayerId");
}
void ViewProviderSketchGeometryExtension::saveAttributes(Base::Writer &writer) const
void ViewProviderSketchGeometryExtension::saveAttributes(Base::Writer& writer) const
{
Part::GeometryPersistenceExtension::saveAttributes(writer);
writer.Stream() << "\" visualLayerId=\"" << VisualLayerId;
writer.Stream() << "\" visualLayerId=\"" << VisualLayerId;
}
PyObject * ViewProviderSketchGeometryExtension::getPyObject()
PyObject* ViewProviderSketchGeometryExtension::getPyObject()
{
return new ViewProviderSketchGeometryExtensionPy(new ViewProviderSketchGeometryExtension(*this));
return new ViewProviderSketchGeometryExtensionPy(
new ViewProviderSketchGeometryExtension(*this));
}
@@ -27,38 +27,52 @@
#include <Mod/Sketcher/SketcherGlobal.h>
namespace SketcherGui {
namespace SketcherGui
{
class SketcherGuiExport ViewProviderSketchGeometryExtension : public Part::GeometryPersistenceExtension
class SketcherGuiExport ViewProviderSketchGeometryExtension
: public Part::GeometryPersistenceExtension
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
public:
ViewProviderSketchGeometryExtension();
~ViewProviderSketchGeometryExtension() override = default;
std::unique_ptr<Part::GeometryExtension> copy() const override;
PyObject *getPyObject() override;
PyObject* getPyObject() override;
// Data Members
// Representation factor
// Provides a mechanism to store a factor associated with the representation of a geometry
// This is only useful when a geometry must be scaled only for representation, while keeping its value
// Applicability: General abstract concepts embodied in a geometry, in practice B-Spline poles.
// Why not in SketchGeometryExtension? Because it is merely representation related. It has no place in
// a console application.
double getRepresentationFactor() const {return RepresentationFactor;}
void setRepresentationFactor(double representationFactor) {RepresentationFactor = representationFactor;}
// This is only useful when a geometry must be scaled only for representation, while keeping its
// value Applicability: General abstract concepts embodied in a geometry, in practice B-Spline
// poles. Why not in SketchGeometryExtension? Because it is merely representation related. It
// has no place in a console application.
double getRepresentationFactor() const
{
return RepresentationFactor;
}
void setRepresentationFactor(double representationFactor)
{
RepresentationFactor = representationFactor;
}
int getVisualLayerId() const {return VisualLayerId;}
void setVisualLayerId(int visuallayerid) {VisualLayerId = visuallayerid;}
int getVisualLayerId() const
{
return VisualLayerId;
}
void setVisualLayerId(int visuallayerid)
{
VisualLayerId = visuallayerid;
}
protected:
void copyAttributes(Part::GeometryExtension * cpy) const override;
void restoreAttributes(Base::XMLReader &reader) override;
void saveAttributes(Base::Writer &writer) const override;
void copyAttributes(Part::GeometryExtension* cpy) const override;
void restoreAttributes(Base::XMLReader& reader) override;
void saveAttributes(Base::Writer& writer) const override;
private:
ViewProviderSketchGeometryExtension(const ViewProviderSketchGeometryExtension&) = default;
@@ -68,7 +82,7 @@ private:
int VisualLayerId;
};
} //namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHER_VIEWPROVIDERSKETCHGEOMETRYEXTENSION_H
#endif// SKETCHER_VIEWPROVIDERSKETCHGEOMETRYEXTENSION_H
@@ -23,6 +23,7 @@
#include "PreCompiled.h"
#include "ViewProviderSketchGeometryExtensionPy.h"
#include "ViewProviderSketchGeometryExtensionPy.cpp"
@@ -38,7 +39,8 @@ std::string ViewProviderSketchGeometryExtensionPy::representation() const
return str.str();
}
PyObject *ViewProviderSketchGeometryExtensionPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
PyObject* ViewProviderSketchGeometryExtensionPy::PyMake(struct _typeobject*, PyObject*,
PyObject*)// Python wrapper
{
// create a new instance of PointPy and the Twin object
return new ViewProviderSketchGeometryExtensionPy(new ViewProviderSketchGeometryExtension);
@@ -60,9 +62,10 @@ int ViewProviderSketchGeometryExtensionPy::PyInit(PyObject* args, PyObject* /*kw
return 0;
}
PyErr_SetString(PyExc_TypeError, "ViewProviderSketchGeometryExtension constructor accepts:\n"
"-- empty parameter list\n"
"-- int\n");
PyErr_SetString(PyExc_TypeError,
"ViewProviderSketchGeometryExtension constructor accepts:\n"
"-- empty parameter list\n"
"-- int\n");
return -1;
}
@@ -76,13 +79,13 @@ void ViewProviderSketchGeometryExtensionPy::setVisualLayerId(Py::Long Id)
this->getViewProviderSketchGeometryExtensionPtr()->setVisualLayerId(Id);
}
PyObject *ViewProviderSketchGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
PyObject* ViewProviderSketchGeometryExtensionPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;
}
int ViewProviderSketchGeometryExtensionPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
int ViewProviderSketchGeometryExtensionPy::setCustomAttributes(const char* /*attr*/,
PyObject* /*obj*/)
{
return 0;
}
+12 -10
View File
@@ -31,7 +31,10 @@ using namespace SketcherGui;
//**************** VisualClassConfig **************************************//
VisualLayer::VisualLayer(unsigned int linePattern, float lineWidth, bool visible): linePattern(linePattern), lineWidth(lineWidth), visible(visible)
VisualLayer::VisualLayer(unsigned int linePattern, float lineWidth, bool visible)
: linePattern(linePattern)
, lineWidth(lineWidth)
, visible(visible)
{}
unsigned int VisualLayer::getLinePattern() const
@@ -64,23 +67,22 @@ void VisualLayer::setVisible(bool show)
visible = show;
}
void VisualLayer::Save(Base::Writer &writer) const
void VisualLayer::Save(Base::Writer& writer) const
{
writer.Stream() << writer.ind()
<< "<VisualLayer " <<
"visible=\"" << (visible?std::string("true"):std::string("false")).c_str() <<
"\" linePattern=\"" << linePattern <<
"\" lineWidth=\"" << lineWidth << "\"/>" << std::endl;
writer.Stream() << writer.ind() << "<VisualLayer "
<< "visible=\""
<< (visible ? std::string("true") : std::string("false")).c_str()
<< "\" linePattern=\"" << linePattern << "\" lineWidth=\"" << lineWidth
<< "\"/>" << std::endl;
}
void VisualLayer::Restore(Base::XMLReader &reader)
void VisualLayer::Restore(Base::XMLReader& reader)
{
reader.readElement("VisualLayer");
std::string str = reader.getAttribute("visible");
visible = ( str == "true");
visible = (str == "true");
linePattern = reader.getAttributeAsUnsigned("linePattern");
lineWidth = reader.getAttributeAsFloat("lineWidth");
}
+14 -13
View File
@@ -30,13 +30,15 @@ namespace SketcherGui
{
/** Provides the visual layer configuration for a class of geometry.
* A class of geometry can be any grouping of geometry, for
* which the user wants to provide a per coin layer specific
* configuration.
*/
class VisualLayer {
* A class of geometry can be any grouping of geometry, for
* which the user wants to provide a per coin layer specific
* configuration.
*/
class VisualLayer
{
public:
explicit VisualLayer(unsigned int linePattern = 0xFFFF, float lineWidth = 3.0, bool visible = true);
explicit VisualLayer(unsigned int linePattern = 0xFFFF, float lineWidth = 3.0,
bool visible = true);
unsigned int getLinePattern() const;
float getLineWidth() const;
@@ -47,8 +49,8 @@ public:
bool isVisible() const;
void setVisible(bool show);
void Save(Base::Writer &/*writer*/) const;
void Restore(Base::XMLReader &/*reader*/);
void Save(Base::Writer& /*writer*/) const;
void Restore(Base::XMLReader& /*reader*/);
private:
unsigned int linePattern;
@@ -60,12 +62,11 @@ private:
bool operator==(VisualLayer const& lhs, VisualLayer const& rhs)
{
return ( lhs.linePattern == rhs.linePattern ) &&
( lhs.lineWidth == rhs.lineWidth ) &&
( lhs.visible == rhs.visible );
return (lhs.linePattern == rhs.linePattern) && (lhs.lineWidth == rhs.lineWidth)
&& (lhs.visible == rhs.visible);
}
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHERGUI_VisualLayer_H
#endif// SKETCHERGUI_VisualLayer_H
+226 -224
View File
@@ -22,15 +22,15 @@
#include "PreCompiled.h"
#include <Mod/Sketcher/App/Constraint.h>
#include "Utils.h"
#include "Workbench.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Mod/Sketcher/App/Constraint.h>
using namespace SketcherGui;
#if 0 // needed for Qt's lupdate utility
#if 0// needed for Qt's lupdate utility
qApp->translate("CommandGroup", "Sketcher");
qApp->translate("Workbench","P&rofiles");
qApp->translate("Workbench","S&ketch");
@@ -46,28 +46,26 @@ using namespace SketcherGui;
TYPESYSTEM_SOURCE(SketcherGui::Workbench, Gui::StdWorkbench)
Workbench::Workbench()
{
}
{}
Workbench::~Workbench()
{
}
{}
Gui::MenuItem* Workbench::setupMenuBar() const
{
Gui::MenuItem* root = StdWorkbench::setupMenuBar();
Gui::MenuItem* item = root->findItem("&Windows");
// == Profile menu ==========================================
/* TODO: implement profile menu with different profiles
Gui::MenuItem* profile = new Gui::MenuItem;
root->insertItem(item, profile);
profile->setCommand("P&rofiles");
// == Profile menu ==========================================
/* TODO: implement profile menu with different profiles
Gui::MenuItem* profile = new Gui::MenuItem;
root->insertItem(item, profile);
profile->setCommand("P&rofiles");
*profile << "Sketcher_ProfilesHexagon1";
*/
*profile << "Sketcher_ProfilesHexagon1";
*/
// == Sketcher menu ==========================================
// == Sketcher menu ==========================================
Gui::MenuItem* geom = new Gui::MenuItem();
geom->setCommand("Sketcher geometries");
@@ -94,11 +92,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
sketch->setCommand("S&ketch");
addSketcherWorkbenchSketchActions(*sketch);
addSketcherWorkbenchSketchEditModeActions(*sketch);
*sketch << geom
<< cons
<< consaccel
<< bsplines
<< virtualspace;
*sketch << geom << cons << consaccel << bsplines << virtualspace;
return root;
}
@@ -111,7 +105,8 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
sketcher->setCommand("Sketcher");
addSketcherWorkbenchSketchActions(*sketcher);
Gui::ToolBarItem* sketcherEditMode = new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
Gui::ToolBarItem* sketcherEditMode =
new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
sketcherEditMode->setCommand("Sketcher Edit Mode");
addSketcherWorkbenchSketchEditModeActions(*sketcherEditMode);
@@ -123,7 +118,8 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
cons->setCommand("Sketcher constraints");
addSketcherWorkbenchConstraints(*cons);
Gui::ToolBarItem* consaccel = new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
Gui::ToolBarItem* consaccel =
new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
consaccel->setCommand("Sketcher tools");
addSketcherWorkbenchTools(*consaccel);
@@ -131,15 +127,17 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
bspline->setCommand("Sketcher B-spline tools");
addSketcherWorkbenchBSplines(*bspline);
Gui::ToolBarItem* virtualspace = new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
Gui::ToolBarItem* virtualspace =
new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
virtualspace->setCommand("Sketcher virtual space");
addSketcherWorkbenchVirtualSpace(*virtualspace);
Gui::ToolBarItem* edittools = new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
Gui::ToolBarItem* edittools =
new Gui::ToolBarItem(root, Gui::ToolBarItem::HideStyle::FORCE_HIDE);
edittools->setCommand("Sketcher edit tools");
addSketcherWorkbenchEditTools(*edittools);
return root;
return root;
}
Gui::ToolBarItem* Workbench::setupCommandBars() const
@@ -151,7 +149,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
void Workbench::activated()
{
Gui::Document *doc = Gui::Application::Instance->activeDocument();
Gui::Document* doc = Gui::Application::Instance->activeDocument();
if (isSketchInEdit(doc)) {
enterEditMode();
}
@@ -159,29 +157,29 @@ void Workbench::activated()
namespace
{
inline const QStringList editModeToolbarNames()
{
return QStringList{ QString::fromLatin1("Sketcher Edit Mode"),
QString::fromLatin1("Sketcher geometries"),
QString::fromLatin1("Sketcher constraints"),
QString::fromLatin1("Sketcher tools"),
QString::fromLatin1("Sketcher B-spline tools"),
QString::fromLatin1("Sketcher virtual space"),
QString::fromLatin1("Sketcher edit tools")};
}
inline const QStringList nonEditModeToolbarNames()
{
return QStringList{ QString::fromLatin1("Structure"),
QString::fromLatin1("Sketcher") };
}
inline const QStringList editModeToolbarNames()
{
return QStringList {QString::fromLatin1("Sketcher Edit Mode"),
QString::fromLatin1("Sketcher geometries"),
QString::fromLatin1("Sketcher constraints"),
QString::fromLatin1("Sketcher tools"),
QString::fromLatin1("Sketcher B-spline tools"),
QString::fromLatin1("Sketcher virtual space"),
QString::fromLatin1("Sketcher edit tools")};
}
inline const QStringList nonEditModeToolbarNames()
{
return QStringList {QString::fromLatin1("Structure"), QString::fromLatin1("Sketcher")};
}
}// namespace
void Workbench::enterEditMode()
{
/*Modify toolbars dynamically.
First save state of toolbars in case user changed visibility of a toolbar but he's not changing the wb.
This happens in someone works directly from sketcher, changing from edit mode to not-edit-mode*/
First save state of toolbars in case user changed visibility of a toolbar but he's not changing
the wb. This happens in someone works directly from sketcher, changing from edit mode to
not-edit-mode*/
Gui::ToolBarManager::getInstance()->saveState();
Gui::ToolBarManager::getInstance()->setToolbarVisibility(true, editModeToolbarNames());
@@ -191,276 +189,280 @@ void Workbench::enterEditMode()
void Workbench::leaveEditMode()
{
/*Modify toolbars dynamically.
First save state of toolbars in case user changed visibility of a toolbar but he's not changing the wb.
This happens in someone works directly from sketcher, changing from edit mode to not-edit-mode*/
First save state of toolbars in case user changed visibility of a toolbar but he's not changing
the wb. This happens in someone works directly from sketcher, changing from edit mode to
not-edit-mode*/
Gui::ToolBarManager::getInstance()->saveState();
Gui::ToolBarManager::getInstance()->setToolbarVisibility(false, editModeToolbarNames());
Gui::ToolBarManager::getInstance()->setToolbarVisibility(true, nonEditModeToolbarNames());
}
namespace SketcherGui {
namespace SketcherGui
{
template <typename T>
template<typename T>
void SketcherAddWorkbenchSketchActions(T& sketch);
template <>
template<>
inline void SketcherAddWorkbenchSketchActions(Gui::MenuItem& sketch)
{
sketch << "Sketcher_NewSketch"
<< "Sketcher_EditSketch"
<< "Sketcher_MapSketch"
<< "Sketcher_ReorientSketch"
<< "Sketcher_ValidateSketch"
<< "Sketcher_MergeSketches"
<< "Sketcher_MirrorSketch";
sketch << "Sketcher_NewSketch"
<< "Sketcher_EditSketch"
<< "Sketcher_MapSketch"
<< "Sketcher_ReorientSketch"
<< "Sketcher_ValidateSketch"
<< "Sketcher_MergeSketches"
<< "Sketcher_MirrorSketch";
}
template <>
template<>
inline void SketcherAddWorkbenchSketchActions(Gui::ToolBarItem& sketch)
{
sketch << "Sketcher_NewSketch"
<< "Sketcher_EditSketch"
<< "Sketcher_MapSketch"
<< "Sketcher_ReorientSketch"
<< "Sketcher_ValidateSketch"
<< "Sketcher_MergeSketches"
<< "Sketcher_MirrorSketch";
sketch << "Sketcher_NewSketch"
<< "Sketcher_EditSketch"
<< "Sketcher_MapSketch"
<< "Sketcher_ReorientSketch"
<< "Sketcher_ValidateSketch"
<< "Sketcher_MergeSketches"
<< "Sketcher_MirrorSketch";
}
template <typename T>
template<typename T>
void SketcherAddWorkbenchSketchEditModeActions(T& sketch);
template <>
template<>
inline void SketcherAddWorkbenchSketchEditModeActions(Gui::MenuItem& sketch)
{
sketch << "Sketcher_LeaveSketch"
<< "Sketcher_ViewSketch"
<< "Sketcher_ViewSection"
<< "Sketcher_StopOperation";
sketch << "Sketcher_LeaveSketch"
<< "Sketcher_ViewSketch"
<< "Sketcher_ViewSection"
<< "Sketcher_StopOperation";
}
template <>
template<>
inline void SketcherAddWorkbenchSketchEditModeActions(Gui::ToolBarItem& sketch)
{
sketch << "Sketcher_LeaveSketch"
<< "Sketcher_ViewSketch"
<< "Sketcher_ViewSection";
sketch << "Sketcher_LeaveSketch"
<< "Sketcher_ViewSketch"
<< "Sketcher_ViewSection";
}
template <typename T>
template<typename T>
void SketcherAddWorkbenchGeometries(T& geom);
template <typename T>
template<typename T>
void SketcherAddWorkspaceArcs(T& geom);
template <>
template<>
inline void SketcherAddWorkspaceArcs<Gui::MenuItem>(Gui::MenuItem& geom)
{
geom << "Sketcher_CreateArc"
<< "Sketcher_Create3PointArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_Create3PointCircle"
<< "Sketcher_CreateEllipseByCenter"
<< "Sketcher_CreateEllipseBy3Points"
<< "Sketcher_CreateArcOfEllipse"
<< "Sketcher_CreateArcOfHyperbola"
<< "Sketcher_CreateArcOfParabola"
<< "Sketcher_CreateBSpline"
<< "Sketcher_CreatePeriodicBSpline"
<< "Sketcher_CreateBSplineByInterpolation"
<< "Sketcher_CreatePeriodicBSplineByInterpolation";
geom << "Sketcher_CreateArc"
<< "Sketcher_Create3PointArc"
<< "Sketcher_CreateCircle"
<< "Sketcher_Create3PointCircle"
<< "Sketcher_CreateEllipseByCenter"
<< "Sketcher_CreateEllipseBy3Points"
<< "Sketcher_CreateArcOfEllipse"
<< "Sketcher_CreateArcOfHyperbola"
<< "Sketcher_CreateArcOfParabola"
<< "Sketcher_CreateBSpline"
<< "Sketcher_CreatePeriodicBSpline"
<< "Sketcher_CreateBSplineByInterpolation"
<< "Sketcher_CreatePeriodicBSplineByInterpolation";
}
template <>
template<>
inline void SketcherAddWorkspaceArcs<Gui::ToolBarItem>(Gui::ToolBarItem& geom)
{
geom << "Sketcher_CompCreateArc"
<< "Sketcher_CompCreateCircle"
<< "Sketcher_CompCreateConic"
<< "Sketcher_CompCreateBSpline";
geom << "Sketcher_CompCreateArc"
<< "Sketcher_CompCreateCircle"
<< "Sketcher_CompCreateConic"
<< "Sketcher_CompCreateBSpline";
}
template <typename T>
template<typename T>
void SketcherAddWorkspaceRegularPolygon(T& geom);
template <>
template<>
inline void SketcherAddWorkspaceRegularPolygon<Gui::MenuItem>(Gui::MenuItem& geom)
{
geom << "Sketcher_CreateTriangle"
<< "Sketcher_CreateSquare"
<< "Sketcher_CreatePentagon"
<< "Sketcher_CreateHexagon"
<< "Sketcher_CreateHeptagon"
<< "Sketcher_CreateOctagon"
<< "Sketcher_CreateRegularPolygon";
geom << "Sketcher_CreateTriangle"
<< "Sketcher_CreateSquare"
<< "Sketcher_CreatePentagon"
<< "Sketcher_CreateHexagon"
<< "Sketcher_CreateHeptagon"
<< "Sketcher_CreateOctagon"
<< "Sketcher_CreateRegularPolygon";
}
template <>
template<>
inline void SketcherAddWorkspaceRegularPolygon<Gui::ToolBarItem>(Gui::ToolBarItem& geom)
{
geom << "Sketcher_CompCreateRegularPolygon";
geom << "Sketcher_CompCreateRegularPolygon";
}
template <typename T>
template<typename T>
void SketcherAddWorkspaceRectangles(T& geom);
template <>
template<>
inline void SketcherAddWorkspaceRectangles<Gui::MenuItem>(Gui::MenuItem& geom)
{
geom << "Sketcher_CreateRectangle"
<< "Sketcher_CreateRectangle_Center"
<< "Sketcher_CreateOblong";
geom << "Sketcher_CreateRectangle"
<< "Sketcher_CreateRectangle_Center"
<< "Sketcher_CreateOblong";
}
template <>
template<>
inline void SketcherAddWorkspaceRectangles<Gui::ToolBarItem>(Gui::ToolBarItem& geom)
{
geom << "Sketcher_CompCreateRectangles";
}
template <typename T>
template<typename T>
void SketcherAddWorkspaceFillets(T& geom);
template <>
template<>
inline void SketcherAddWorkspaceFillets<Gui::MenuItem>(Gui::MenuItem& geom)
{
geom << "Sketcher_CreateFillet"
<< "Sketcher_CreatePointFillet";
geom << "Sketcher_CreateFillet"
<< "Sketcher_CreatePointFillet";
}
template <>
template<>
inline void SketcherAddWorkspaceFillets<Gui::ToolBarItem>(Gui::ToolBarItem& geom)
{
geom << "Sketcher_CompCreateFillets";
geom << "Sketcher_CompCreateFillets";
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchGeometries(T& geom)
{
geom << "Sketcher_CreatePoint"
<< "Sketcher_CreateLine";
geom << "Sketcher_CreatePoint"
<< "Sketcher_CreateLine";
SketcherAddWorkspaceArcs(geom);
geom << "Separator"
<< "Sketcher_CreatePolyline";
geom << "Separator"
<< "Sketcher_CreatePolyline";
SketcherAddWorkspaceRectangles(geom);
SketcherAddWorkspaceRegularPolygon(geom);
geom << "Sketcher_CreateSlot"
<< "Separator";
geom << "Sketcher_CreateSlot"
<< "Separator";
SketcherAddWorkspaceFillets(geom);
geom << "Sketcher_Trimming"
<< "Sketcher_Extend"
<< "Sketcher_Split"
<< "Sketcher_External"
<< "Sketcher_CarbonCopy"
<< "Sketcher_ToggleConstruction"
/*<< "Sketcher_CreateText"*/
/*<< "Sketcher_CreateDraftLine"*/;
geom << "Sketcher_Trimming"
<< "Sketcher_Extend"
<< "Sketcher_Split"
<< "Sketcher_External"
<< "Sketcher_CarbonCopy"
<< "Sketcher_ToggleConstruction"
/*<< "Sketcher_CreateText"*/
/*<< "Sketcher_CreateDraftLine"*/;
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchConstraints(T& cons);
template <>
template<>
inline void SketcherAddWorkbenchConstraints<Gui::MenuItem>(Gui::MenuItem& cons)
{
cons << "Sketcher_ConstrainCoincident"
<< "Sketcher_ConstrainPointOnObject"
<< "Sketcher_ConstrainVertical"
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainTangent"
<< "Sketcher_ConstrainEqual"
<< "Sketcher_ConstrainSymmetric"
<< "Sketcher_ConstrainBlock"
<< "Separator"
<< "Sketcher_ConstrainLock"
<< "Sketcher_ConstrainDistanceX"
<< "Sketcher_ConstrainDistanceY"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
<< "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainRadiam"
<< "Sketcher_ConstrainAngle"
<< "Sketcher_ConstrainSnellsLaw"
<< "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ToggleActiveConstraint";
cons << "Sketcher_ConstrainCoincident"
<< "Sketcher_ConstrainPointOnObject"
<< "Sketcher_ConstrainVertical"
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainTangent"
<< "Sketcher_ConstrainEqual"
<< "Sketcher_ConstrainSymmetric"
<< "Sketcher_ConstrainBlock"
<< "Separator"
<< "Sketcher_ConstrainLock"
<< "Sketcher_ConstrainDistanceX"
<< "Sketcher_ConstrainDistanceY"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_ConstrainRadius"
<< "Sketcher_ConstrainDiameter"
<< "Sketcher_ConstrainRadiam"
<< "Sketcher_ConstrainAngle"
<< "Sketcher_ConstrainSnellsLaw"
<< "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ToggleActiveConstraint";
}
template <>
template<>
inline void SketcherAddWorkbenchConstraints<Gui::ToolBarItem>(Gui::ToolBarItem& cons)
{
cons << "Sketcher_ConstrainCoincident"
<< "Sketcher_ConstrainPointOnObject"
<< "Sketcher_ConstrainVertical"
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainTangent"
<< "Sketcher_ConstrainEqual"
<< "Sketcher_ConstrainSymmetric"
<< "Sketcher_ConstrainBlock"
<< "Separator"
<< "Sketcher_ConstrainLock"
<< "Sketcher_ConstrainDistanceX"
<< "Sketcher_ConstrainDistanceY"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_CompConstrainRadDia"
<< "Sketcher_ConstrainAngle"
// << "Sketcher_ConstrainSnellsLaw" // Rarely used, show only in menu
<< "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ToggleActiveConstraint";
cons << "Sketcher_ConstrainCoincident"
<< "Sketcher_ConstrainPointOnObject"
<< "Sketcher_ConstrainVertical"
<< "Sketcher_ConstrainHorizontal"
<< "Sketcher_ConstrainParallel"
<< "Sketcher_ConstrainPerpendicular"
<< "Sketcher_ConstrainTangent"
<< "Sketcher_ConstrainEqual"
<< "Sketcher_ConstrainSymmetric"
<< "Sketcher_ConstrainBlock"
<< "Separator"
<< "Sketcher_ConstrainLock"
<< "Sketcher_ConstrainDistanceX"
<< "Sketcher_ConstrainDistanceY"
<< "Sketcher_ConstrainDistance"
<< "Sketcher_CompConstrainRadDia"
<< "Sketcher_ConstrainAngle"
// << "Sketcher_ConstrainSnellsLaw" // Rarely used, show only in menu
<< "Separator"
<< "Sketcher_ToggleDrivingConstraint"
<< "Sketcher_ToggleActiveConstraint";
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchTools(T& consaccel);
template <>
template<>
inline void SketcherAddWorkbenchTools<Gui::MenuItem>(Gui::MenuItem& consaccel)
{
consaccel << "Sketcher_SelectElementsWithDoFs"
<< "Sketcher_SelectConstraints"
<< "Sketcher_SelectElementsAssociatedWithConstraints"
<< "Sketcher_SelectRedundantConstraints"
<< "Sketcher_SelectConflictingConstraints"
<< "Sketcher_RestoreInternalAlignmentGeometry"
<< "Separator"
<< "Sketcher_SelectOrigin"
<< "Sketcher_SelectHorizontalAxis"
<< "Sketcher_SelectVerticalAxis"
<< "Separator"
<< "Sketcher_Symmetry"
<< "Sketcher_Clone"
<< "Sketcher_Copy"
<< "Sketcher_Move"
<< "Sketcher_RectangularArray"
<< "Sketcher_RemoveAxesAlignment"
<< "Separator"
<< "Sketcher_DeleteAllGeometry"
<< "Sketcher_DeleteAllConstraints";
consaccel << "Sketcher_SelectElementsWithDoFs"
<< "Sketcher_SelectConstraints"
<< "Sketcher_SelectElementsAssociatedWithConstraints"
<< "Sketcher_SelectRedundantConstraints"
<< "Sketcher_SelectConflictingConstraints"
<< "Sketcher_RestoreInternalAlignmentGeometry"
<< "Separator"
<< "Sketcher_SelectOrigin"
<< "Sketcher_SelectHorizontalAxis"
<< "Sketcher_SelectVerticalAxis"
<< "Separator"
<< "Sketcher_Symmetry"
<< "Sketcher_Clone"
<< "Sketcher_Copy"
<< "Sketcher_Move"
<< "Sketcher_RectangularArray"
<< "Sketcher_RemoveAxesAlignment"
<< "Separator"
<< "Sketcher_DeleteAllGeometry"
<< "Sketcher_DeleteAllConstraints";
}
template <>
template<>
inline void SketcherAddWorkbenchTools<Gui::ToolBarItem>(Gui::ToolBarItem& consaccel)
{
consaccel //<< "Sketcher_SelectElementsWithDoFs" //rarely used, it is usually accessed by solver message.
<< "Sketcher_SelectConstraints"
<< "Sketcher_SelectElementsAssociatedWithConstraints"
//<< "Sketcher_SelectRedundantConstraints" //rarely used, it is usually accessed by solver message.
//<< "Sketcher_SelectConflictingConstraints"
<< "Sketcher_RestoreInternalAlignmentGeometry"
<< "Sketcher_Symmetry"
<< "Sketcher_CompCopy"
<< "Sketcher_RectangularArray"
<< "Sketcher_RemoveAxesAlignment"
<< "Sketcher_DeleteAllConstraints";
consaccel//<< "Sketcher_SelectElementsWithDoFs" //rarely used, it is usually accessed by solver
// message.
<< "Sketcher_SelectConstraints"
<< "Sketcher_SelectElementsAssociatedWithConstraints"
//<< "Sketcher_SelectRedundantConstraints" //rarely used, it is usually accessed by solver
// message.
//<< "Sketcher_SelectConflictingConstraints"
<< "Sketcher_RestoreInternalAlignmentGeometry"
<< "Sketcher_Symmetry"
<< "Sketcher_CompCopy"
<< "Sketcher_RectangularArray"
<< "Sketcher_RemoveAxesAlignment"
<< "Sketcher_DeleteAllConstraints";
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchBSplines(T& bspline);
template <>
template<>
inline void SketcherAddWorkbenchBSplines<Gui::MenuItem>(Gui::MenuItem& bspline)
{
bspline << "Sketcher_BSplineDegree"
@@ -477,7 +479,7 @@ inline void SketcherAddWorkbenchBSplines<Gui::MenuItem>(Gui::MenuItem& bspline)
<< "Sketcher_JoinCurves";
}
template <>
template<>
inline void SketcherAddWorkbenchBSplines<Gui::ToolBarItem>(Gui::ToolBarItem& bspline)
{
bspline << "Sketcher_CompBSplineShowHideGeometryInformation"
@@ -489,30 +491,30 @@ inline void SketcherAddWorkbenchBSplines<Gui::ToolBarItem>(Gui::ToolBarItem& bsp
<< "Sketcher_JoinCurves";
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchVirtualSpace(T& virtualspace);
template <>
template<>
inline void SketcherAddWorkbenchVirtualSpace<Gui::MenuItem>(Gui::MenuItem& virtualspace)
{
virtualspace << "Sketcher_SwitchVirtualSpace";
}
template <>
template<>
inline void SketcherAddWorkbenchVirtualSpace<Gui::ToolBarItem>(Gui::ToolBarItem& virtualspace)
{
virtualspace << "Sketcher_SwitchVirtualSpace";
}
template <typename T>
template<typename T>
inline void SketcherAddWorkbenchEditTools(T& virtualspedittoolsace);
template <>
template<>
inline void SketcherAddWorkbenchEditTools<Gui::ToolBarItem>(Gui::ToolBarItem& edittools)
{
edittools << "Sketcher_Grid"
<< "Sketcher_Snap"
<< "Sketcher_RenderingOrder";
edittools << "Sketcher_Grid"
<< "Sketcher_Snap"
<< "Sketcher_RenderingOrder";
}
void addSketcherWorkbenchSketchActions(Gui::MenuItem& sketch)
+5 -4
View File
@@ -30,12 +30,13 @@
#include <Mod/Sketcher/SketcherGlobal.h>
namespace SketcherGui {
namespace SketcherGui
{
/**
* @author Werner Mayer
*/
class SketcherGuiExport Workbench : public Gui::StdWorkbench
class SketcherGuiExport Workbench: public Gui::StdWorkbench
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
@@ -70,6 +71,6 @@ SketcherGuiExport void addSketcherWorkbenchBSplines(Gui::ToolBarItem& bspline);
SketcherGuiExport void addSketcherWorkbenchVirtualSpace(Gui::ToolBarItem& virtualspace);
SketcherGuiExport void addSketcherWorkbenchEditTools(Gui::ToolBarItem& edittools);
} // namespace SketcherGui
}// namespace SketcherGui
#endif // SKETCHER_WORKBENCH_H
#endif// SKETCHER_WORKBENCH_H