[Suggestion] Copy/Paste objects in Model tree

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
paddle
Veteran
Posts: 1391
Joined: Mon Feb 03, 2020 4:47 pm

[Suggestion] Copy/Paste objects in Model tree

Post by paddle »

I think the current copy paste of sketches (and other objects) in the tree is not as easy as it could be.
I remember it got me frustrated more than once when trying to copy paste sketches.

I just tried again this morning. I do :
- make a body
- make a basic sketch
- exit edit mode
- right click and copy (or ctrlC)
- A window open asking me about dependencies and if I want to copy or not XY_plane (which is super confusing)
- Right click on the current body, or on the current sketch (both do the same)
- The sketch created is not on the active body but outside.

Then I found out that I can drag the new sketch inside the currrent body, then the sketch is in the body.

And this is in the simplest 'hello world' scenario. If the sketch is not on a XYZ plane then you get a bigger dependencies tree with all objects on which the sketch relies. With complex projects it becomes quickly a real pain.

To get back to the 'hello world' scenario where the sketch is on a simple XY plane. Should I copy the XY_plane? Or not? The user just want to copy paste the sketch one doesn't know what to do.

Behaviour suggestion :
- right click the sketch and copy (or ctrlC)
- Nothing happens. (No dependency window shows up)
- Right click on one body or another, paste (or ctrlV) :
- Copy the sketch inside that body at the end of the body's elements.
___A - If the sketch was on XY YZ ZX planes, use the body's plane automatically.
___B - If the sketch was on one face of the selected body, use that face.
___C - If the sketch was on one face of another body: Open a dialog to offer user 3 possibilities :
______a - Paste the sketch on a newly created plane with same equation as where it was in its original body.
______b - Paste the sketch on XY plane (and user will re-map the sketch where he wants it.)
______c - Select dependencies : Open the 'Select object' dialog which currently opens at step 2.

Suggestion 2 :
Be able to paste the sketch where we want in the body's element. I mean not necesarilly at the end.
Usecase : You created a pad. Then you drafted some faces of the pad. Then you realise you need another pad and that its faces will need to be drafted too.
Currently I don't think you can insert a new sketch after the first pad, use the pad tool on this sketch, then modify your draft to add the new faces.

Currenly you have to delete the draft, make the pad, then make a new draft. Or alternatively create a second draft.
Last edited by paddle on Thu Jul 21, 2022 6:57 am, edited 2 times in total.
User avatar
paddle
Veteran
Posts: 1391
Joined: Mon Feb 03, 2020 4:47 pm

Re: [Suggestion] Copy/Paste objects in Model tree

Post by paddle »

So I started to have a look at it this afternoon.
And the situation seem to require an extra thought. I think I'll probably wrap up my feature ideas on the sketcher first before moving to this one.
So here's a summary of my search for later reference.

Currently 'copy' 'paste' and 'duplicate selected object' (as well as redo, undo and others) are defined in the file CommandDoc.cpp

Code: Select all

StdCmdCopy::StdCmdCopy()
StdCmdPaste::StdCmdPaste()
StdCmdDuplicateSelection::StdCmdDuplicateSelection()
First thing I noticed is that StdCmdDuplicateSelection is actually very close to copy + paste. I'm unsure of why it exist altogether.

About StdCmdCopy, basically it get the objects to copy in a ByteArray form and copy it to the clipboard (as mimedata, not xml text).
To get the objects formated in a ByteArray it calls getMainWindow()->createMimeDataFromSelection() which is a function in MainWindow.cpp.

What this function does is that it passes the selected objects to DlgObjectSelection (DlgObjectSelection.cpp) which is the 'Select Object' dialog box that opens when you copy something and prompts you to select the dependencies you want to copy.

Then createMimeDataFromSelection() use the update selection and export those with App::Document exportObjects function which returns it as a ostring (the selected objects formated as XML I guess?). Then createMimeDataFromSelection() turns that data into a ByteArray and returns it.

I have not looked into the paste function, but I guess it just append the objects in the bytearray to the current root object whatever the objects.

One thing positive about this approach is that it's cross-instance of FreeCAD, meaning you can copy the data from one freeCad, close it, open it again and paste the data. Also it's a bit dumb because it appends the object whatever it is to the end. So I guess it works with whatever object. But in a slightly dumb way.
zackw
Posts: 16
Joined: Sun May 01, 2022 12:11 pm

Re: [Suggestion] Copy/Paste objects in Model tree

Post by zackw »

