Merge pull request #11537 from Ondsel-Development/copy_paste_2023
[Sketcher] Add copy/cut/paste sketcher commands
This commit is contained in:
@@ -59,11 +59,11 @@ std::string PythonConverter::convert(const Part::Geometry* geo, Mode mode)
|
||||
return command;
|
||||
}
|
||||
|
||||
std::string PythonConverter::convert(const Sketcher::Constraint* constraint)
|
||||
std::string PythonConverter::convert(const Sketcher::Constraint* constraint, GeoIdMode geoIdMode)
|
||||
{
|
||||
// addConstraint(Sketcher.Constraint('Distance',%d,%f))
|
||||
std::string command;
|
||||
auto cg = process(constraint);
|
||||
auto cg = process(constraint, geoIdMode);
|
||||
|
||||
command = boost::str(boost::format("addConstraint(%s)\n") % cg);
|
||||
|
||||
@@ -85,13 +85,13 @@ std::string PythonConverter::convert(const std::string& doc,
|
||||
if (ngeos > 0) {
|
||||
if (construction) {
|
||||
command = boost::str(
|
||||
boost::format("constrGeoList = []\n%s\n%s.addGeometry(constrGeoList,%s)\ndel "
|
||||
"constrGeoList")
|
||||
boost::format("constrGeoList = []\n%s%s.addGeometry(constrGeoList,%s)\n"
|
||||
"del constrGeoList\n")
|
||||
% geolist % doc % "True");
|
||||
}
|
||||
else {
|
||||
command = boost::str(
|
||||
boost::format("geoList = []\n%s\n%s.addGeometry(geoList,%s)\ndel geoList")
|
||||
boost::format("geoList = []\n%s%s.addGeometry(geoList,%s)\ndel geoList\n")
|
||||
% geolist % doc % "False");
|
||||
}
|
||||
}
|
||||
@@ -134,10 +134,10 @@ std::string PythonConverter::convert(const std::string& doc,
|
||||
|
||||
if (sg.construction) {
|
||||
geolist =
|
||||
boost::str(boost::format("%s\nconstrGeoList.append(%s)\n") % geolist % sg.creation);
|
||||
boost::str(boost::format("%sconstrGeoList.append(%s)\n") % geolist % sg.creation);
|
||||
}
|
||||
else {
|
||||
geolist = boost::str(boost::format("%s\ngeoList.append(%s)\n") % geolist % sg.creation);
|
||||
geolist = boost::str(boost::format("%sgeoList.append(%s)\n") % geolist % sg.creation);
|
||||
}
|
||||
|
||||
ngeos++;
|
||||
@@ -165,7 +165,8 @@ std::string PythonConverter::convert(const std::string& doc,
|
||||
}
|
||||
|
||||
std::string PythonConverter::convert(const std::string& doc,
|
||||
const std::vector<Sketcher::Constraint*>& constraints)
|
||||
const std::vector<Sketcher::Constraint*>& constraints,
|
||||
GeoIdMode geoIdMode)
|
||||
{
|
||||
if (constraints.size() == 1) {
|
||||
auto cg = convert(constraints[0]);
|
||||
@@ -176,7 +177,7 @@ std::string PythonConverter::convert(const std::string& doc,
|
||||
std::string constraintlist = "constraintList = []";
|
||||
|
||||
for (auto constraint : constraints) {
|
||||
auto cg = process(constraint);
|
||||
auto cg = process(constraint, geoIdMode);
|
||||
|
||||
constraintlist =
|
||||
boost::str(boost::format("%s\nconstraintList.append(%s)") % constraintlist % cg);
|
||||
@@ -200,7 +201,8 @@ PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry* g
|
||||
auto sgeo = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation = boost::str(
|
||||
boost::format("Part.LineSegment(App.Vector(%f,%f,%f),App.Vector(%f,%f,%f))")
|
||||
boost::format(
|
||||
"Part.LineSegment(App.Vector(%f, %f, %f),App.Vector(%f, %f, %f))")
|
||||
% sgeo->getStartPoint().x % sgeo->getStartPoint().y % sgeo->getStartPoint().z
|
||||
% sgeo->getEndPoint().x % sgeo->getEndPoint().y % sgeo->getEndPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
@@ -225,7 +227,7 @@ PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry* g
|
||||
auto sgeo = static_cast<const Part::GeomPoint*>(geo);
|
||||
SingleGeometry sg;
|
||||
sg.creation =
|
||||
boost::str(boost::format("Part.Point(App.Vector(%f,%f,%f))")
|
||||
boost::str(boost::format("Part.Point(App.Vector(%f, %f, %f))")
|
||||
% sgeo->getPoint().x % sgeo->getPoint().y % sgeo->getPoint().z);
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
@@ -309,10 +311,10 @@ PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry* g
|
||||
controlpoints.append(1, ']');
|
||||
|
||||
SingleGeometry sg;
|
||||
sg.creation =
|
||||
boost::str(boost::format("Part.BSplineCurve (%s,None,None,%s,%d,None,False)")
|
||||
% controlpoints.c_str() % (bSpline->isPeriodic() ? "True" : "False")
|
||||
% bSpline->getDegree());
|
||||
sg.creation = boost::str(
|
||||
boost::format("Part.BSplineCurve (%s, None, None, %s, %d, None, False)")
|
||||
% controlpoints.c_str() % (bSpline->isPeriodic() ? "True" : "False")
|
||||
% bSpline->getDegree());
|
||||
sg.construction = Sketcher::GeometryFacade::getConstruction(geo);
|
||||
return sg;
|
||||
}},
|
||||
@@ -342,128 +344,159 @@ PythonConverter::SingleGeometry PythonConverter::process(const Part::Geometry* g
|
||||
return creator(geo);
|
||||
}
|
||||
|
||||
std::string PythonConverter::process(const Sketcher::Constraint* constraint)
|
||||
std::string PythonConverter::process(const Sketcher::Constraint* constraint, GeoIdMode geoIdMode)
|
||||
{
|
||||
static std::map<const Sketcher::ConstraintType,
|
||||
std::function<std::string(const Sketcher::Constraint*)>>
|
||||
bool addLastIdVar = geoIdMode == GeoIdMode::AddLastGeoIdToGeoIds;
|
||||
std::string geoId1 = (addLastIdVar ? "lastGeoId + " : "") + std::to_string(constraint->First);
|
||||
std::string geoId2 = (addLastIdVar ? "lastGeoId + " : "") + std::to_string(constraint->Second);
|
||||
std::string geoId3 = (addLastIdVar ? "lastGeoId + " : "") + std::to_string(constraint->Third);
|
||||
|
||||
static std::map<
|
||||
const Sketcher::ConstraintType,
|
||||
std::function<
|
||||
std::string(const Sketcher::Constraint*, std::string&, std::string&, std::string&)>>
|
||||
converterMap = {
|
||||
{Sketcher::Coincident,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Coincident', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Coincident', %s, %i, %s, %i)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}},
|
||||
{Sketcher::Horizontal,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Horizontal', %i)")
|
||||
% constr->First);
|
||||
return boost::str(boost::format("Sketcher.Constraint('Horizontal', %s)")
|
||||
% geoId1);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Horizontal', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Horizontal', %s, %i, %s, %i)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Vertical,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Vertical', %i)")
|
||||
% constr->First);
|
||||
return boost::str(boost::format("Sketcher.Constraint('Vertical', %s)")
|
||||
% geoId1);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Vertical', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Vertical', %s, %i, %s, %i)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Block,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Block', %i)")
|
||||
% constr->First);
|
||||
[]([[maybe_unused]] const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
[[maybe_unused]] std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Block', %s)") % geoId1);
|
||||
}},
|
||||
{Sketcher::Tangent,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %s, %s)")
|
||||
% geoId1 % geoId2);
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->Second);
|
||||
return boost::str(boost::format("Sketcher.Constraint('Tangent', %s, %i, %s)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Tangent', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Tangent', %s, %i, %s, %i)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Parallel,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Parallel', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
[]([[maybe_unused]] const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Parallel', %s, %s)") % geoId1
|
||||
% geoId2);
|
||||
}},
|
||||
{Sketcher::Perpendicular,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[]([[maybe_unused]] const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
return boost::str(boost::format("Sketcher.Constraint('Perpendicular', %s, %s)")
|
||||
% geoId1 % geoId2);
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %s, %i, %s)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Perpendicular', %s, %i, %s, %i)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::Equal,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Equal', %i, %i)")
|
||||
% constr->First % constr->Second);
|
||||
[]([[maybe_unused]] const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Equal', %s, %s)") % geoId1
|
||||
% geoId2);
|
||||
}},
|
||||
{Sketcher::InternalAlignment,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->AlignmentType == EllipseMajorDiameter
|
||||
|| constr->AlignmentType == EllipseMinorDiameter
|
||||
|| constr->AlignmentType == HyperbolaMajor
|
||||
|| constr->AlignmentType == HyperbolaMinor
|
||||
|| constr->AlignmentType == ParabolaFocalAxis) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% constr->Second);
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %s, %s)")
|
||||
% constr->internalAlignmentTypeToString() % geoId1 % geoId2);
|
||||
}
|
||||
else if (constr->AlignmentType == EllipseFocus1
|
||||
|| constr->AlignmentType == EllipseFocus2
|
||||
|| constr->AlignmentType == HyperbolaFocus
|
||||
|| constr->AlignmentType == ParabolaFocus) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% static_cast<int>(constr->FirstPos) % constr->Second);
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %s, %i, %s)")
|
||||
% constr->internalAlignmentTypeToString() % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2);
|
||||
}
|
||||
else if (constr->AlignmentType == BSplineControlPoint) {
|
||||
return boost::str(
|
||||
boost::format(
|
||||
"Sketcher.Constraint('InternalAlignment:%s', %i, %i, %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First
|
||||
% static_cast<int>(constr->FirstPos) % constr->Second
|
||||
"Sketcher.Constraint('InternalAlignment:%s', %s, %i, %s, %i)")
|
||||
% constr->internalAlignmentTypeToString() % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2
|
||||
% constr->InternalAlignmentIndex);
|
||||
}
|
||||
else if (constr->AlignmentType == BSplineKnotPoint) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %i, 1, %i, %i)")
|
||||
% constr->internalAlignmentTypeToString() % constr->First % constr->Second
|
||||
boost::format("Sketcher.Constraint('InternalAlignment:%s', %s, 1, %s, %i)")
|
||||
% constr->internalAlignmentTypeToString() % geoId1 % geoId2
|
||||
% constr->InternalAlignmentIndex);
|
||||
}
|
||||
|
||||
@@ -471,124 +504,160 @@ std::string PythonConverter::process(const Sketcher::Constraint* constraint)
|
||||
"PythonConverter: Constraint Alignment Type not supported")
|
||||
}},
|
||||
{Sketcher::Distance,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %s, %f)")
|
||||
% geoId1 % constr->getValue());
|
||||
}
|
||||
else if (constr->FirstPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %i, %i, %f)")
|
||||
% constr->First % constr->Second % constr->getValue());
|
||||
return boost::str(boost::format("Sketcher.Constraint('Distance', %s, %s, %f)")
|
||||
% geoId1 % geoId2 % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% constr->getValue());
|
||||
boost::format("Sketcher.Constraint('Distance', %s, %i, %s, %f)") % geoId1
|
||||
% static_cast<int>(constr->FirstPos) % geoId2 % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Distance', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('Distance', %s, %i, %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::Angle,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %s, %f)")
|
||||
% geoId1 % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %i, %i, %f)")
|
||||
% constr->First % constr->Second % constr->getValue());
|
||||
else if (constr->Third == GeoEnum::GeoUndef) {
|
||||
if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Angle', %s, %s, %f)")
|
||||
% geoId1 % geoId2 % constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Angle', %s, %i, %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Angle', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
boost::format("Sketcher.Constraint('AngleViaPoint', %s, %s, %s, %i, %f)")
|
||||
% geoId1 % geoId2 % geoId3 % static_cast<int>(constr->ThirdPos)
|
||||
% constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::DistanceX,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %s, %f)")
|
||||
% geoId1 % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceX', %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos)
|
||||
% constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('DistanceX', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('DistanceX', %s, %i, %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::DistanceY,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
if (constr->Second == GeoEnum::GeoUndef) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %s, %f)")
|
||||
% geoId1 % constr->getValue());
|
||||
}
|
||||
else if (constr->SecondPos == Sketcher::PointPos::none) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
return boost::str(boost::format("Sketcher.Constraint('DistanceY', %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos)
|
||||
% constr->getValue());
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('DistanceY', %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
boost::format("Sketcher.Constraint('DistanceY', %s, %i, %s, %i, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % constr->getValue());
|
||||
}
|
||||
}},
|
||||
{Sketcher::Radius,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Radius', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
[[maybe_unused]] std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Radius', %s, %f)") % geoId1
|
||||
% constr->getValue());
|
||||
}},
|
||||
{Sketcher::Diameter,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Diameter', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
[[maybe_unused]] std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Diameter', %s, %f)") % geoId1
|
||||
% constr->getValue());
|
||||
}},
|
||||
{Sketcher::Weight,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Weight', %i, %f)")
|
||||
% constr->First % constr->getValue());
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
[[maybe_unused]] std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('Weight', %s, %f)") % geoId1
|
||||
% constr->getValue());
|
||||
}},
|
||||
{Sketcher::PointOnObject,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('PointOnObject', %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos)
|
||||
% constr->Second);
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
[[maybe_unused]] std::string& geoId3) {
|
||||
return boost::str(boost::format("Sketcher.Constraint('PointOnObject', %s, %i, %s)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2);
|
||||
}},
|
||||
{Sketcher::Symmetric,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
std::string& geoId3) {
|
||||
if (constr->ThirdPos == Sketcher::PointPos::none) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third);
|
||||
boost::format("Sketcher.Constraint('Symmetric', %s, %i, %s, %i, %s)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % geoId3);
|
||||
}
|
||||
else {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('Symmetric', %i, %i, %i, %i, %i, %i)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third
|
||||
boost::format("Sketcher.Constraint('Symmetric', %s, %i, %s, %i, %s, %i)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % geoId3
|
||||
% static_cast<int>(constr->ThirdPos));
|
||||
}
|
||||
}},
|
||||
{Sketcher::SnellsLaw,
|
||||
[](const Sketcher::Constraint* constr) {
|
||||
[](const Sketcher::Constraint* constr,
|
||||
std::string& geoId1,
|
||||
std::string& geoId2,
|
||||
std::string& geoId3) {
|
||||
return boost::str(
|
||||
boost::format("Sketcher.Constraint('SnellsLaw', %i, %i, %i, %i, %i, %f)")
|
||||
% constr->First % static_cast<int>(constr->FirstPos) % constr->Second
|
||||
% static_cast<int>(constr->SecondPos) % constr->Third % constr->getValue());
|
||||
boost::format("Sketcher.Constraint('SnellsLaw', %s, %i, %s, %i, %s, %f)")
|
||||
% geoId1 % static_cast<int>(constr->FirstPos) % geoId2
|
||||
% static_cast<int>(constr->SecondPos) % geoId3 % constr->getValue());
|
||||
}},
|
||||
};
|
||||
|
||||
@@ -600,7 +669,7 @@ std::string PythonConverter::process(const Sketcher::Constraint* constraint)
|
||||
|
||||
auto creator = result->second;
|
||||
|
||||
return creator(constraint);
|
||||
return creator(constraint, geoId1, geoId2, geoId3);
|
||||
}
|
||||
|
||||
std::vector<std::string> PythonConverter::multiLine(std::string&& singlestring)
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#ifndef SKETCHER_PythonConverter_H
|
||||
#define SKETCHER_PythonConverter_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Mod/Sketcher/SketcherGlobal.h>
|
||||
|
||||
namespace Part
|
||||
@@ -57,7 +60,13 @@ public:
|
||||
OmitInternalGeometry
|
||||
};
|
||||
|
||||
explicit PythonConverter() = delete;
|
||||
enum class GeoIdMode
|
||||
{
|
||||
DoNotChangeGeoIds,
|
||||
AddLastGeoIdToGeoIds,
|
||||
};
|
||||
|
||||
PythonConverter() = delete;
|
||||
~PythonConverter() = delete;
|
||||
|
||||
/// Convert a geometry into the string representing the command creating it
|
||||
@@ -68,17 +77,20 @@ public:
|
||||
const std::vector<Part::Geometry*>& geos,
|
||||
Mode mode = Mode::CreateInternalGeometry);
|
||||
|
||||
static std::string convert(const Sketcher::Constraint* constraint);
|
||||
static std::string convert(const Sketcher::Constraint* constraint,
|
||||
GeoIdMode geoIdMode = GeoIdMode::DoNotChangeGeoIds);
|
||||
|
||||
static std::string convert(const std::string& doc,
|
||||
const std::vector<Sketcher::Constraint*>& constraints);
|
||||
const std::vector<Sketcher::Constraint*>& constraints,
|
||||
GeoIdMode geoIdMode = GeoIdMode::DoNotChangeGeoIds);
|
||||
|
||||
static std::vector<std::string> multiLine(std::string&& singlestring);
|
||||
|
||||
private:
|
||||
static SingleGeometry process(const Part::Geometry* geo);
|
||||
|
||||
static std::string process(const Sketcher::Constraint* constraint);
|
||||
static std::string process(const Sketcher::Constraint* constraint,
|
||||
GeoIdMode geoIdMode = GeoIdMode::DoNotChangeGeoIds);
|
||||
};
|
||||
|
||||
} // namespace Sketcher
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <Inventor/SbString.h>
|
||||
@@ -33,6 +34,8 @@
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Gui/Action.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
@@ -42,6 +45,7 @@
|
||||
#include <Gui/Notifications.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/SelectionObject.h>
|
||||
#include <Mod/Sketcher/App/PythonConverter.h>
|
||||
#include <Mod/Sketcher/App/SketchObject.h>
|
||||
#include <Mod/Sketcher/App/SolverGeometryExtension.h>
|
||||
|
||||
@@ -140,6 +144,185 @@ Sketcher::SketchObject* getSketchObject()
|
||||
|
||||
// ================================================================================
|
||||
|
||||
// Copy
|
||||
|
||||
bool copySelectionToClipboard(Sketcher::SketchObject* obj) {
|
||||
std::vector<int> listOfGeoId = getListOfSelectedGeoIds(true);
|
||||
if (listOfGeoId.empty()) { return false; }
|
||||
sort(listOfGeoId.begin(), listOfGeoId.end());
|
||||
|
||||
//Export selected geometries as a formatted string.
|
||||
std::vector<Part::Geometry*> shapeGeometry;
|
||||
for (auto geoId : listOfGeoId) {
|
||||
Part::Geometry* geoNew = obj->getGeometry(geoId)->copy();
|
||||
shapeGeometry.push_back(geoNew);
|
||||
}
|
||||
std::string geosAsStr = Sketcher::PythonConverter::convert(
|
||||
"objectStr",
|
||||
shapeGeometry,
|
||||
Sketcher::PythonConverter::Mode::OmitInternalGeometry);
|
||||
|
||||
// Export constraints of selected geos.
|
||||
std::vector<Sketcher::Constraint*> shapeConstraints;
|
||||
for (auto constr : obj->Constraints.getValues()) {
|
||||
|
||||
auto isSelectedGeoOrAxis = [](const std::vector<int>& vec, int value) {
|
||||
return (std::find(vec.begin(), vec.end(), value) != vec.end())
|
||||
|| value == GeoEnum::GeoUndef || value == GeoEnum::RtPnt
|
||||
|| value == GeoEnum::VAxis || value == GeoEnum::HAxis;
|
||||
};
|
||||
|
||||
if (!isSelectedGeoOrAxis(listOfGeoId, constr->First)
|
||||
|| !isSelectedGeoOrAxis(listOfGeoId, constr->Second)
|
||||
|| !isSelectedGeoOrAxis(listOfGeoId, constr->Third)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Constraint* temp = constr->copy();
|
||||
for (size_t j = 0; j < listOfGeoId.size(); j++) {
|
||||
if (temp->First == listOfGeoId[j]) {
|
||||
temp->First = j;
|
||||
}
|
||||
if (temp->Second == listOfGeoId[j]) {
|
||||
temp->Second = j;
|
||||
}
|
||||
if (temp->Third == listOfGeoId[j]) {
|
||||
temp->Third = j;
|
||||
}
|
||||
}
|
||||
shapeConstraints.push_back(temp);
|
||||
}
|
||||
std::string cstrAsStr = Sketcher::PythonConverter::convert("objectStr", shapeConstraints, Sketcher::PythonConverter::GeoIdMode::AddLastGeoIdToGeoIds);
|
||||
|
||||
std::string exportedData = "# Copied from sketcher. From:\n#objectStr = " + Gui::Command::getObjectCmd(obj) + "\n"
|
||||
+ geosAsStr + "\n" + cstrAsStr;
|
||||
|
||||
if (!exportedData.empty()) {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(QString::fromStdString(exportedData));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCopyClipboard)
|
||||
|
||||
CmdSketcherCopyClipboard::CmdSketcherCopyClipboard()
|
||||
: Command("Sketcher_CopyClipboard")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("C&opy in sketcher");
|
||||
sToolTipText = QT_TR_NOOP("Copy selected geometries and constraints to the clipboard");
|
||||
sWhatsThis = "Sketcher_CopyClipboard";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "edit-copy";
|
||||
sAccel = keySequenceToAccel(QKeySequence::Copy);
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCopyClipboard::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
copySelectionToClipboard(getSketchObject());
|
||||
}
|
||||
|
||||
bool CmdSketcherCopyClipboard::isActive()
|
||||
{
|
||||
return isCommandActive(getActiveGuiDocument(), true);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
|
||||
// Cut
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCut)
|
||||
|
||||
CmdSketcherCut::CmdSketcherCut()
|
||||
: Command("Sketcher_Cut")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("C&ut in sketcher");
|
||||
sToolTipText = QT_TR_NOOP("Cut selected geometries and constraints to the clipboard");
|
||||
sWhatsThis = "Sketcher_Cut";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "edit-cut";
|
||||
sAccel = keySequenceToAccel(QKeySequence::Cut);
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCut::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
if (copySelectionToClipboard(getSketchObject())) {
|
||||
|
||||
Gui::Document* doc = getActiveGuiDocument();
|
||||
ReleaseHandler(doc);
|
||||
auto* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Cut in Sketcher"));
|
||||
vp->deleteSelected();
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdSketcherCut::isActive()
|
||||
{
|
||||
return isCommandActive(getActiveGuiDocument(), true);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
|
||||
// Paste
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherPaste)
|
||||
|
||||
CmdSketcherPaste::CmdSketcherPaste()
|
||||
: Command("Sketcher_Paste")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = "Sketcher";
|
||||
sMenuText = QT_TR_NOOP("P&aste in sketcher");
|
||||
sToolTipText = QT_TR_NOOP("Paste selected geometries and constraints from the clipboard");
|
||||
sWhatsThis = "Sketcher_Paste";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "edit-paste";
|
||||
sAccel = keySequenceToAccel(QKeySequence::Paste);
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherPaste::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::Document* doc = getActiveGuiDocument();
|
||||
ReleaseHandler(doc);
|
||||
auto* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
Sketcher::SketchObject* obj = vp->getSketchObject();
|
||||
|
||||
std::string data = QGuiApplication::clipboard()->text().toStdString();
|
||||
if (data.find("# Copied from sketcher.", 0) == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
data = "objectStr = " + Gui::Command::getObjectCmd(obj) +"\n" + data;
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Paste in Sketcher"));
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc, data.c_str());
|
||||
|
||||
obj->solve(true);
|
||||
vp->draw(false, false);
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
bool CmdSketcherPaste::isActive()
|
||||
{
|
||||
return isCommandActive(getActiveGuiDocument(), false);
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
|
||||
// Select Constraints of selected elements
|
||||
DEF_STD_CMD_A(CmdSketcherSelectConstraints)
|
||||
|
||||
@@ -2432,5 +2615,8 @@ void CreateSketcherCommandsConstraintAccel()
|
||||
rcCmdMgr.addCommand(new CmdSketcherDeleteAllGeometry());
|
||||
rcCmdMgr.addCommand(new CmdSketcherDeleteAllConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherRemoveAxesAlignment());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCopyClipboard());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCut());
|
||||
rcCmdMgr.addCommand(new CmdSketcherPaste());
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
@@ -31,12 +31,6 @@
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
// ******************** ViewProvider attorney *********************************************//
|
||||
inline void ViewProviderSketchShortcutListenerAttorney::deleteSelected(ViewProviderSketch& vp)
|
||||
{
|
||||
vp.deleteSelected();
|
||||
};
|
||||
|
||||
// ******************** ShortcutListener *********************************************//
|
||||
ShortcutListener::ShortcutListener(ViewProviderSketch* vp)
|
||||
{
|
||||
@@ -55,7 +49,7 @@ bool ShortcutListener::eventFilter(QObject* obj, QEvent* event)
|
||||
switch (kevent->key()) {
|
||||
case Qt::Key_Delete:
|
||||
kevent->accept();
|
||||
ViewProviderSketchShortcutListenerAttorney::deleteSelected(*pViewProvider);
|
||||
pViewProvider->deleteSelected();
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -31,15 +31,6 @@ namespace SketcherGui
|
||||
|
||||
class ViewProviderSketch;
|
||||
|
||||
class ViewProviderSketchShortcutListenerAttorney
|
||||
{
|
||||
private:
|
||||
static inline void deleteSelected(ViewProviderSketch& vp);
|
||||
|
||||
|
||||
friend class ShortcutListener;
|
||||
};
|
||||
|
||||
class ShortcutListener: public QObject
|
||||
{
|
||||
// Q_OBJECT
|
||||
|
||||
@@ -672,6 +672,7 @@ public:
|
||||
const Gui::View3DInventorViewer* viewer) override;
|
||||
//@}
|
||||
|
||||
void deleteSelected();
|
||||
|
||||
/// Control the overlays appearing on the Tree and reflecting different sketcher states
|
||||
QIcon mergeColorfulOverlayIcons(const QIcon& orig) const override;
|
||||
@@ -702,7 +703,6 @@ public:
|
||||
friend class ViewProviderSketchDrawSketchHandlerAttorney;
|
||||
friend class ViewProviderSketchCoinAttorney;
|
||||
friend class ViewProviderSketchSnapAttorney;
|
||||
friend class ViewProviderSketchShortcutListenerAttorney;
|
||||
//@}
|
||||
protected:
|
||||
/** @name enter/exit edit mode */
|
||||
@@ -867,9 +867,6 @@ private:
|
||||
|
||||
bool isConstraintSelected(int constraintId) const;
|
||||
|
||||
//********* ViewProviderSketchShortcutListenerAttorney ***********//
|
||||
void deleteSelected();
|
||||
|
||||
//********* ViewProviderSketchDrawSketchHandlerAttorney **********//
|
||||
void setConstraintSelectability(bool enabled = true);
|
||||
void setPositionText(const Base::Vector2d& Pos, const SbString& txt);
|
||||
|
||||
@@ -543,7 +543,11 @@ inline void SketcherAddWorkbenchTools<Gui::MenuItem>(Gui::MenuItem& consaccel)
|
||||
<< "Sketcher_RemoveAxesAlignment"
|
||||
<< "Separator"
|
||||
<< "Sketcher_DeleteAllGeometry"
|
||||
<< "Sketcher_DeleteAllConstraints";
|
||||
<< "Sketcher_DeleteAllConstraints"
|
||||
<< "Separator"
|
||||
<< "Sketcher_CopyClipboard"
|
||||
<< "Sketcher_Cut"
|
||||
<< "Sketcher_Paste";
|
||||
}
|
||||
|
||||
template<>
|
||||
|
||||
Reference in New Issue
Block a user