[Feature idea] Sketcher Ctrl-C ctrl-V between projects
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
[Feature idea] Sketcher Ctrl-C ctrl-V between projects
Hey guys,
Something that has been annoying me a lot is the inability to copy/paste geometries in the sketcher.
I know there's the copy/clone commands, but ctrl-c ctrl-v is much more intuitive and fast to use.
Beside something that would be really cool is to be able to copy/paste geometries between sketches and between project :
You copy in project A sketch001, then open project B, open sketch006 and paste your selected geometries.
My question is, in what scope should this be integrated in order to be cross sketches/projects ?
If it's integrated inside ViewProviderSketch::keyPressed then will the data be lost once the sketch is exited?
My guess is that it requires a vector of geometries, but where to declare it such that it is 'program wide' ?
Cheers
Something that has been annoying me a lot is the inability to copy/paste geometries in the sketcher.
I know there's the copy/clone commands, but ctrl-c ctrl-v is much more intuitive and fast to use.
Beside something that would be really cool is to be able to copy/paste geometries between sketches and between project :
You copy in project A sketch001, then open project B, open sketch006 and paste your selected geometries.
My question is, in what scope should this be integrated in order to be cross sketches/projects ?
If it's integrated inside ViewProviderSketch::keyPressed then will the data be lost once the sketch is exited?
My guess is that it requires a vector of geometries, but where to declare it such that it is 'program wide' ?
Cheers
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
I remember having read that copying of complex geometries up to a whole model is done by using the system wide keyboard buffer on the textual xml representation.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
An
Ok so the plan is :
Get the selected geometries.
Get the constraints that are on those geometries.
Put all that on a ByteArray
Put the byteArray in the QclipBoard. This way the copy/paste can even be done between instances of FreeCAD. Even potentially posted as text in the forum, which could make sharing geometry on the forum easy (for bug demo or other) without having to save and attach the freecad file.
Sounds easy. But I'm stuck at first step. I can't find how to get the list of selected geometries. I basically want a
First issue is that it seems that to get the geometries you start with a vector of string "vertex 1" "edge 4"... Ok the code is here already.
Now my problem is that I can't find how to create an empty std::vector<Part::Geometry*> and push_back the geometries in the for loop.
I try the simple :
But VS tells me it's wrong because of something I can't get :
Another issue is that this is a vector of pointers. So my bytearray will have useless pointers stored and not the actual data...
Any hint?
Get the selected geometries.
Get the constraints that are on those geometries.
Put all that on a ByteArray
Put the byteArray in the QclipBoard. This way the copy/paste can even be done between instances of FreeCAD. Even potentially posted as text in the forum, which could make sharing geometry on the forum easy (for bug demo or other) without having to save and attach the freecad file.
Sounds easy. But I'm stuck at first step. I can't find how to get the list of selected geometries. I basically want a
Code: Select all
std::vector<Part::Geometry*> geoSelected;
Code: Select all
// 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) {
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();
if (SubNames.empty()) {
QMessageBox::warning(Gui::getMainWindow(),
QObject::tr("Wrong selection"),
QObject::tr("Select elements from a single sketch."));
return;
}
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
getSelection().clearSelection();
int LastGeoId = 0;
Sketcher::PointPos LastPointPos = Sketcher::PointPos::none;
const Part::Geometry *LastGeo = 0;
// 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::PointPos::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::PointPos::start;
// points to copy
if (LastGeoId >= 0) {
geoids++;
stream << LastGeoId << ",";
}
}
}
}
I try the simple :
Code: Select all
std::vector<Part::Geometry*> geovals;
for (std::vector<std::string>::const_iterator it = SubNames.begin(); it != SubNames.end(); ++it) {
if (it->size() > 4 && it->substr(0, 4) == "Edge") {
LastGeoId = std::atoi(it->substr(4, 4000).c_str()) - 1;
LastGeo = Obj->getGeometry(LastGeoId);
if (LastGeoId >= 0) {
geovals.push_back(LastGeo);
}
}
Code: Select all
C++ no instance of overloaded function matches the argument list argument types are: (const Part::Geometry *) object type is: std::vector<Part::Geometry *, std::allocator<Part::Geometry *>>
Any hint?
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: An
Yes and No, Sketch is not only a bunch of geometries, so, you could have some difficulties to export it.
In Curves WB where you have a menu item that permit to past the code that is generating the Curve or the Surface in "Python Console".
Using it you will have this printed in "Python Console"
Code: Select all
>>> ### Begin command Curves_bspline_to_console
>>> import FreeCAD
>>> from FreeCAD import Vector
>>> import Part
>>>
>>> poles0 = [Vector (-186.17474365234375, 73.06820678710938, 40.0), Vector (-466.6299222984221, 100.91031895516615, 40.0), Vector (-560.541579553814, 246.90657028186783, 39.999999999999986), Vector (-39.8610101313747, 384.96656062446516, 40.000000000000014), Vector (-15.280454727937686, 200.65344883087087, 40.0), Vector (-135.01138305664062, 56.912776947021484, 40.0)]
>>> weights0 = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
>>> knots0 = [0.0, 307.9455593123799, 684.7652291154752, 936.3089571815935]
>>> mults0 = [4, 1, 1, 4]
>>> periodic0 = False
>>> degree0 = 3
>>> rational0 = False
>>> bs0 = Part.BSplineCurve()
>>> bs0.buildFromPolesMultsKnots(poles0, mults0, knots0, periodic0, degree0, weights0, rational0)
>>> obj0 = FreeCAD.ActiveDocument.addObject("Part::Spline","BSplineCurve0")
>>> obj0.Shape = bs0.toShape()
>>>
Just an idea.
Regards
Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
Re: An
I start to have the feeling that thie geometry class is indeed quite complex and exporting it as a bytearray is a no-go.onekk wrote: ↑Thu Jan 27, 2022 5:58 pm Yes and No, Sketch is not only a bunch of geometries, so, you could have some difficulties to export it.
In Curves WB where you have a menu item that permit to past the code that is generating the Curve or the Surface in "Python Console".
Using it you will have this printed in "Python Console"
Something similar would be very useful to have even for generic Part objects, maybe for Sketch it will be more complicated, but, maybe with some work it could be done.
Just an idea.
Regards
Carlo D.
But the fact is that sketch geometries are not particularly complex. It should basically be a vector of geometries, including the different points coordinate.
So yes new plan:
- Export the geometry in text format (something formated similarly to the example you gave).
- copy the text to the clipboard.
- Import from text to geometry and constraint classes when ctrlV
It makes more work but it feels like it's going to be easier than running around trying to export the geometry class directly.
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
if you make thing using scripting, sketch is not the most immediate way, you could take care of constraints in code and use only Part and maybe Draft functions.
If you use vector math is not difficult to calculate "ending points" and similar things.
EDIT: sorry for mistyping, but on mobile it happens. (I've corrected post on PC)
Regards
Carlo D.
If you use vector math is not difficult to calculate "ending points" and similar things.
EDIT: sorry for mistyping, but on mobile it happens. (I've corrected post on PC)
Regards
Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.
Blog: https://okkmkblog.wordpress.com/
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
So I just started to work a bit on this again and copying to the clipboard is surprinsigly easy. I can easily copy the geoid of selected objects then print them anywhere.
Now I only need to format the string to something like :
Then work on the CtrlV part: create geometries from this string.
Should be pretty straight forward!
Do you have any comment regarding the format of the string? Maybe there's already something existing in FreeCAD which is similar? Maybe it could reuse some python format or something rather than this dumb format I used? (I never used python scripting with FreeCAD so consider my knowledge = 0 on that)
Now I only need to format the string to something like :
Code: Select all
Geometries:
{newGeoId = 0; GeoType = xx; p1(x,y);p2(x,y)... }
{newGeoId = 1; GeoType = xx; p1(x,y);p2(x,y)... }
Constraints:
{newCstrId = 0; CstrType = xx; First = x; FirstPos = x; Second = x; SecondPos = x; Third = x; ThirdPos = x}
{newCstrId = 0; CstrType = xx; First = x; FirstPos = x; Second = x; SecondPos = x; Third = x; ThirdPos = x}
Should be pretty straight forward!
Do you have any comment regarding the format of the string? Maybe there's already something existing in FreeCAD which is similar? Maybe it could reuse some python format or something rather than this dumb format I used? (I never used python scripting with FreeCAD so consider my knowledge = 0 on that)
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
I found that there are
functions which are doing just what I need : exporting the geometries and constraints as xml formated string.
The thing is that the string is put in a Writer &writer object that I'm having trouble dealing with.
I'm trying to make an new instance of that writer class in order to use the existing save functions. Though I can't get it to work.
Any idea how to do it properly?
Code: Select all
Save (Writer &writer)
Restore(XMLReader &reader)
The thing is that the string is put in a Writer &writer object that I'm having trouble dealing with.
I'm trying to make an new instance of that writer class in order to use the existing save functions. Though I can't get it to work.
Code: Select all
std::stringstream stream;
Base::Writer *writer;
const std::vector< Sketcher::Constraint* >& vals = Obj->Constraints.getValues();
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin(); it != vals.end(); ++it) {
(*it)->Save(*writer);
}
stream << writer->Stream().rdbuf();
//Copy to clipboard
QClipboard* clipboard = QGuiApplication::clipboard();
clipboard->setText(QString::fromStdString(stream.str()));
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
Ok we haev to use StringWriter class :
Working as expected now.
Code: Select all
Base::StringWriter writer;
const std::vector< Sketcher::Constraint* >& vals = Obj->Constraints.getValues();
for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();
it != vals.end(); ++it) {
for (int i = 0; i < listOfGeoId.size(); i++) {
if ( (*it)->First == listOfGeoId[i] || (*it)->Second == listOfGeoId[i] || (*it)->Third == listOfGeoId[i] ) {
(*it)->Save(writer);
}
}
}
//Copy to clipboard
QClipboard* clipboard = QGuiApplication::clipboard();
clipboard->setText(QString::fromStdString(writer.getString()));
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
Re: [Feature idea] Sketcher Ctrl-C ctrl-V between projects
So using the existing save and restore functions, we can do what I planed to do.
Now the only thing is that construction lines are copied as normal lines.
Somehow my restore is failing to restore the geometryModeFlags parameter which set lines as construction.
Other than that this feature will benefit a lot when group dragging will be implemented (which is currently pending review/debugging).
Now the only thing is that construction lines are copied as normal lines.
Somehow my restore is failing to restore the geometryModeFlags parameter which set lines as construction.
Code: Select all
<GeoExtensions count="1">
<GeoExtension type="Sketcher::SketchGeometryExtension" internalGeometryType="0" geometryModeFlags="00000000000000000000000000000010" geometryLayer="0"/>
</GeoExtensions>
Support me on Patreon: https://www.patreon.com/FreeCadDevDiary
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA
FreeCad Dev Diary channel:[/b] https://www.youtube.com/channel/UCGMTmJ ... NiPSSEhBHA