[Sketcher] Auto horizontal/vertical (#11330)
* Refactor sketcher horizontal / vertical constraints and adds a horizontal/vertical command. * Sketcher : HorVer : change tool icon. --------- Co-authored-by: Paddle <PaddleStroke@users.noreply.github.com>
This commit is contained in:
@@ -2592,6 +2592,347 @@ bool CmdSketcherDimension::isActive(void)
|
||||
return isCommandActive(getActiveGuiDocument());
|
||||
}
|
||||
|
||||
// Comp for horizontal/vertical =============================================
|
||||
|
||||
class CmdSketcherCompHorizontalVertical : public Gui::GroupCommand
|
||||
{
|
||||
public:
|
||||
CmdSketcherCompHorizontalVertical()
|
||||
: GroupCommand("Sketcher_CompHorVer")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Horizontal/Vertical");
|
||||
sToolTipText = QT_TR_NOOP("Constrains a single line to either horizontal or vertical.");
|
||||
sWhatsThis = "Sketcher_CompHorVer";
|
||||
sStatusTip = sToolTipText;
|
||||
eType = ForEdit;
|
||||
|
||||
setCheckable(false);
|
||||
|
||||
addCommand("Sketcher_ConstrainHorVer");
|
||||
addCommand("Sketcher_ConstrainHorizontal");
|
||||
addCommand("Sketcher_ConstrainVertical");
|
||||
}
|
||||
|
||||
const char* className() const override { return "CmdSketcherCompDimensionTools"; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
bool canHorVerBlock(Sketcher::SketchObject* Obj, int geoId)
|
||||
{
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
// check if the edge already has a Horizontal/Vertical/Block constraint
|
||||
for (auto& constr : vals) {
|
||||
if (constr->Type == Sketcher::Horizontal && constr->First == geoId
|
||||
&& constr->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Double constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return false;
|
||||
}
|
||||
if (constr->Type == Sketcher::Vertical && constr->First == geoId
|
||||
&& constr->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a vertical constraint!"));
|
||||
return false;
|
||||
}
|
||||
// check if the edge already has a Block constraint
|
||||
if (constr->Type == Sketcher::Block && constr->First == geoId
|
||||
&& constr->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a Block constraint!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void horVerActivated(CmdSketcherConstraint* cmd, std::string type)
|
||||
{
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = Gui::Command::getSelection().getSelectionEx();
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1
|
||||
|| !selection[0].isObjectTypeOf(Sketcher::SketchObject::getClassTypeId())) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool constraintMode = hGrp->GetBool("ContinuousConstraintMode", true);
|
||||
|
||||
if (constraintMode) {
|
||||
ActivateHandler(cmd->getActiveGuiDocument(), new DrawSketchHandlerGenConstraint(cmd));
|
||||
Gui::Command::getSelection().clearSelection();
|
||||
}
|
||||
else {
|
||||
Gui::TranslatedUserWarning(cmd->getActiveGuiDocument(),
|
||||
QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select an edge from the sketch."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string>& SubNames = selection[0].getSubNames();
|
||||
auto* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
std::vector<int> edgegeoids;
|
||||
std::vector<int> pointgeoids;
|
||||
std::vector<Sketcher::PointPos> pointpos;
|
||||
|
||||
int fixedpoints = 0;
|
||||
|
||||
for (auto& name : SubNames) {
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
getIdsFromName(name, Obj, GeoId, PosId);
|
||||
|
||||
if (isEdge(GeoId, PosId)) {// it is an edge
|
||||
const Part::Geometry* geo = Obj->getGeometry(GeoId);
|
||||
|
||||
if (!isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (canHorVerBlock(Obj, GeoId)) {
|
||||
edgegeoids.push_back(GeoId);
|
||||
}
|
||||
}
|
||||
else if (isVertex(GeoId, PosId)) {
|
||||
// can be a point, a construction point, an external point or root
|
||||
|
||||
if (isPointOrSegmentFixed(Obj, GeoId)) {
|
||||
fixedpoints++;
|
||||
}
|
||||
|
||||
pointgeoids.push_back(GeoId);
|
||||
pointpos.push_back(PosId);
|
||||
}
|
||||
}
|
||||
|
||||
if (edgegeoids.empty() && pointgeoids.empty()) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected item(s) can't accept a horizontal or vertical constraint!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is at least one edge selected, ignore the point alignment functionality
|
||||
if (!edgegeoids.empty()) {
|
||||
// undo command open
|
||||
const char* cmdName = type == "Horizontal" ? "Add horizontal constraint" : type == "Vertical" ? "Add vertical constraint" : "Add horizontal/vertical constraint";
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", cmdName));
|
||||
for (auto& geoId : edgegeoids) {
|
||||
std::string typeToApply = type;
|
||||
if (type == "HorVer") {
|
||||
const Part::Geometry* geo = Obj->getGeometry(geoId);
|
||||
auto* line = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
double angle = toVector2d(line->getEndPoint() - line->getStartPoint()).Angle();
|
||||
typeToApply = fabs(sin(angle)) < fabs(cos(angle)) ? "Horizontal" : "Vertical";
|
||||
}
|
||||
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('%s',%d))",
|
||||
typeToApply,
|
||||
geoId);
|
||||
}
|
||||
}
|
||||
else if (fixedpoints <= 1) {// pointgeoids
|
||||
// undo command open
|
||||
const char* cmdName = type == "Horizontal" ? "Add horizontal alignment" : type == "Vertical" ? "Add vertical alignment" : "Add horizontal/vertical alignment";
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", cmdName));
|
||||
std::vector<int>::iterator it;
|
||||
std::vector<Sketcher::PointPos>::iterator itp;
|
||||
for (it = pointgeoids.begin(), itp = pointpos.begin();
|
||||
it != std::prev(pointgeoids.end()) && itp != std::prev(pointpos.end());
|
||||
it++, itp++) {
|
||||
|
||||
std::string typeToApply = type;
|
||||
if (type == "HorVer") {
|
||||
auto point1 = Obj->getPoint(*it, *itp);
|
||||
auto point2 = Obj->getPoint(*std::next(it), *std::next(itp));
|
||||
double angle = toVector2d(point2 - point1).Angle();
|
||||
typeToApply = fabs(sin(angle)) < fabs(cos(angle)) ? "Horizontal" : "Vertical";
|
||||
}
|
||||
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('%s',%d,%d,%d,%d))",
|
||||
typeToApply,
|
||||
*it,
|
||||
static_cast<int>(*itp),
|
||||
*std::next(it),
|
||||
static_cast<int>(*std::next(itp)));
|
||||
}
|
||||
}
|
||||
else {// vertex mode, fixedpoints > 1
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("There are more than one fixed points selected. "
|
||||
"Select a maximum of one fixed point!"));
|
||||
return;
|
||||
}
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
// clear the selection (convenience)
|
||||
Gui::Command::getSelection().clearSelection();
|
||||
}
|
||||
|
||||
void horVerApplyConstraint(CmdSketcherConstraint* cmd, std::string type, std::vector<SelIdPair>& selSeq, int seqIndex)
|
||||
{
|
||||
auto* sketchgui =
|
||||
static_cast<SketcherGui::ViewProviderSketch*>(cmd->getActiveGuiDocument()->getInEdit());
|
||||
Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
|
||||
|
||||
switch (seqIndex) {
|
||||
case 0:// {Edge}
|
||||
{
|
||||
// create the constraint
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
int CrvId = selSeq.front().GeoId;
|
||||
if (CrvId != -1) {
|
||||
const Part::Geometry* geo = Obj->getGeometry(CrvId);
|
||||
|
||||
if (!isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the edge already has a Horizontal/Vertical/Block constraint
|
||||
if (!canHorVerBlock(Obj, CrvId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string typeToApply = type;
|
||||
if (type == "HorVer") {
|
||||
const Part::Geometry* geo = Obj->getGeometry(CrvId);
|
||||
auto* line = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
double angle = toVector2d(line->getEndPoint() - line->getStartPoint()).Angle();
|
||||
typeToApply = fabs(sin(angle)) < fabs(cos(angle)) ? "Horizontal" : "Vertical";
|
||||
}
|
||||
|
||||
const char* cmdName = typeToApply == "Horizontal" ? "Add horizontal constraint" : "Add vertical constraint";
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", cmdName));
|
||||
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('%s',%d))",
|
||||
typeToApply,
|
||||
CrvId);
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:// {SelVertex, SelVertexOrRoot}
|
||||
case 2:// {SelRoot, SelVertex}
|
||||
{
|
||||
int GeoId1, GeoId2;
|
||||
Sketcher::PointPos PosId1, PosId2;
|
||||
GeoId1 = selSeq.at(0).GeoId;
|
||||
GeoId2 = selSeq.at(1).GeoId;
|
||||
PosId1 = selSeq.at(0).PosId;
|
||||
PosId2 = selSeq.at(1).PosId;
|
||||
|
||||
if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)) {
|
||||
showNoConstraintBetweenFixedGeometry(Obj);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string typeToApply = type;
|
||||
if (type == "HorVer") {
|
||||
auto point1 = Obj->getPoint(GeoId1, PosId1);
|
||||
auto point2 = Obj->getPoint(GeoId2, PosId2);
|
||||
double angle = toVector2d(point2 - point1).Angle();
|
||||
typeToApply = fabs(sin(angle)) < fabs(cos(angle)) ? "Horizontal" : "Vertical";
|
||||
}
|
||||
|
||||
// undo command open
|
||||
const char* cmdName = type == "Horizontal" ? "Add horizontal alignment" : "Add vertical alignment";
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", cmdName));
|
||||
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('%s',%d,%d,%d,%d))",
|
||||
typeToApply,
|
||||
GeoId1,
|
||||
static_cast<int>(PosId1),
|
||||
GeoId2,
|
||||
static_cast<int>(PosId2));
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CmdSketcherConstrainHorVer : public CmdSketcherConstraint
|
||||
{
|
||||
public:
|
||||
CmdSketcherConstrainHorVer();
|
||||
~CmdSketcherConstrainHorVer() override
|
||||
{}
|
||||
const char* className() const override
|
||||
{
|
||||
return "CmdSketcherConstrainHorVer";
|
||||
}
|
||||
|
||||
protected:
|
||||
void activated(int iMsg) override;
|
||||
void applyConstraint(std::vector<SelIdPair>& selSeq, int seqIndex) override;
|
||||
};
|
||||
|
||||
CmdSketcherConstrainHorVer::CmdSketcherConstrainHorVer()
|
||||
: CmdSketcherConstraint("Sketcher_ConstrainHorVer")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("Horizontal/Vertical");
|
||||
sToolTipText = QT_TR_NOOP("Constrains a single line to either horizontal or vertical, whichever is closer to current alignment.");
|
||||
sWhatsThis = "Sketcher_ConstrainHorVer";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Constraint_HorVer";
|
||||
sAccel = "A";
|
||||
eType = ForEdit;
|
||||
|
||||
allowedSelSequences = { {SelEdge}, {SelVertex, SelVertexOrRoot}, {SelRoot, SelVertex} };
|
||||
}
|
||||
|
||||
void CmdSketcherConstrainHorVer::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
horVerActivated(this, "HorVer");
|
||||
}
|
||||
|
||||
void CmdSketcherConstrainHorVer::applyConstraint(std::vector<SelIdPair>& selSeq, int seqIndex)
|
||||
{
|
||||
horVerApplyConstraint(this, "HorVer", selSeq, seqIndex);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -2630,255 +2971,12 @@ CmdSketcherConstrainHorizontal::CmdSketcherConstrainHorizontal()
|
||||
void CmdSketcherConstrainHorizontal::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1
|
||||
|| !selection[0].isObjectTypeOf(Sketcher::SketchObject::getClassTypeId())) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool constraintMode = hGrp->GetBool("ContinuousConstraintMode", true);
|
||||
|
||||
if (constraintMode) {
|
||||
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerGenConstraint(this));
|
||||
getSelection().clearSelection();
|
||||
}
|
||||
else {
|
||||
Gui::TranslatedUserWarning(getActiveGuiDocument(),
|
||||
QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select an edge from the sketch."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string>& SubNames = selection[0].getSubNames();
|
||||
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
std::vector<int> edgegeoids;
|
||||
std::vector<int> pointgeoids;
|
||||
std::vector<Sketcher::PointPos> pointpos;
|
||||
|
||||
int fixedpoints = 0;
|
||||
// go through the selected subelements
|
||||
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end();
|
||||
++it) {
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
getIdsFromName((*it), Obj, GeoId, PosId);
|
||||
|
||||
if (isEdge(GeoId, PosId)) {// it is an edge
|
||||
const Part::Geometry* geo = Obj->getGeometry(GeoId);
|
||||
|
||||
if (! isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the edge already has a Horizontal/Vertical/Block constraint
|
||||
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin();
|
||||
it != vals.end();
|
||||
++it) {
|
||||
if ((*it)->Type == Sketcher::Horizontal && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Double constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
if ((*it)->Type == Sketcher::Vertical && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a vertical constraint!"));
|
||||
return;
|
||||
}
|
||||
// check if the edge already has a Block constraint
|
||||
if ((*it)->Type == Sketcher::Block && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a Block constraint!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
edgegeoids.push_back(GeoId);
|
||||
}
|
||||
else if (isVertex(GeoId, PosId)) {
|
||||
// can be a point, a construction point, an external point or root
|
||||
|
||||
if (isPointOrSegmentFixed(Obj, GeoId)) {
|
||||
fixedpoints++;
|
||||
}
|
||||
|
||||
pointgeoids.push_back(GeoId);
|
||||
pointpos.push_back(PosId);
|
||||
}
|
||||
}
|
||||
|
||||
if (edgegeoids.empty() && pointgeoids.empty()) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected item(s) can't accept a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is at least one edge selected, ignore the point alignment functionality
|
||||
if (!edgegeoids.empty()) {
|
||||
// undo command open
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add horizontal constraint"));
|
||||
for (std::vector<int>::iterator it = edgegeoids.begin(); it != edgegeoids.end(); it++) {
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Horizontal',%d))",
|
||||
*it);
|
||||
}
|
||||
}
|
||||
else if (fixedpoints <= 1) {// pointgeoids
|
||||
// undo command open
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add horizontal alignment"));
|
||||
std::vector<int>::iterator it;
|
||||
std::vector<Sketcher::PointPos>::iterator itp;
|
||||
for (it = pointgeoids.begin(), itp = pointpos.begin();
|
||||
it != std::prev(pointgeoids.end()) && itp != std::prev(pointpos.end());
|
||||
it++, itp++) {
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Horizontal',%d,%d,%d,%d))",
|
||||
*it,
|
||||
static_cast<int>(*itp),
|
||||
*std::next(it),
|
||||
static_cast<int>(*std::next(itp)));
|
||||
}
|
||||
}
|
||||
else {// vertex mode, fixedpoints > 1
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("There are more than one fixed points selected. "
|
||||
"Select a maximum of one fixed point!"));
|
||||
return;
|
||||
}
|
||||
// finish the transaction and update
|
||||
commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
// clear the selection (convenience)
|
||||
getSelection().clearSelection();
|
||||
horVerActivated(this, "Horizontal");
|
||||
}
|
||||
|
||||
void CmdSketcherConstrainHorizontal::applyConstraint(std::vector<SelIdPair>& selSeq, int seqIndex)
|
||||
{
|
||||
SketcherGui::ViewProviderSketch* sketchgui =
|
||||
static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
|
||||
Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
|
||||
|
||||
switch (seqIndex) {
|
||||
case 0:// {Edge}
|
||||
{
|
||||
// create the constraint
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
int CrvId = selSeq.front().GeoId;
|
||||
if (CrvId != -1) {
|
||||
const Part::Geometry* geo = Obj->getGeometry(CrvId);
|
||||
|
||||
if (! isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the edge already has a Horizontal/Vertical/Block constraint
|
||||
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin();
|
||||
it != vals.end();
|
||||
++it) {
|
||||
if ((*it)->Type == Sketcher::Horizontal && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Double constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
if ((*it)->Type == Sketcher::Vertical && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a vertical constraint!"));
|
||||
return;
|
||||
}
|
||||
// check if the edge already has a Block constraint
|
||||
if ((*it)->Type == Sketcher::Block && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a Block constraint!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// undo command open
|
||||
Gui::Command::openCommand(
|
||||
QT_TRANSLATE_NOOP("Command", "Add horizontal constraint"));
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Horizontal',%d))",
|
||||
CrvId);
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:// {SelVertex, SelVertexOrRoot}
|
||||
case 2:// {SelRoot, SelVertex}
|
||||
{
|
||||
int GeoId1, GeoId2;
|
||||
Sketcher::PointPos PosId1, PosId2;
|
||||
GeoId1 = selSeq.at(0).GeoId;
|
||||
GeoId2 = selSeq.at(1).GeoId;
|
||||
PosId1 = selSeq.at(0).PosId;
|
||||
PosId2 = selSeq.at(1).PosId;
|
||||
|
||||
if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)) {
|
||||
showNoConstraintBetweenFixedGeometry(Obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// undo command open
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add horizontal alignment"));
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Horizontal',%d,%d,%d,%d))",
|
||||
GeoId1,
|
||||
static_cast<int>(PosId1),
|
||||
GeoId2,
|
||||
static_cast<int>(PosId2));
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
horVerApplyConstraint(this, "Horizontal", selSeq, seqIndex);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
@@ -2918,253 +3016,12 @@ CmdSketcherConstrainVertical::CmdSketcherConstrainVertical()
|
||||
void CmdSketcherConstrainVertical::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1
|
||||
|| !selection[0].isObjectTypeOf(Sketcher::SketchObject::getClassTypeId())) {
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool constraintMode = hGrp->GetBool("ContinuousConstraintMode", true);
|
||||
|
||||
if (constraintMode) {
|
||||
ActivateHandler(getActiveGuiDocument(), new DrawSketchHandlerGenConstraint(this));
|
||||
getSelection().clearSelection();
|
||||
}
|
||||
else {
|
||||
Gui::TranslatedUserWarning(getActiveGuiDocument(),
|
||||
QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select an edge from the sketch."));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string>& SubNames = selection[0].getSubNames();
|
||||
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
std::vector<int> edgegeoids;
|
||||
std::vector<int> pointgeoids;
|
||||
std::vector<Sketcher::PointPos> pointpos;
|
||||
|
||||
int fixedpoints = 0;
|
||||
// go through the selected subelements
|
||||
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end();
|
||||
++it) {
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
getIdsFromName((*it), Obj, GeoId, PosId);
|
||||
|
||||
if (isEdge(GeoId, PosId)) {// it is an edge
|
||||
const Part::Geometry* geo = Obj->getGeometry(GeoId);
|
||||
|
||||
if (! isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the edge already has a Horizontal/Vertical/Block constraint
|
||||
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin();
|
||||
it != vals.end();
|
||||
++it) {
|
||||
if ((*it)->Type == Sketcher::Vertical && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Double constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
if ((*it)->Type == Sketcher::Horizontal && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
// check if the edge already has a Block constraint
|
||||
if ((*it)->Type == Sketcher::Block && (*it)->First == GeoId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a Block constraint!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
edgegeoids.push_back(GeoId);
|
||||
}
|
||||
else if (isVertex(GeoId, PosId)) {
|
||||
// can be a point, a construction point, an external point, root or a blocked geometry
|
||||
if (isPointOrSegmentFixed(Obj, GeoId)) {
|
||||
fixedpoints++;
|
||||
}
|
||||
|
||||
pointgeoids.push_back(GeoId);
|
||||
pointpos.push_back(PosId);
|
||||
}
|
||||
}
|
||||
|
||||
if (edgegeoids.empty() && pointgeoids.empty()) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected item(s) can't accept a vertical constraint!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is at least one edge selected, ignore the point alignment functionality
|
||||
if (!edgegeoids.empty()) {
|
||||
// undo command open
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add vertical constraint"));
|
||||
for (std::vector<int>::iterator it = edgegeoids.begin(); it != edgegeoids.end(); it++) {
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Vertical',%d))",
|
||||
*it);
|
||||
}
|
||||
}
|
||||
else if (fixedpoints <= 1) {// vertex mode, maximum one fixed point
|
||||
// undo command open
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add vertical alignment"));
|
||||
std::vector<int>::iterator it;
|
||||
std::vector<Sketcher::PointPos>::iterator itp;
|
||||
for (it = pointgeoids.begin(), itp = pointpos.begin();
|
||||
it != std::prev(pointgeoids.end()) && itp != std::prev(pointpos.end());
|
||||
it++, itp++) {
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Vertical',%d,%d,%d,%d))",
|
||||
*it,
|
||||
static_cast<int>(*itp),
|
||||
*std::next(it),
|
||||
static_cast<int>(*std::next(itp)));
|
||||
}
|
||||
}
|
||||
else {// vertex mode, fixedpoints > 1
|
||||
Gui::TranslatedUserWarning(Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("There are more than one fixed points selected. "
|
||||
"Select a maximum of one fixed point!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// finish the transaction and update
|
||||
commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
// clear the selection (convenience)
|
||||
getSelection().clearSelection();
|
||||
horVerActivated(this, "Vertical");
|
||||
}
|
||||
|
||||
void CmdSketcherConstrainVertical::applyConstraint(std::vector<SelIdPair>& selSeq, int seqIndex)
|
||||
{
|
||||
SketcherGui::ViewProviderSketch* sketchgui =
|
||||
static_cast<SketcherGui::ViewProviderSketch*>(getActiveGuiDocument()->getInEdit());
|
||||
Sketcher::SketchObject* Obj = sketchgui->getSketchObject();
|
||||
|
||||
switch (seqIndex) {
|
||||
case 0:// {Edge}
|
||||
{
|
||||
// create the constraint
|
||||
const std::vector<Sketcher::Constraint*>& vals = Obj->Constraints.getValues();
|
||||
|
||||
int CrvId = selSeq.front().GeoId;
|
||||
if (CrvId != -1) {
|
||||
const Part::Geometry* geo = Obj->getGeometry(CrvId);
|
||||
|
||||
if (! isLineSegment(*geo)) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge is not a line segment."));
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the edge already has a Horizontal or Vertical constraint
|
||||
for (std::vector<Sketcher::Constraint*>::const_iterator it = vals.begin();
|
||||
it != vals.end();
|
||||
++it) {
|
||||
if ((*it)->Type == Sketcher::Horizontal && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a horizontal constraint!"));
|
||||
return;
|
||||
}
|
||||
if ((*it)->Type == Sketcher::Vertical && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Double constraint"),
|
||||
QObject::tr("The selected edge already has a vertical constraint!"));
|
||||
return;
|
||||
}
|
||||
// check if the edge already has a Block constraint
|
||||
if ((*it)->Type == Sketcher::Block && (*it)->First == CrvId
|
||||
&& (*it)->FirstPos == Sketcher::PointPos::none) {
|
||||
Gui::TranslatedUserWarning(
|
||||
Obj,
|
||||
QObject::tr("Impossible constraint"),
|
||||
QObject::tr("The selected edge already has a Block constraint!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// undo command open
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add vertical constraint"));
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Vertical',%d))",
|
||||
CrvId);
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
tryAutoRecompute(Obj);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:// {SelVertex, SelVertexOrRoot}
|
||||
case 2:// {SelRoot, SelVertex}
|
||||
{
|
||||
int GeoId1, GeoId2;
|
||||
Sketcher::PointPos PosId1, PosId2;
|
||||
GeoId1 = selSeq.at(0).GeoId;
|
||||
GeoId2 = selSeq.at(1).GeoId;
|
||||
PosId1 = selSeq.at(0).PosId;
|
||||
PosId2 = selSeq.at(1).PosId;
|
||||
|
||||
if (areBothPointsOrSegmentsFixed(Obj, GeoId1, GeoId2)) {
|
||||
showNoConstraintBetweenFixedGeometry(Obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// undo command open
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Add horizontal alignment"));
|
||||
// issue the actual commands to create the constraint
|
||||
Gui::cmdAppObjectArgs(sketchgui->getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Vertical',%d,%d,%d,%d))",
|
||||
GeoId1,
|
||||
static_cast<int>(PosId1),
|
||||
GeoId2,
|
||||
static_cast<int>(PosId2));
|
||||
// finish the transaction and update
|
||||
Gui::Command::commitCommand();
|
||||
|
||||
tryAutoRecompute(Obj);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
horVerApplyConstraint(this, "Vertical", selSeq, seqIndex);
|
||||
}
|
||||
|
||||
// ======================================================================================
|
||||
@@ -10069,6 +9926,8 @@ void CreateSketcherCommandsConstraints()
|
||||
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainHorizontal());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainVertical());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainHorVer());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCompHorizontalVertical());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainLock());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainBlock());
|
||||
rcCmdMgr.addCommand(new CmdSketcherConstrainCoincident());
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<file>icons/constraints/Constraint_Horizontal.svg</file>
|
||||
<file>icons/constraints/Constraint_HorizontalDistance.svg</file>
|
||||
<file>icons/constraints/Constraint_HorizontalDistance_Driven.svg</file>
|
||||
<file>icons/constraints/Constraint_HorVer.svg</file>
|
||||
<file>icons/constraints/Constraint_InternalAlignment.svg</file>
|
||||
<file>icons/constraints/Constraint_InternalAlignment_Ellipse_Focus1.svg</file>
|
||||
<file>icons/constraints/Constraint_InternalAlignment_Ellipse_Focus2.svg</file>
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2816"
|
||||
version="1.1"
|
||||
sodipodi:docname="Constraint_HorVer.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview26"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
objecttolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
guidetolerance="10.0"
|
||||
inkscape:pageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="8.3195532"
|
||||
inkscape:cx="35.518734"
|
||||
inkscape:cy="1.262087"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="1571"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2816" />
|
||||
<defs
|
||||
id="defs2818">
|
||||
<linearGradient
|
||||
id="linearGradient3602">
|
||||
<stop
|
||||
style="stop-color:#ff2600;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3604" />
|
||||
<stop
|
||||
style="stop-color:#ff5f00;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3606" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3602"
|
||||
id="linearGradient3608"
|
||||
x1="3.909091"
|
||||
y1="14.363636"
|
||||
x2="24.818181"
|
||||
y2="14.363636"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3602-7"
|
||||
id="linearGradient3608-5"
|
||||
x1="3.909091"
|
||||
y1="14.363636"
|
||||
x2="24.81818"
|
||||
y2="14.363636"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3602-7">
|
||||
<stop
|
||||
style="stop-color:#c51900;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3604-1" />
|
||||
<stop
|
||||
style="stop-color:#ff5f00;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3606-3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3602-5"
|
||||
id="linearGradient3608-1"
|
||||
x1="3.909091"
|
||||
y1="14.363636"
|
||||
x2="24.81818"
|
||||
y2="14.363636"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3602-5">
|
||||
<stop
|
||||
style="stop-color:#c51900;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3604-9" />
|
||||
<stop
|
||||
style="stop-color:#ff5f00;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3606-9" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="14.363636"
|
||||
x2="24.81818"
|
||||
y1="14.363636"
|
||||
x1="3.909091"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3686"
|
||||
xlink:href="#linearGradient3602-5" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient3602-58"
|
||||
id="linearGradient3608-8"
|
||||
x1="3.909091"
|
||||
y1="14.363636"
|
||||
x2="24.81818"
|
||||
y2="14.363636"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3602-58">
|
||||
<stop
|
||||
style="stop-color:#c51900;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3604-2" />
|
||||
<stop
|
||||
style="stop-color:#ff5f00;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3606-2" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
y2="14.363636"
|
||||
x2="24.81818"
|
||||
y1="14.363636"
|
||||
x1="3.909091"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient3726"
|
||||
xlink:href="#linearGradient3602-58" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata2821">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[wmayer]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:date>2011-10-10</dc:date>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Sketcher/Gui/Resources/icons/Constraint_Horizontal.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1-75">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:#280000;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect3770-7"
|
||||
width="57.992863"
|
||||
height="9.9582825"
|
||||
x="3.0265496"
|
||||
y="26.997831"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(0.99999974,7.1938714e-4,-7.1838503e-4,0.99999974,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#ef2929;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect3770-3-2"
|
||||
width="53.993343"
|
||||
height="5.9749722"
|
||||
x="5.0389857"
|
||||
y="28.997681"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(0.99999989,4.636052e-4,-0.00111473,0.99999938,0,0)" />
|
||||
</g>
|
||||
<g
|
||||
id="layer1-75-9"
|
||||
transform="rotate(-90,31.999999,32.000001)">
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:#280000;stroke-width:2;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect3770-7-3"
|
||||
width="57.992863"
|
||||
height="9.9582825"
|
||||
x="3.0265496"
|
||||
y="26.997831"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(0.99999974,7.1938714e-4,-7.1838503e-4,0.99999974,0,0)" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#ef2929;stroke-width:2;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
id="rect3770-3-2-2"
|
||||
width="53.993343"
|
||||
height="5.9749722"
|
||||
x="5.0389857"
|
||||
y="28.997681"
|
||||
rx="0"
|
||||
ry="0"
|
||||
transform="matrix(0.99999989,4.636052e-4,-0.00111473,0.99999938,0,0)" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
@@ -211,6 +211,12 @@ inline Base::Vector3d toVector3d(const Base::Vector2d& vector2d)
|
||||
return Base::Vector3d(vector2d.x, vector2d.y, 0.);
|
||||
}
|
||||
|
||||
/// converts a 3D vector in the XY plane into a 2D vector
|
||||
inline Base::Vector2d toVector2d(const Base::Vector3d& vector3d)
|
||||
{
|
||||
return Base::Vector2d(vector3d.x, vector3d.y);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
auto toPointerVector(const std::vector<std::unique_ptr<T>>& vector)
|
||||
|
||||
@@ -432,6 +432,7 @@ inline void SketcherAddWorkbenchConstraints<Gui::MenuItem>(Gui::MenuItem& cons)
|
||||
<< "Sketcher_ConstrainPointOnObject"
|
||||
<< "Sketcher_ConstrainVertical"
|
||||
<< "Sketcher_ConstrainHorizontal"
|
||||
<< "Sketcher_ConstrainHorVer"
|
||||
<< "Sketcher_ConstrainParallel"
|
||||
<< "Sketcher_ConstrainPerpendicular"
|
||||
<< "Sketcher_ConstrainTangent"
|
||||
@@ -462,8 +463,7 @@ inline void SketcherAddWorkbenchConstraints<Gui::ToolBarItem>(Gui::ToolBarItem&
|
||||
|
||||
cons << "Sketcher_ConstrainCoincident"
|
||||
<< "Sketcher_ConstrainPointOnObject"
|
||||
<< "Sketcher_ConstrainVertical"
|
||||
<< "Sketcher_ConstrainHorizontal"
|
||||
<< "Sketcher_CompHorVer"
|
||||
<< "Sketcher_ConstrainParallel"
|
||||
<< "Sketcher_ConstrainPerpendicular"
|
||||
<< "Sketcher_ConstrainTangent"
|
||||
|
||||
Reference in New Issue
Block a user