[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: 1392
Joined: Mon Feb 03, 2020 4:47 pm

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

Post by paddle »

@zackw Thanks for your work on this !
Is it not possible to simply modify the current StdCmdPaste and/or StdCmdCopy commands by adding if statements which would trigger different actions based on selection?

@wmayer it would be great to have your feedback on this before he codes something that will be deemed 'unaceptable architecture'.
zackw
Posts: 16
Joined: Sun May 01, 2022 12:11 pm

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

Post by zackw »

@paddle As far as I can tell, I'd have to include module files into the CommandDoc.cpp file. Like, the selection handles things as "DocumentObject"s, which is one of the base classes for like everything. I might be missing something here, and it is indeed possible to check what kind of thing is selected without including the sketcher/part class, but I haven't figured out how yet if so. Could patch in like a string id onto the classes of interest, but that seems... painful. The Command.cpp file in PartDesign Gui contains a good example of checking whether or not a document object is an instance of a body, line 931. As far as I know, it has to be done this way, using isDerivedFrom() and getClassTypeId().

Luckily there are some more helpful functions once you have figured out your selection. I plan on using 'PartDesign::Body's addObject() function for instance. I think there might be a moveObject() function hiding somewhere too, but it's not undo/redo safe.

I could also just move the copy/paste commands into a different module, like PartDesign, and that should work. That feels a bit messy to me however, since eventually the clipboard functionality could be pretty complex.
User avatar
paddle
Veteran
Posts: 1392
Joined: Mon Feb 03, 2020 4:47 pm

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

Post by paddle »

zackw wrote: Fri Aug 19, 2022 9:26 pm @paddle As far as I can tell, I'd have to include module files into the CommandDoc.cpp file.
Oh yes I see, that's actually what wmayer told me in my PR.

Here's what he said btw :
You cannot and you mustn't . The design is that the core provides the basic infrastructure but it's up to the extension modules to do then the actual work. The core is not interested in what exactly an extension modules does and how it does it.

As a consequence you are not allowed to implicitly or explicitly add a dependency of an extension module to the core system. In this case it would not even work technically because SketcherGui links FreeCADGui and now you can't make FreeCADGui to also depend on SketcherGui as this would be a cyclic dependency and thus impossible to build the libraries.

Please keep in mind: everybody is free to use the core system and e.g. implements his own Sketcher extension module. When doing so the core must behave the same independent on how the extension module is implemented but this wouldn't be possible if you added a dependency.

If you want to do something in an extension module but the core doesn't provide the basics then the way to go is to add a virtual function to a class in the core (here ViewProviderDocumentObject) and override this function in the class of the module (here ViewProviderSketch).
So if I understand correctly, here what we should do :
Have the StdCmdPaste and/or StdCmdCopy commands call functions that are in ViewProviderDocumentObject. Declare those functions as virtual. Then reimplement them in the different modules.

Edit: That would work to copy paste geometries in the sketch (the PR that I did) but that wouldn't help your project of copy/paste objects in model tree. As you can want to copy paste a sketch even when you are not using sketcher.

The core must be able to get the object type so that it can act differently depending on type. Can't we read the type of the object from the mime data? It should be possible as the model tree show different icons for different objects.
wmayer
Founder
Posts: 20243
Joined: Thu Feb 19, 2009 10:32 am
Contact:

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

Post by wmayer »

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?
Not sure what you plan but keep in mind that the clipboard is a mechanism across applications. This means if you copy something in one FreeCAD application it must be pastable in a second FreeCAD instance.
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.
In the clipboard there is not an object (e.g. a reference to a sketch object) but the serialization of the object. This is an important difference.
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.
It's because the core system defines the interfaces and the modules implement them. For the core system it's totally irrelevant of what exact type an object is. This is the basic architecture of FreeCAD to make it easily extendable.
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.
Not sure what you are after but again there is no need that the core had to know of what type a selected object is. If you need something like this then the way to go is to add a virtual method to the base class in the core and re-implement this method in the sub-class of the module.
it would be great to have your feedback on this before he codes something that will be deemed 'unaceptable architecture'.
As I've already said in one of the issues/PRs a specialized Copy/Paste for certain object types that works differently to the current mechanism should be implemented as separate commands.
As far as I can tell, I'd have to include module files into the CommandDoc.cpp file.
This would neither be accepted because it breaks the basic architecture nor will it work technically because it leads to circular dependencies. Again there is no alternative than splitting the implementations from the interfaces.
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 reply @wmayer ! Really appreciate the input. To be clear, the clipboard should still work across applications and should generally function just about the same as copy/paste worked before. Sorry about the huge wall of text, I try and keep exposition like this on my blog for my own reference. Hopefully you (wmayer) and other people (thanks @paddle :D! ) can find time once in a while to pick through and guide me a bit when convenient.

Again, paste-into is like so:
- Copy just a sketch
- Select a compatible object in the model tree view
- Paste
- Object automatically placed under selection in model view
- No need to activate anything new.
In the clipboard there is not an object (e.g. a reference to a sketch object) but the serialization of the object. This is an important difference.
Yep yep, I was thinking about some way to interpret the serialized object in the clipboard, but detecting what is in the clipboard is not as important as the rest of the functionality. I will probably start by fully de-serializing the object and then figuring out what it is (been a while since I looked at that code)

I'm totally keeping in the spirit of the core of FreeCAD, moving the copy/paste code into a module seems like the way to go. I was aware that circular dependencies weren't gonna work :D and have been basically trying to decide whether a new module, or some kind of virtual method/overload would be the way to go. Like I said though, module seems logical. I'm going to try and implement the basics doing the best I can, then demonstrate the changes and let people pick apart the code and the new functionality :D

I'm planning on keeping with just the two commands, but the "Paste" command will be greatly more complicated.
As I've already said in one of the issues/PRs a specialized Copy/Paste for certain object types that works differently to the current mechanism should be implemented as separate commands.
This would result in an interesting hierarchy of commands, since the current Paste command would be responsible for checking conditions and using different commands as appropriate. I haven't seen a command call a different command yet, is that normal?

Once the basic copy/paste commands are moved to the clipboard module, I will implement a draft of the "paste-into" stuff. But, the other high priority thing to me is the selection dialog (DlgObjectSelection). There are a few cases in which I feel like this could be smarter, automatically assuming you want to copy every dependency isn't optimal. For example, automatically selecting spreadsheets isn't ideal; and there could be an argument made that automatically selecting origin axis' isn't great either. I sort of want to experiment with making the dialog optional for certain selections, too. Copying a sketch into the same body rarely needs any additional sorting.

In the same vein, prompting to create new objects should probably also be put in the same place as the selection dialog.
A simple example of wanting new reference objects:
- Make a sketch referenced to a body's face
- Copy that sketch
- Selection dialog appears and asks if you want to create a datum plane instead of copying the body and it's face
- Sketch can now be easily pasted anywhere, including into a different body

If I move the DlgObjectSelection into the Clipboard module, I should probably change the name to something more fitting. Selection module perhaps? Not sure. Just FYI, I do try and read as many relevant PRs, commits, and forum posts as I can to gain some context on all this :) doing my best to catch up on years development on just the code related to what I'm working on :lol:.
Post Reply