Sketcher: UI Copy Support & 2D Array python command rework
========================================================== - Support for copying geometric elements in the sketcher with Ctrl+C (or using the still missing icon). It will show you the vector of displacement from the "reference point". The reference point can be chosen by the user (although it is not necessary to do it so) by making the point the user wish to be the reference point the last selected element. It conveniently incorporates "autoconstraints", so that you can make this point (the one of the copy) directly coincident with any other point in the sketch. - Python 2D array command modified to lock elements position using construction lines and constraints. - Support for different spacing between u and v directions (the direction of the cols and the direction of the rows). - Support to avoid copying DistanceX and DistanceY constraints when used for locking a point. This means that if the geometry that you copy(array) is fully constraint, the resulting 2D array is also fully constraint. - UI support for creating 2D linear arrays in the sketcher. - Bug fix in python addArray, wrong line copy startingpoint calculation fixed. How to create a 2D array in the sketcher: 1. Select your geometric elements. 2. Click the button 3. Fill in the rows/cols and preferences on spacing and constraining each element of the array 4. Click Ok 5. Define the direction of the cols of the array and click
This commit is contained in:
parent
ee43612125
commit
6a16910ba5
|
@ -2011,7 +2011,8 @@ int SketchObject::addSymmetric(const std::vector<int> &geoIdList, int refGeoId,
|
|||
return Geometry.getSize()-1;
|
||||
}
|
||||
|
||||
int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3d& displacement, int csize/*=2*/, int rsize/*=1*/)
|
||||
int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3d& displacement, int csize/*=2*/, int rsize/*=1*/,
|
||||
bool constraindisplacement /*= false*/, double perpscale /*= 1.0*/)
|
||||
{
|
||||
const std::vector< Part::Geometry * > &geovals = getInternalGeometry();
|
||||
std::vector< Part::Geometry * > newgeoVals(geovals);
|
||||
|
@ -2021,83 +2022,142 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
|||
|
||||
int cgeoid = getHighestCurveIndex()+1;
|
||||
|
||||
int iterfirstgeoid = -1 ;
|
||||
|
||||
Base::Vector3d iterfirstpoint;
|
||||
|
||||
int refgeoid = -1;
|
||||
|
||||
int colrefgeoid = 0, rowrefgeoid = 0;
|
||||
|
||||
int currentrowfirstgeoid= -1, prevrowstartfirstgeoid = -1, prevfirstgeoid = -1;
|
||||
|
||||
Sketcher::PointPos refposId;
|
||||
|
||||
std::map<int, int> geoIdMap;
|
||||
|
||||
Base::Vector3d perpendicularDisplacement = Base::Vector3d(displacement.y,-displacement.x,0);
|
||||
Base::Vector3d perpendicularDisplacement = Base::Vector3d(perpscale*displacement.y,perpscale*-displacement.x,0);
|
||||
|
||||
int x,y;
|
||||
|
||||
for (y=0;y<rsize;y++) {
|
||||
for (y=0;y<rsize;y++) {
|
||||
for (x=0;x<csize;x++) {
|
||||
if(x == 0 && y == 0)
|
||||
|
||||
if(x == 0 && y == 0) { // the reference for constraining array elements is the first valid point of the first element
|
||||
const Part::Geometry *geo = getGeometry(*(geoIdList.begin()));
|
||||
refgeoid=*(geoIdList.begin());
|
||||
currentrowfirstgeoid = refgeoid;
|
||||
iterfirstgeoid = refgeoid;
|
||||
if(geo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
geo->getTypeId() == Part::GeomEllipse::getClassTypeId() ){
|
||||
refposId = Sketcher::mid;
|
||||
}
|
||||
else
|
||||
refposId = Sketcher::start;
|
||||
|
||||
continue; // the first element is already in place
|
||||
}
|
||||
else {
|
||||
prevfirstgeoid = iterfirstgeoid;
|
||||
|
||||
iterfirstgeoid = cgeoid;
|
||||
|
||||
if( x == 0 ) { // if first element of second row
|
||||
prevrowstartfirstgeoid = currentrowfirstgeoid;
|
||||
currentrowfirstgeoid = cgeoid;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<int>::const_iterator it = geoIdList.begin(); it != geoIdList.end(); ++it) {
|
||||
const Part::Geometry *geo = getGeometry(*it);
|
||||
Part::Geometry *geosym = geo->clone();
|
||||
Part::Geometry *geocopy = geo->clone();
|
||||
|
||||
// Handle Geometry
|
||||
if(geosym->getTypeId() == Part::GeomLineSegment::getClassTypeId()){
|
||||
Part::GeomLineSegment *geosymline = static_cast<Part::GeomLineSegment *>(geosym);
|
||||
if(geocopy->getTypeId() == Part::GeomLineSegment::getClassTypeId()){
|
||||
Part::GeomLineSegment *geosymline = static_cast<Part::GeomLineSegment *>(geocopy);
|
||||
Base::Vector3d sp = geosymline->getStartPoint();
|
||||
Base::Vector3d ep = geosymline->getEndPoint();
|
||||
Base::Vector3d ssp = geosymline->getStartPoint()+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
|
||||
geosymline->setPoints( sp+double(x)*displacement+double(y)*perpendicularDisplacement,
|
||||
geosymline->setPoints( ssp,
|
||||
ep+double(x)*displacement+double(y)*perpendicularDisplacement);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = ssp;
|
||||
}
|
||||
else if(geosym->getTypeId() == Part::GeomCircle::getClassTypeId()){
|
||||
Part::GeomCircle *geosymcircle = static_cast<Part::GeomCircle *>(geosym);
|
||||
Base::Vector3d cp = geosymcircle->getCenter();
|
||||
else if(geocopy->getTypeId() == Part::GeomCircle::getClassTypeId()){
|
||||
Part::GeomCircle *geosymcircle = static_cast<Part::GeomCircle *>(geocopy);
|
||||
Base::Vector3d cp = geosymcircle->getCenter();
|
||||
Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
|
||||
geosymcircle->setCenter(cp+double(x)*displacement+double(y)*perpendicularDisplacement);
|
||||
geosymcircle->setCenter(scp);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = scp;
|
||||
}
|
||||
else if(geosym->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){
|
||||
Part::GeomArcOfCircle *geoaoc = static_cast<Part::GeomArcOfCircle *>(geosym);
|
||||
else if(geocopy->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()){
|
||||
Part::GeomArcOfCircle *geoaoc = static_cast<Part::GeomArcOfCircle *>(geocopy);
|
||||
Base::Vector3d cp = geoaoc->getCenter();
|
||||
Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
|
||||
geoaoc->setCenter(scp);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = geoaoc->getStartPoint(true);
|
||||
}
|
||||
else if(geosym->getTypeId() == Part::GeomEllipse::getClassTypeId()){
|
||||
Part::GeomEllipse *geosymellipse = static_cast<Part::GeomEllipse *>(geosym);
|
||||
else if(geocopy->getTypeId() == Part::GeomEllipse::getClassTypeId()){
|
||||
Part::GeomEllipse *geosymellipse = static_cast<Part::GeomEllipse *>(geocopy);
|
||||
Base::Vector3d cp = geosymellipse->getCenter();
|
||||
Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
|
||||
geosymellipse->setCenter(scp);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = scp;
|
||||
}
|
||||
else if(geosym->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){
|
||||
Part::GeomArcOfEllipse *geosymaoe = static_cast<Part::GeomArcOfEllipse *>(geosym);
|
||||
Base::Vector3d cp = geosymaoe->getCenter();
|
||||
else if(geocopy->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()){
|
||||
Part::GeomArcOfEllipse *geoaoe = static_cast<Part::GeomArcOfEllipse *>(geocopy);
|
||||
Base::Vector3d cp = geoaoe->getCenter();
|
||||
Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
|
||||
geosymaoe->setCenter(scp);
|
||||
geoaoe->setCenter(scp);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = geoaoe->getStartPoint(true);
|
||||
}
|
||||
else if(geosym->getTypeId() == Part::GeomPoint::getClassTypeId()){
|
||||
Part::GeomPoint *geosympoint = static_cast<Part::GeomPoint *>(geosym);
|
||||
Base::Vector3d cp = geosympoint->getPoint();
|
||||
|
||||
geosympoint->setPoint(cp+double(x)*displacement+double(y)*perpendicularDisplacement);
|
||||
else if(geocopy->getTypeId() == Part::GeomPoint::getClassTypeId()){
|
||||
Part::GeomPoint *geopoint = static_cast<Part::GeomPoint *>(geocopy);
|
||||
Base::Vector3d cp = geopoint->getPoint();
|
||||
Base::Vector3d scp = cp+double(x)*displacement+double(y)*perpendicularDisplacement;
|
||||
geopoint->setPoint(scp);
|
||||
|
||||
if(it == geoIdList.begin())
|
||||
iterfirstpoint = scp;
|
||||
}
|
||||
else {
|
||||
Base::Console().Error("Unsupported Geometry!! Just copying it.\n");
|
||||
Base::Console().Error("Unsupported Geometry!! Just skipping it.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
newgeoVals.push_back(geosym);
|
||||
newgeoVals.push_back(geocopy);
|
||||
geoIdMap.insert(std::make_pair(*it, cgeoid));
|
||||
cgeoid++;
|
||||
}
|
||||
|
||||
// handle constraints
|
||||
// handle geometry constraints
|
||||
for (std::vector<Constraint *>::const_iterator it = constrvals.begin(); it != constrvals.end(); ++it) {
|
||||
|
||||
std::vector<int>::const_iterator fit=std::find(geoIdList.begin(), geoIdList.end(), (*it)->First);
|
||||
|
||||
if(fit != geoIdList.end()) { // if First of constraint is in geoIdList
|
||||
|
||||
if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) {
|
||||
Constraint *constNew = (*it)->clone();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
newconstrVals.push_back(constNew);
|
||||
if( (*it)->Second == Constraint::GeoUndef /*&& (*it)->Third == Constraint::GeoUndef*/) {
|
||||
if( ((*it)->Type != Sketcher::DistanceX && (*it)->Type != Sketcher::DistanceY ) ||
|
||||
(*it)->FirstPos == Sketcher::none ) { // if it is not a point locking DistanceX/Y
|
||||
Constraint *constNew = (*it)->clone();
|
||||
constNew->First = geoIdMap[(*it)->First];
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
else { // other geoids intervene in this constraint
|
||||
|
||||
|
@ -2127,6 +2187,159 @@ int SketchObject::addCopy(const std::vector<int> &geoIdList, const Base::Vector3
|
|||
}
|
||||
}
|
||||
|
||||
// handle inter-geometry constraints
|
||||
// example: App.ActiveDocument.Sketch.addArray([0,1], App.Vector(150,150,0),3,4,True)
|
||||
if(constraindisplacement){
|
||||
|
||||
// add a construction line
|
||||
Part::GeomLineSegment *constrline= new Part::GeomLineSegment();
|
||||
|
||||
Base::Vector3d spdisp = Vector3d(); // initializes to 0,0,0
|
||||
|
||||
Base::Vector3d sp = getPoint(refgeoid,refposId)+ ( ( x == 0 )?
|
||||
(double(x)*displacement+double(y-1)*perpendicularDisplacement):
|
||||
(double(x-1)*displacement+double(y)*perpendicularDisplacement)); // position of the reference point
|
||||
Base::Vector3d ep = iterfirstpoint; // position of the current instance corresponding point
|
||||
constrline->setPoints(sp,ep);
|
||||
constrline->Construction=true;
|
||||
|
||||
newgeoVals.push_back(constrline);
|
||||
|
||||
Constraint *constNew;
|
||||
|
||||
if(x == 0) { // first element of a row
|
||||
|
||||
// add coincidents for construction line
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Coincident;
|
||||
constNew->First = prevrowstartfirstgeoid;
|
||||
constNew->FirstPos = refposId;
|
||||
constNew->Second = cgeoid;
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Coincident;
|
||||
constNew->First = iterfirstgeoid;
|
||||
constNew->FirstPos = refposId;
|
||||
constNew->Second = cgeoid;
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
if( y == 1 ) { // it is the first added element of this row in the perpendicular to displacementvector direction
|
||||
rowrefgeoid = cgeoid;
|
||||
cgeoid++;
|
||||
|
||||
// add length (or equal if perpscale==1) and perpendicular
|
||||
if(perpscale==1.0) {
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Equal;
|
||||
constNew->First = rowrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = colrefgeoid;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
} else {
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Distance;
|
||||
constNew->First = rowrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Value = perpendicularDisplacement.Length();
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Perpendicular;
|
||||
constNew->First = rowrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = colrefgeoid;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
else { // it is just one more element in the col direction
|
||||
cgeoid++;
|
||||
|
||||
// all other first rowers get an equality and perpendicular constraint
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Equal;
|
||||
constNew->First = rowrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = cgeoid-1;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Perpendicular;
|
||||
constNew->First = cgeoid-1;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = colrefgeoid;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
}
|
||||
}
|
||||
else { // any element not being the first element of a row
|
||||
|
||||
// add coincidents for construction line
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Coincident;
|
||||
constNew->First = prevfirstgeoid;
|
||||
constNew->FirstPos = refposId;
|
||||
constNew->Second = cgeoid;
|
||||
constNew->SecondPos = Sketcher::start;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Coincident;
|
||||
constNew->First = iterfirstgeoid;
|
||||
constNew->FirstPos = refposId;
|
||||
constNew->Second = cgeoid;
|
||||
constNew->SecondPos = Sketcher::end;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
if(y == 0 && x == 1) { // first element of the first row
|
||||
colrefgeoid = cgeoid;
|
||||
cgeoid++;
|
||||
|
||||
// add length and Angle
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Distance;
|
||||
constNew->First = colrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Value = displacement.Length();
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Angle;
|
||||
constNew->First = colrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Value = atan2(displacement.y,displacement.x);
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
}
|
||||
else { // any other element
|
||||
cgeoid++;
|
||||
|
||||
// all other elements get an equality and parallel constraint
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Equal;
|
||||
constNew->First = colrefgeoid;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = cgeoid-1;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
|
||||
constNew = new Constraint();
|
||||
constNew->Type = Sketcher::Parallel;
|
||||
constNew->First = cgeoid-1;
|
||||
constNew->FirstPos = Sketcher::none;
|
||||
constNew->Second = colrefgeoid;
|
||||
constNew->SecondPos = Sketcher::none;
|
||||
newconstrVals.push_back(constNew);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
geoIdMap.clear(); // after each creation reset map so that the key-value is univoque
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,8 +152,10 @@ public:
|
|||
int trim(int geoId, const Base::Vector3d& point);
|
||||
/// adds symmetric geometric elements with respect to the refGeoId (line or point)
|
||||
int addSymmetric(const std::vector<int> &geoIdList, int refGeoId, Sketcher::PointPos refPosId=Sketcher::none);
|
||||
/// adds a copy of the geometric elements displaced by the displacement vector
|
||||
int addCopy(const std::vector<int> &geoIdList, const Base::Vector3d& displacement, int csize=2, int rsize=1);
|
||||
/// with default parameters adds a copy of the geometric elements displaced by the displacement vector.
|
||||
/// It creates an array of csize elements in the direction of the displacement vector by rsize elements in the
|
||||
/// direction perpendicular to the displacement vector, wherein the modulus of this perpendicular vector is scaled by perpscale.
|
||||
int addCopy(const std::vector<int> &geoIdList, const Base::Vector3d& displacement, int csize=2, int rsize=1, bool constraindisplacement = false, double perpscale = 1.0);
|
||||
/// Exposes all internal geometry of an object supporting internal geometry
|
||||
/*!
|
||||
* \return -1 on error
|
||||
|
|
|
@ -834,8 +834,10 @@ PyObject* SketchObjectPy::addArray(PyObject *args)
|
|||
{
|
||||
PyObject *pcObj, *pcVect;
|
||||
int rows,cols;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO!ii", &pcObj, &(Base::VectorPy::Type), &pcVect,&rows,&cols))
|
||||
double perpscale=1.0;
|
||||
PyObject* constraindisplacement= Py_False;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO!ii|O!d", &pcObj, &(Base::VectorPy::Type), &pcVect,&rows,&cols, &PyBool_Type, &constraindisplacement,&perpscale))
|
||||
return 0;
|
||||
|
||||
Base::Vector3d vect = static_cast<Base::VectorPy*>(pcVect)->value();
|
||||
|
@ -849,7 +851,7 @@ PyObject* SketchObjectPy::addArray(PyObject *args)
|
|||
geoIdList.push_back(PyInt_AsLong((*it).ptr()));
|
||||
}
|
||||
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect,rows,cols) + 1;
|
||||
int ret = this->getSketchObjectPtr()->addCopy(geoIdList,vect,rows,cols, PyObject_IsTrue(constraindisplacement) ? true : false, perpscale) + 1;
|
||||
|
||||
if(ret == -1)
|
||||
throw Py::TypeError("Copy operation unsuccessful!");
|
||||
|
|
|
@ -37,6 +37,7 @@ set(SketcherGui_MOC_HDRS
|
|||
TaskDlgEditSketch.h
|
||||
SketchOrientationDialog.h
|
||||
SketcherSettings.h
|
||||
SketchLinearArrayDialog.h
|
||||
PropertyConstraintListItem.h
|
||||
)
|
||||
fc_wrap_cpp(SketcherGui_MOC_SRCS ${SketcherGui_MOC_HDRS})
|
||||
|
@ -54,6 +55,7 @@ set(SketcherGui_UIC_SRCS
|
|||
InsertDatum.ui
|
||||
SketchOrientationDialog.ui
|
||||
SketcherSettings.ui
|
||||
SketchLinearArrayDialog.ui
|
||||
)
|
||||
qt4_wrap_ui(SketcherGui_UIC_HDRS ${SketcherGui_UIC_SRCS})
|
||||
|
||||
|
@ -110,6 +112,8 @@ SET(SketcherGui_SRCS
|
|||
SketchOrientationDialog.h
|
||||
SketcherSettings.cpp
|
||||
SketcherSettings.h
|
||||
SketchLinearArrayDialog.h
|
||||
SketchLinearArrayDialog.cpp
|
||||
TaskDlgEditSketch.cpp
|
||||
TaskDlgEditSketch.h
|
||||
ViewProviderPython.cpp
|
||||
|
|
|
@ -37,10 +37,17 @@
|
|||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/DlgEditFileIncludeProptertyExternal.h>
|
||||
|
||||
#include <Gui/Action.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include "ViewProviderSketch.h"
|
||||
#include "DrawSketchHandler.h"
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Sketcher/App/SketchObject.h>
|
||||
|
||||
#include "ViewProviderSketch.h"
|
||||
#include "SketchLinearArrayDialog.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace SketcherGui;
|
||||
|
@ -64,6 +71,19 @@ bool isSketcherAcceleratorActive(Gui::Document *doc, bool actsOnSelection )
|
|||
return false;
|
||||
}
|
||||
|
||||
void ActivateAcceleratorHandler(Gui::Document *doc,DrawSketchHandler *handler)
|
||||
{
|
||||
if (doc) {
|
||||
if (doc->getInEdit() && doc->getInEdit()->isDerivedFrom
|
||||
(SketcherGui::ViewProviderSketch::getClassTypeId())) {
|
||||
|
||||
SketcherGui::ViewProviderSketch* vp = dynamic_cast<SketcherGui::ViewProviderSketch*> (doc->getInEdit());
|
||||
vp->purgeHandler();
|
||||
vp->activateHandler(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close Shape Command
|
||||
DEF_STD_CMD_A(CmdSketcherCloseShape);
|
||||
|
||||
|
@ -1171,6 +1191,576 @@ bool CmdSketcherSymmetry::isActive(void)
|
|||
return isSketcherAcceleratorActive( getActiveGuiDocument(), true );
|
||||
}
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_createcopy[]={
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
". c None",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"......................###.......",
|
||||
"...................####.#.......",
|
||||
".................###..###.......",
|
||||
"...............###..............",
|
||||
".............###................",
|
||||
"............###.................",
|
||||
"...........##...................",
|
||||
"............###.................",
|
||||
".............###................",
|
||||
"...............###..............",
|
||||
".................###..###.......",
|
||||
"...................####.#.......",
|
||||
"......................###.......",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
|
||||
class DrawSketchHandlerCopy: public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerCopy(string geoidlist, int origingeoid, Sketcher::PointPos originpos, int nelements): geoIdList(geoidlist), OriginGeoId (origingeoid),
|
||||
OriginPos(originpos), nElements(nelements), Mode(STATUS_SEEK_First), EditCurve(2){}
|
||||
virtual ~DrawSketchHandlerCopy(){}
|
||||
/// mode table
|
||||
enum SelectMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
STATUS_End
|
||||
};
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createcopy),7,7);
|
||||
Origin = static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->getPoint(OriginGeoId, OriginPos);
|
||||
EditCurve[0] = Base::Vector2D(Origin.x,Origin.y);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
float length = (onSketchPos - EditCurve[0]).Length();
|
||||
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2D(1.f,0.f));
|
||||
SbString text;
|
||||
text.sprintf(" (%.1f,%.1fdeg)", length, angle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.0,0.0),AutoConstraint::VERTEX)) {
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First){
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_End){
|
||||
|
||||
Base::Vector2D vector = EditCurve[1]-EditCurve[0];
|
||||
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
Gui::Command::openCommand("Create copy of geometry");
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
|
||||
|
||||
try{
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc, "App.ActiveDocument.%s.addCopy(%s,App.Vector(%f,%f,0))",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
geoIdList.c_str(), vector.fX, vector.fY
|
||||
);
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
|
||||
// add auto constraints for the destination copy
|
||||
if (sugConstr1.size() > 0) {
|
||||
createAutoConstraints(sugConstr1, OriginGeoId+nElements, OriginPos);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
||||
if(autoRecompute)
|
||||
Gui::Command::updateActive();
|
||||
else
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
string geoIdList;
|
||||
Base::Vector3d Origin;
|
||||
int OriginGeoId;
|
||||
Sketcher::PointPos OriginPos;
|
||||
int nElements;
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
std::vector<AutoConstraint> sugConstr1;
|
||||
};
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherCopy);
|
||||
|
||||
CmdSketcherCopy::CmdSketcherCopy()
|
||||
:Command("Sketcher_Copy")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("Copy");
|
||||
sToolTipText = QT_TR_NOOP("Creates a copy of the geometry taking as reference the last selected point");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_Copy";
|
||||
sAccel = "CTRL+C";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherCopy::activated(int iMsg)
|
||||
{
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select elements from a single sketch."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string> &SubNames = selection[0].getSubNames();
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
std::string doc_name = Obj->getDocument()->getName();
|
||||
std::string obj_name = Obj->getNameInDocument();
|
||||
std::stringstream ss;
|
||||
|
||||
getSelection().clearSelection();
|
||||
|
||||
int nelements = SubNames.size();
|
||||
|
||||
int LastGeoId;
|
||||
Sketcher::PointPos LastPointPos = Sketcher::none;
|
||||
const Part::Geometry *LastGeo;
|
||||
|
||||
// create python command with list of elements
|
||||
std::stringstream stream;
|
||||
int geoids = 0;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
// only handle non-external edges
|
||||
if ( it->size() > 4 && it->substr(0,4) == "Edge" ) {
|
||||
LastGeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
|
||||
LastPointPos = Sketcher::none;
|
||||
|
||||
LastGeo = Obj->getGeometry(LastGeoId);
|
||||
|
||||
// lines to copy
|
||||
if(LastGeoId>=0) {
|
||||
geoids++;
|
||||
stream << LastGeoId << ",";
|
||||
}
|
||||
}
|
||||
else if(it->size() > 6 && it->substr(0,6) == "Vertex"){
|
||||
// only if it is a GeomPoint
|
||||
int VtId = std::atoi(it->substr(6,4000).c_str()) - 1;
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
Obj->getGeoVertexIndex(VtId, GeoId, PosId);
|
||||
if (Obj->getGeometry(GeoId)->getTypeId() == Part::GeomPoint::getClassTypeId()) {
|
||||
LastGeoId = GeoId;
|
||||
LastPointPos = Sketcher::start;
|
||||
// points to copy
|
||||
if(LastGeoId>=0) {
|
||||
geoids++;
|
||||
stream << LastGeoId << ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if last selected element is a Vertex, not being a GeomPoint
|
||||
if(SubNames.rbegin()->size() > 6 && SubNames.rbegin()->substr(0,6) == "Vertex"){
|
||||
int VtId = std::atoi(SubNames.rbegin()->substr(6,4000).c_str()) - 1;
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
Obj->getGeoVertexIndex(VtId, GeoId, PosId);
|
||||
if (Obj->getGeometry(GeoId)->getTypeId() != Part::GeomPoint::getClassTypeId()) {
|
||||
LastGeoId = GeoId;
|
||||
LastPointPos = PosId;
|
||||
}
|
||||
}
|
||||
|
||||
if ( geoids < 1 ) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("A copy requires at least one selected non-external geometric element"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string geoIdList = stream.str();
|
||||
|
||||
// remove the last added comma and brackets to make the python list
|
||||
int index = geoIdList.rfind(',');
|
||||
geoIdList.resize(index);
|
||||
geoIdList.insert(0,1,'[');
|
||||
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)
|
||||
if(LastPointPos == Sketcher::none){
|
||||
if( LastGeo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
LastGeo->getTypeId() == Part::GeomEllipse::getClassTypeId() ) {
|
||||
LastPointPos = Sketcher::mid;
|
||||
}
|
||||
else {
|
||||
LastPointPos = Sketcher::start;
|
||||
}
|
||||
}
|
||||
|
||||
ActivateAcceleratorHandler(getActiveGuiDocument(),new DrawSketchHandlerCopy(geoIdList, LastGeoId, LastPointPos, geoids));
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CmdSketcherCopy::isActive(void)
|
||||
{
|
||||
return isSketcherAcceleratorActive( getActiveGuiDocument(), true );
|
||||
}
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_createlineararray[]={
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
". c None",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
".....###.............###........",
|
||||
"....#.####.........####.#.......",
|
||||
"....###.###......###..###.......",
|
||||
".........###...###..............",
|
||||
"...........#####................",
|
||||
"............###.................",
|
||||
"...........#####................",
|
||||
"............###.................",
|
||||
"...........#####................",
|
||||
"........###....###..............",
|
||||
".###..###........###..###.......",
|
||||
".#.####............####.#.......",
|
||||
".###..................###.......",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
|
||||
class DrawSketchHandlerLinearArray: public DrawSketchHandler
|
||||
{
|
||||
public:
|
||||
DrawSketchHandlerLinearArray(string geoidlist, int origingeoid, Sketcher::PointPos originpos, int nelements,
|
||||
int rows,int cols,bool constraintSeparation,
|
||||
bool equalVerticalHorizontalSpacing ): geoIdList(geoidlist), OriginGeoId (origingeoid),
|
||||
Rows(rows), Cols(cols), ConstraintSeparation(constraintSeparation), EqualVerticalHorizontalSpacing(equalVerticalHorizontalSpacing),
|
||||
OriginPos(originpos), nElements(nelements), Mode(STATUS_SEEK_First), EditCurve(2){}
|
||||
virtual ~DrawSketchHandlerLinearArray(){}
|
||||
/// mode table
|
||||
enum SelectMode {
|
||||
STATUS_SEEK_First, /**< enum value ----. */
|
||||
STATUS_End
|
||||
};
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
setCursor(QPixmap(cursor_createlineararray),7,7);
|
||||
Origin = static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->getPoint(OriginGeoId, OriginPos);
|
||||
EditCurve[0] = Base::Vector2D(Origin.x,Origin.y);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First) {
|
||||
float length = (onSketchPos - EditCurve[0]).Length();
|
||||
float angle = (onSketchPos - EditCurve[0]).GetAngle(Base::Vector2D(1.f,0.f));
|
||||
SbString text;
|
||||
text.sprintf(" (%.1f,%.1fdeg)", length, angle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr1, onSketchPos, Base::Vector2D(0.0,0.0),AutoConstraint::VERTEX)) {
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
applyCursor();
|
||||
}
|
||||
|
||||
virtual bool pressButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_SEEK_First){
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool releaseButton(Base::Vector2D onSketchPos)
|
||||
{
|
||||
if (Mode==STATUS_End){
|
||||
|
||||
Base::Vector2D vector = EditCurve[1]-EditCurve[0];
|
||||
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
Gui::Command::openCommand("Create copy of geometry");
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool autoRecompute = hGrp->GetBool("AutoRecompute",false);
|
||||
|
||||
try{
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc, "App.ActiveDocument.%s.addArray(%s, App.Vector(%f,%f,0),%d,%d,%s,%f)",
|
||||
sketchgui->getObject()->getNameInDocument(),
|
||||
geoIdList.c_str(), vector.fX, vector.fY,
|
||||
Cols, Rows,
|
||||
(ConstraintSeparation?"True":"False"),
|
||||
(EqualVerticalHorizontalSpacing?1.0:0.5));
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Error("%s\n", e.what());
|
||||
Gui::Command::abortCommand();
|
||||
}
|
||||
|
||||
// add auto constraints for the destination copy
|
||||
if (sugConstr1.size() > 0) {
|
||||
createAutoConstraints(sugConstr1, OriginGeoId+nElements, OriginPos);
|
||||
sugConstr1.clear();
|
||||
}
|
||||
|
||||
if(autoRecompute)
|
||||
Gui::Command::updateActive();
|
||||
else
|
||||
static_cast<Sketcher::SketchObject *>(sketchgui->getObject())->solve();
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
}
|
||||
return true;
|
||||
}
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
string geoIdList;
|
||||
Base::Vector3d Origin;
|
||||
int OriginGeoId;
|
||||
Sketcher::PointPos OriginPos;
|
||||
int nElements;
|
||||
int Rows;
|
||||
int Cols;
|
||||
bool ConstraintSeparation;
|
||||
bool EqualVerticalHorizontalSpacing;
|
||||
std::vector<Base::Vector2D> EditCurve;
|
||||
std::vector<AutoConstraint> sugConstr1;
|
||||
};
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdSketcherLinearArray);
|
||||
|
||||
CmdSketcherLinearArray::CmdSketcherLinearArray()
|
||||
:Command("Sketcher_LinearArray")
|
||||
{
|
||||
sAppModule = "Sketcher";
|
||||
sGroup = QT_TR_NOOP("Sketcher");
|
||||
sMenuText = QT_TR_NOOP("LinearArray");
|
||||
sToolTipText = QT_TR_NOOP("Creates a lineararray of the geometry taking as reference the last selected point");
|
||||
sWhatsThis = sToolTipText;
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "Sketcher_LinearArray";
|
||||
sAccel = "";
|
||||
eType = ForEdit;
|
||||
}
|
||||
|
||||
void CmdSketcherLinearArray::activated(int iMsg)
|
||||
{
|
||||
// get the selection
|
||||
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
|
||||
Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());
|
||||
|
||||
// only one sketch with its subelements are allowed to be selected
|
||||
if (selection.size() != 1) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("Select elements from a single sketch."));
|
||||
return;
|
||||
}
|
||||
|
||||
// get the needed lists and objects
|
||||
const std::vector<std::string> &SubNames = selection[0].getSubNames();
|
||||
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();
|
||||
|
||||
std::string doc_name = Obj->getDocument()->getName();
|
||||
std::string obj_name = Obj->getNameInDocument();
|
||||
std::stringstream ss;
|
||||
|
||||
getSelection().clearSelection();
|
||||
|
||||
int nelements = SubNames.size();
|
||||
|
||||
int LastGeoId;
|
||||
Sketcher::PointPos LastPointPos = Sketcher::none;
|
||||
const Part::Geometry *LastGeo;
|
||||
|
||||
// create python command with list of elements
|
||||
std::stringstream stream;
|
||||
int geoids = 0;
|
||||
|
||||
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
|
||||
// only handle non-external edges
|
||||
if ( it->size() > 4 && it->substr(0,4) == "Edge" ) {
|
||||
LastGeoId = std::atoi(it->substr(4,4000).c_str()) - 1;
|
||||
LastPointPos = Sketcher::none;
|
||||
|
||||
LastGeo = Obj->getGeometry(LastGeoId);
|
||||
|
||||
// lines to copy
|
||||
if(LastGeoId>=0) {
|
||||
geoids++;
|
||||
stream << LastGeoId << ",";
|
||||
}
|
||||
}
|
||||
else if(it->size() > 6 && it->substr(0,6) == "Vertex"){
|
||||
// only if it is a GeomPoint
|
||||
int VtId = std::atoi(it->substr(6,4000).c_str()) - 1;
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
Obj->getGeoVertexIndex(VtId, GeoId, PosId);
|
||||
if (Obj->getGeometry(GeoId)->getTypeId() == Part::GeomPoint::getClassTypeId()) {
|
||||
LastGeoId = GeoId;
|
||||
LastPointPos = Sketcher::start;
|
||||
// points to copy
|
||||
if(LastGeoId>=0) {
|
||||
geoids++;
|
||||
stream << LastGeoId << ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if last selected element is a Vertex, not being a GeomPoint
|
||||
if(SubNames.rbegin()->size() > 6 && SubNames.rbegin()->substr(0,6) == "Vertex"){
|
||||
int VtId = std::atoi(SubNames.rbegin()->substr(6,4000).c_str()) - 1;
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
Obj->getGeoVertexIndex(VtId, GeoId, PosId);
|
||||
if (Obj->getGeometry(GeoId)->getTypeId() != Part::GeomPoint::getClassTypeId()) {
|
||||
LastGeoId = GeoId;
|
||||
LastPointPos = PosId;
|
||||
}
|
||||
}
|
||||
|
||||
if ( geoids < 1 ) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("A copy requires at least one selected non-external geometric element"));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string geoIdList = stream.str();
|
||||
|
||||
// remove the last added comma and brackets to make the python list
|
||||
int index = geoIdList.rfind(',');
|
||||
geoIdList.resize(index);
|
||||
geoIdList.insert(0,1,'[');
|
||||
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)
|
||||
if(LastPointPos == Sketcher::none){
|
||||
if( LastGeo->getTypeId() == Part::GeomCircle::getClassTypeId() ||
|
||||
LastGeo->getTypeId() == Part::GeomEllipse::getClassTypeId() ) {
|
||||
LastPointPos = Sketcher::mid;
|
||||
}
|
||||
else {
|
||||
LastPointPos = Sketcher::start;
|
||||
}
|
||||
}
|
||||
|
||||
// Pop-up asking for values
|
||||
SketchLinearArrayDialog * slad = new SketchLinearArrayDialog();
|
||||
|
||||
if( slad->exec() == QDialog::Accepted )
|
||||
ActivateAcceleratorHandler(getActiveGuiDocument(),
|
||||
new DrawSketchHandlerLinearArray(geoIdList, LastGeoId, LastPointPos, geoids,
|
||||
slad->Rows, slad->Cols, slad->ConstraintSeparation,
|
||||
slad->EqualVerticalHorizontalSpacing));
|
||||
|
||||
delete slad;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool CmdSketcherLinearArray::isActive(void)
|
||||
{
|
||||
return isSketcherAcceleratorActive( getActiveGuiDocument(), true );
|
||||
}
|
||||
|
||||
void CreateSketcherCommandsConstraintAccel(void)
|
||||
{
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
|
@ -1185,5 +1775,7 @@ void CreateSketcherCommandsConstraintAccel(void)
|
|||
rcCmdMgr.addCommand(new CmdSketcherSelectConflictingConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSelectElementsAssociatedWithConstraints());
|
||||
rcCmdMgr.addCommand(new CmdSketcherRestoreInternalAlignmentGeometry());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSymmetry());
|
||||
rcCmdMgr.addCommand(new CmdSketcherSymmetry());
|
||||
rcCmdMgr.addCommand(new CmdSketcherCopy());
|
||||
rcCmdMgr.addCommand(new CmdSketcherLinearArray());
|
||||
}
|
||||
|
|
78
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.cpp
Normal file
78
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2015 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
|
||||
* *
|
||||
* 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 <QPixmap>
|
||||
# include <QDialog>
|
||||
#endif
|
||||
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
|
||||
#include "ui_SketchLinearArrayDialog.h"
|
||||
#include "SketchLinearArrayDialog.h"
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
SketchLinearArrayDialog::SketchLinearArrayDialog(void)
|
||||
: QDialog(Gui::getMainWindow()), ui(new Ui_SketchLinearArrayDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->RowsQuantitySpinBox->onRestore();
|
||||
ui->ColsQuantitySpinBox->onRestore();
|
||||
ui->ConstraintSeparationCheckBox->onRestore();
|
||||
ui->EqualVerticalHorizontalSpacingCheckBox->onRestore();
|
||||
|
||||
updateValues();
|
||||
}
|
||||
|
||||
SketchLinearArrayDialog::~SketchLinearArrayDialog()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SketchLinearArrayDialog::accept()
|
||||
{
|
||||
ui->RowsQuantitySpinBox->onSave();
|
||||
ui->ColsQuantitySpinBox->onSave();
|
||||
ui->ConstraintSeparationCheckBox->onSave();
|
||||
ui->EqualVerticalHorizontalSpacingCheckBox->onSave();
|
||||
|
||||
updateValues();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void SketchLinearArrayDialog::updateValues(void)
|
||||
{
|
||||
Rows = ui->RowsQuantitySpinBox->value();
|
||||
Cols = ui->ColsQuantitySpinBox->value();
|
||||
ConstraintSeparation = ui->ConstraintSeparationCheckBox->isChecked();
|
||||
EqualVerticalHorizontalSpacing = ui->EqualVerticalHorizontalSpacingCheckBox->isChecked();
|
||||
}
|
||||
|
||||
#include "moc_SketchLinearArrayDialog.cpp"
|
55
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.h
Normal file
55
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2015 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
|
||||
* *
|
||||
* 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 SKETCHERGUI_SketchLinearArrayDialog_H
|
||||
#define SKETCHERGUI_SketchLinearArrayDialog_H
|
||||
|
||||
#include <Base/Placement.h>
|
||||
#include <QDialog>
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class Ui_SketchLinearArrayDialog;
|
||||
class SketchLinearArrayDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SketchLinearArrayDialog(void);
|
||||
~SketchLinearArrayDialog();
|
||||
|
||||
void accept();
|
||||
|
||||
int Rows;
|
||||
int Cols;
|
||||
bool ConstraintSeparation;
|
||||
bool EqualVerticalHorizontalSpacing;
|
||||
|
||||
protected:
|
||||
void updateValues(void);
|
||||
private:
|
||||
Ui_SketchLinearArrayDialog* ui;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SKETCHERGUI_SketchLinearArrayDialog_H
|
187
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.ui
Normal file
187
src/Mod/Sketcher/Gui/SketchLinearArrayDialog.ui
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SketcherGui::SketchLinearArrayDialog</class>
|
||||
<widget class="QDialog" name="SketcherGui::SketchLinearArrayDialog">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>287</width>
|
||||
<height>177</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create array</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Columns:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefSpinBox" name="ColsQuantitySpinBox">
|
||||
<property name="toolTip">
|
||||
<string>Number of columns of the linear array</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultArrayColumnNumber</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Sketcher</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Rows:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefSpinBox" name="RowsQuantitySpinBox">
|
||||
<property name="toolTip">
|
||||
<string>Number of rows of the linear array</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultArrayRowNumber</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Sketcher</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="EqualVerticalHorizontalSpacingCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Makes the inter-row and inter-col spacing the same if clicked</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Equal vertical/horizontal spacing</string>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultEqualVerticalHorizontalSpacing</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Sketcher</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="ConstraintSeparationCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>if selected, each element in the array is constraint with respect to the others using construction lines</string>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Constrain inter-element separation</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DefaultConstraintArrayElements</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Sketcher</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::PrefSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::PrefCheckBox</class>
|
||||
<extends>QCheckBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SketcherGui::SketchLinearArrayDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SketcherGui::SketchLinearArrayDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -246,7 +246,10 @@ inline void SketcherAddWorkbenchTools<Gui::MenuItem>(Gui::MenuItem& consaccel){
|
|||
<< "Sketcher_SelectConflictingConstraints"
|
||||
<< "Sketcher_SelectElementsAssociatedWithConstraints"
|
||||
<< "Sketcher_RestoreInternalAlignmentGeometry"
|
||||
<< "Sketcher_Symmetry";
|
||||
<< "Sketcher_Symmetry"
|
||||
<< "Sketcher_Copy"
|
||||
<< "Sketcher_LinearArray";
|
||||
|
||||
}
|
||||
template <>
|
||||
inline void SketcherAddWorkbenchTools<Gui::ToolBarItem>(Gui::ToolBarItem& consaccel){
|
||||
|
@ -254,7 +257,9 @@ inline void SketcherAddWorkbenchTools<Gui::ToolBarItem>(Gui::ToolBarItem& consac
|
|||
<< "Sketcher_ConnectLines"
|
||||
<< "Sketcher_SelectConstraints"
|
||||
<< "Sketcher_RestoreInternalAlignmentGeometry"
|
||||
<< "Sketcher_Symmetry";
|
||||
<< "Sketcher_Symmetry"
|
||||
<< "Sketcher_Copy"
|
||||
<< "Sketcher_LinearArray";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
Loading…
Reference in New Issue
Block a user