Thanks for the overview that you already provided, I'm trying to go through and figure out a solution to making copy/paste work a little better. I compiled the documentation myself to get the graphs of everything, and I've been writing down notes and my own graphs in a document hosted by diagrams.net.

First off, if anyone knows of a way to work with the clipboard in Python, that would be super handy for testing :) . I haven't figured out a way to do something akin to insertFromMimeData() in python, for example. That means I either have to make python bindings for the clipboard stuff (might be useful, but it's probably redundant), or I have to do everything in C++.

For the basic copy-paste-into functionality, there needs to be a "supported" list of parents and children. This gets interesting pretty quick, since the core command .cpp files don't include things like the sketcher and part design classes by default. And I don't think they should. As such, I'm not sure where to put the copy/paste code. On one hand, it's pretty core to the program, on the other hand it should be extensible by all the modules. I don't understand enough about the program for the answer to be obvious. If the DocumentObject class simply supported something like addObject() that might be enough.

Other things besides sketches that should support paste-into functionality
  • Shape binders
  • Draft objects, text is a common one for me
  • Parts
  • Bodies
  • Groups
  • Objects in other open documents
  • Assemblies?
Other possible features:
  • Copying a Face creates either an independent face when pasted, or a datum plane (prompt user?) (or a shape binder?)
  • Paste-into-multiple, basically just paste a copy into each thing selected.
  • There's a lot of potential feature creep here, but I think that just means whatever system is created should be modular and easily extended. Imagine it automatically handling operations like pasting into a feature (like a pocket/pad), etc.
If, based on some of the requirements here, someone more experienced than myself wanted to suggest where to put the copy/paste code, that'd be much appreciated :D

I will probably have to find something a bit easier to swallow in addition to this, reading code and documentation and the wiki and tracing links and trying to understand complicated features and trying to hold all of it in your head gets tiring real fast :D
User avatar
paddle
Veteran
Posts: 1391
Joined: Mon Feb 03, 2020 4:47 pm

Re: [Suggestion] Copy/Paste objects in Model tree

Post by paddle »

zackw wrote: Fri Jul 29, 2022 9:35 pm First off, if anyone knows of a way to work with the clipboard in Python, that would be super handy for testing :) . I haven't figured out a way to do something akin to insertFromMimeData() in python, for example. That means I either have to make python bindings for the clipboard stuff (might be useful, but it's probably redundant), or I have to do everything in C++.
Why do you want to do things in python? I think setting up things will be as hard as developping the thing in c++ in itself. So I would suggest doing it directly in C++. Compilation is not that slow. Though I say that but I only make things on sketcher, so compilation is fast, but maybe on something general it would require a total rebuild everytime. In which case I understand why python could be interesting.
zackw wrote: Fri Jul 29, 2022 9:35 pm Other possible features:
  • Copying a Face creates either an independent face when pasted, or a datum plane (prompt user?) (or a shape binder?)
That's a great idea.
zackw wrote: Fri Jul 29, 2022 9:35 pm If, based on some of the requirements here, someone more experienced than myself wanted to suggest where to put the copy/paste code, that'd be much appreciated :D
We had such discussion about the copy paste function in sketcher when I made the PR : https://github.com/FreeCAD/FreeCAD/pull/5480 you might find some information in here.
Also I think regarding architecture @wmayer and @openBrain should have the answer.
zackw wrote: Fri Jul 29, 2022 9:35 pm I will probably have to find something a bit easier to swallow in addition to this, reading code and documentation and the wiki and tracing links and trying to understand complicated features and trying to hold all of it in your head gets tiring real fast :D
I totally get it! It can be frustrating very fast. Though keeping trying is the way to success :)
chrisb
Veteran
Posts: 53919
Joined: Tue Mar 17, 2015 9:14 am

Re: [Suggestion] Copy/Paste objects in Model tree

Post by chrisb »

paddle wrote: Wed Feb 02, 2022 6:05 pm First thing I noticed is that StdCmdDuplicateSelection is actually very close to copy + paste. I'm unsure of why it exist altogether.
This keeps a copied sketch inside of a body. Alas, it still opens the fancy copy dialog and if used with the defaults it copies erroneously the attachment plane as well as described above.
It doesn't keep objects inside of Part containers.

I would like to see two copy commands too, but make them work differently:
1) a basic copy command, copying just the selected object and keeping it inside of the source's container (Body, Part, Group)
2) the full deep copy which we have now which requires additional work if not everything is copied.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
wmayer
Founder
Posts: 20241
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: [Suggestion] Copy/Paste objects in Model tree

Post by wmayer »

Qt has implemented a powerful clipboard that's also accessible via Python (PySide2):

Code: Select all

from PySide2 import QtWidgets

cb = QtWidgets.QApplication.clipboard()
cb.mimeData()
openBrain
Veteran
Posts: 9034
Joined: Fri Nov 09, 2018 5:38 pm
Contact:

Re: [Suggestion] Copy/Paste objects in Model tree

Post by openBrain »

paddle wrote: Sat Jul 30, 2022 5:43 am
zackw wrote: Fri Jul 29, 2022 9:35 pm If, based on some of the requirements here, someone more experienced than myself wanted to suggest where to put the copy/paste code, that'd be much appreciated :D
We had such discussion about the copy paste function in sketcher when I made the PR : https://github.com/FreeCAD/FreeCAD/pull/5480 you might find some information in here.
Also I think regarding architecture @wmayer and @openBrain should have the answer.
@wmayer widely commented the PR you pointed out. I think he said everything about where things should go there. ;)
zackw wrote: Fri Jul 29, 2022 9:35 pm I will probably have to find something a bit easier to swallow in addition to this, reading code and documentation and the wiki and tracing links and trying to understand complicated features and trying to hold all of it in your head gets tiring real fast :D
I totally get it! It can be frustrating very fast. Though keeping trying is the way to success :)
A good IDE that eases navigating through code is priceless. ;)
zackw
Posts: 16
Joined: Sun May 01, 2022 12:11 pm

Re: [Suggestion] Copy/Paste objects in Model tree

Post by zackw »

Thanks all for the input!
@paddle sometimes it's just easier to throw something in Python and poke/tweak it a bit. I've got C++ set up, and yeah compilation isn't that bad, but yeah for me sometimes I just want to use Python. I had actually read through that pull request once before, but thanks for linking it and I think there is some good stuff here. I might have an inkling of a setup coming together in my head, gonna muse on it a bit more. Thank you @wmayer for the python clipboard note, I'll look into that!

@chrisb I'm honestly not sure what you mean by the two copy commands? (1) wouldn't require pasting? (2) is just what we have now but with some fixes?

@openBrain I've got an IDE setup :D It's pretty crazy how much RAM you can use up in a few seconds while searching through such a large codebase :lol:
chrisb
Veteran
Posts: 53919
Joined: Tue Mar 17, 2015 9:14 am

Re: [Suggestion] Copy/Paste objects in Model tree

Post by chrisb »

zackw wrote: Mon Aug 01, 2022 9:35 am @chrisb I'm honestly not sure what you mean by the two copy commands? (1) wouldn't require pasting? (2) is just what we have now but with some fixes?
Menu->Edit has a Copy command and a "Duplicate selection". The latter doesn't need pasting.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
zackw
Posts: 16
Joined: Sun May 01, 2022 12:11 pm

Re: [Suggestion] Copy/Paste objects in Model tree

Post by zackw »

Alright so I've been poking around some more. Still have yet to write any meaningful amount of code, since it seems like every corner I go around reveals a larger problem. It seems to me like the two obvious approaches to a extensible Copy/Paste system is to either use some kind of Command overloading, or to implement a new module in charge of the clipboard in general. I'm leaning towards a new module, but wondering if I'm missing anything?

The basic functionality for the paste Command(s) requires awareness of what kind of object that's being selected, and what kind of object is in the clipboard. As I understand, the Core of FreeCAD can't discern after a certain point what kind of object something is, like telling whether or not something is a sketch or a body. It looks like you have to include the module in order to do that.

The other issue is that the current dependency selector also seems to be built into the core, and therefore also is unaware of what kind objects you are clicking on. As far as I know, this means it's impossible to smartly determine what kind of thing should be automatically selected, and what should not. This may be moved into a new module, but including this functionality might warrant a different name. (Selection module?)

There's also @paddle's code for copying sketch geometry, and it makes sense to me for something like that to be included in this module as well. Actually, other similar things could be included as well. I haven't used these workbenches much, but maybe something similar to paddle's system is also needed for the drawing creation workbench or arch workbench.

@wmayer it seems like you are pretty knowledgeable on this kind of thing, any thoughts? Any reason why a new "Clipboard" GUI-only module would be a bad approach? Do you know of any way that the core could provide a "default" Command that modules could overload/replace?

I have some more thoughts and notes on my learning and decision process in this blog post. I post here of course since a new module is a bigger task than just modifying or creating a command or two, and should probably involve more experienced people than myself :D
Post Reply