Hello, I would like to use Inkscape to draw animation frames. I have set up every frame as a separate layer. Now I'd like to be able to "flip" between layers for quickly checking the animation.
This means that there would be an "up" key which makes the next layer active and visible and all others invisible, and a "down" key which makes the previous layer active and visible and all others invisible.
My best bet was that I could change the active layer and visibility in a Python script with the attributes inkscape:current-layer="layerX" and style="display:none". Would that work? How could I trigger a script with a single keystroke?
And would it be an efficient way of implementing this? On Aaron Spike's site it said that the entire SVG is written to a file when it's passed to Python. However, I'd need to flip frames back and forth every second if I want to check the animation. Also, does Inkscape parse and reconstruct the entire document when Python has changed something, or is something like a diff applied?
Are there other easy ways of implementing this flipping in the C++ code?
Any inputs on this will be appreciated Gerrit
_________________________________________________________________ Don't just search. Find. Check out the new MSN Search! http://search.msn.com/
On Sun, 2007-05-06 at 08:44 +0000, Gerrit . wrote:
Hello, I would like to use Inkscape to draw animation frames. I have set up every frame as a separate layer. Now I'd like to be able to "flip" between layers for quickly checking the animation.
Interesting.
This means that there would be an "up" key which makes the next layer active and visible and all others invisible, and a "down" key which makes the previous layer active and visible and all others invisible.
This might be possible from the technical perspective, but I don't think that "up" and "down" are good keys for it.
My best bet was that I could change the active layer and visibility in a Python script with the attributes inkscape:current-layer="layerX" and style="display:none". Would that work? How could I trigger a script with a single keystroke?
All Effects can be set to keystrokes, the same as any other key mapping as all effects have Verb IDs. So, when you define a script as an effect you can add it to your keymap directly.
And would it be an efficient way of implementing this? On Aaron Spike's site it said that the entire SVG is written to a file when it's passed to Python. However, I'd need to flip frames back and forth every second if I want to check the animation. Also, does Inkscape parse and reconstruct the entire document when Python has changed something, or is something like a diff applied?
Unfortunately it is pretty much a full replacement today. Plus with serializing everything into files, it really isn't high performance. I'm not saying it's impossible with enough hardware, but I don't think using a script will work for you today.
Are there other easy ways of implementing this flipping in the C++ code?
Any inputs on this will be appreciated
Yes, there are a class of effects called "internal" effects. Basically they are effects that are compiled in, but use the effects interfaces. You just need to subclass the Inkscape::Extension::Implementation::Implementation object and implement the functions you're interested in (probably effect). You should look at blur and grid for examples.
I'd be happy to help with more questions as you get to them.
--Ted
On Sun, May 06, 2007 at 07:33:29AM -0700, Ted Gould wrote:
This means that there would be an "up" key which makes the next layer active and visible and all others invisible, and a "down" key which makes the previous layer active and visible and all others invisible.
This might be possible from the technical perspective, but I don't think that "up" and "down" are good keys for it.
"left" "right" maybe?
And would it be an efficient way of implementing this? On Aaron Spike's site it said that the entire SVG is written to a file when it's passed to Python. However, I'd need to flip frames back and forth every second if I want to check the animation. Also, does Inkscape parse and reconstruct the entire document when Python has changed something, or is something like a diff applied?
Unfortunately it is pretty much a full replacement today. Plus with serializing everything into files, it really isn't high performance. I'm not saying it's impossible with enough hardware, but I don't think using a script will work for you today.
This approach might be interesting for a proof of concept, but this really sounds like something more geared for the DOM-based embedded scripting approach.
Bryce
On Sun, 2007-05-06 at 08:23 -0700, Bryce Harrington wrote:
On Sun, May 06, 2007 at 07:33:29AM -0700, Ted Gould wrote:
This means that there would be an "up" key which makes the next layer active and visible and all others invisible, and a "down" key which makes the previous layer active and visible and all others invisible.
This might be possible from the technical perspective, but I don't think that "up" and "down" are good keys for it.
"left" "right" maybe?
I was thinking that "up" and "down" are pretty overloaded already -- infact all the arrow keys are. So something like "o" and "p" might work better, or something with a modifier. I think we're going to have to start requiring second keyboards ;)
Unfortunately it is pretty much a full replacement today. Plus with serializing everything into files, it really isn't high performance. I'm not saying it's impossible with enough hardware, but I don't think using a script will work for you today.
This approach might be interesting for a proof of concept, but this really sounds like something more geared for the DOM-based embedded scripting approach.
Yes, but C++ works too. :) Implementing an effect in C++ is also pretty easy (if you know C++) as the interface is already well defined. I hope that we can get loadable C++ extensions working someday also.
--Ted
From: Ted Gould <ted@...11...> To: Bryce Harrington <bryce@...961...> CC: "Gerrit ." <g99k@...19...>, inkscape-devel@lists.sourceforge.net Subject: Re: [Inkscape-devel] How to implement layer flipping Date: Mon, 07 May 2007 10:40:46 -0700
On Sun, 2007-05-06 at 08:23 -0700, Bryce Harrington wrote:
On Sun, May 06, 2007 at 07:33:29AM -0700, Ted Gould wrote:
This means that there would be an "up" key which makes the next
layer active
and visible and all others invisible, and a "down" key which makes
the
previous layer active and visible and all others invisible.
This might be possible from the technical perspective, but I don't
think
that "up" and "down" are good keys for it.
"left" "right" maybe?
I was thinking that "up" and "down" are pretty overloaded already -- infact all the arrow keys are. So something like "o" and "p" might work better, or something with a modifier. I think we're going to have to start requiring second keyboards ;)
Unfortunately it is pretty much a full replacement today. Plus with serializing everything into files, it really isn't high performance. I'm not saying it's impossible with enough hardware, but I don't think using a script will work for you today.
This approach might be interesting for a proof of concept, but this really sounds like something more geared for the DOM-based embedded scripting approach.
Yes, but C++ works too. :) Implementing an effect in C++ is also pretty easy (if you know C++) as the interface is already well defined. I hope that we can get loadable C++ extensions working someday also.
--Ted
<< signature.asc >>
_________________________________________________________________ FREE pop-up blocking with the new MSN Toolbar - get it now! http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/
Ted, Bryce, thanks for your detailed response and your suggestions. Since you offered help further down the road, I'd now like to ask for your advice again.
I was thinking that "up" and "down" are pretty overloaded already -- infact all the arrow keys are. So something like "o" and "p" might work better, or something with a modifier. I think we're going to have to start requiring second keyboards ;)
Sorry for the misleading labeling, I really wasn't thinking of the arrow keys. The Flash IDE uses "," and ".", but of course any two keys next to each other would do the job.
Unfortunately it is pretty much a full replacement today. Plus with serializing everything into files, it really isn't high performance. I'm not saying it's impossible with enough hardware, but I don't think using a script will work for you today.
This approach might be interesting for a proof of concept, but this really sounds like something more geared for the DOM-based embedded scripting approach.
Yes, but C++ works too. :) Implementing an effect in C++ is also pretty easy (if you know C++) as the interface is already well defined. I hope that we can get loadable C++ extensions working someday also.
I am almost as inexperienced and uncomfortable with C++ as I am with Python, so I wouldn't mind using C++. :-)
You just need to subclass the Inkscape::Extension::Implementation::Implementation object and implement the functions you're interested in (probably effect). You should look at blur and grid for examples.
Alright, the effect method is passed an Inkscape::UI::View::View as a "document" parameter. How do I get the current active layer from here? In the docs, I found these two layer functions:
((SPDesktop*)document)->selection->activeContext() ((SPDesktop*)document)->currentLayer()
"currentLayer" looks better to me, but the Doxygen comment says it's actually the top layer???
And once I got the layer, how do I set it to visible/invisible? At first glance, the method SPItem::setExplicitlyHidden(bool const) looks like it'd do the job. Can I safely cast the SPObject pointers to SPItem? What is the actual class of the layer nodes?
Finally, how do I register the extension class and bind it to keystrokes? Is there an example?
Thanks a lot for your advice! Gerrit
_________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
On Tue, 2007-05-08 at 13:30 +0000, Gerrit . wrote:
Ted, Bryce, thanks for your detailed response and your suggestions. Since you offered help further down the road, I'd now like to ask for your advice again.
I think that goes for everyone on this list, yourself included. We like questions, it makes me feel important if my mailbox is full ;)
Finally, how do I register the extension class and bind it to keystrokes? Is there an example?
I'm going to answer this one, because I know the answer here, hopefully others will answer the layers one because I'm not as confident in those areas of the code.
You can edit the file in /share/keys/default.xml to change the keymap. Also, for testing, you can put a keys.xml in your ~/.inkscape directory and modify it there. Under "action" you should put the ID of your extension.
--Ted
Heya Mental,
Gerrit is working on a layer-flipping based animation feature - Ted and I gave a little advice, but perhaps you could addressg some of his questions relating to the layers code?
Thanks, Bryce
On Tue, May 08, 2007 at 01:30:58PM +0000, Gerrit . wrote:
You just need to subclass the Inkscape::Extension::Implementation::Implementation object and implement the functions you're interested in (probably effect). You should look at blur and grid for examples.
Alright, the effect method is passed an Inkscape::UI::View::View as a "document" parameter. How do I get the current active layer from here? In the docs, I found these two layer functions:
((SPDesktop*)document)->selection->activeContext() ((SPDesktop*)document)->currentLayer()
"currentLayer" looks better to me, but the Doxygen comment says it's actually the top layer???
And once I got the layer, how do I set it to visible/invisible? At first glance, the method SPItem::setExplicitlyHidden(bool const) looks like it'd do the job. Can I safely cast the SPObject pointers to SPItem? What is the actual class of the layer nodes?
Thanks a lot for your advice! Gerrit
currentLayer is the correct way to find the currently active layer for a view; layers are just SPItemGroups, which are SPItems themselves, so you should be able to use SPItem methods like setExplicitlyHidden.
For now, the proper way to downcast SPObject * to SPItem * is to use the SP_ITEM() macro -- be sure to test whether it returns NULL however (in the [unusual, but possible] case when the object was not an SPItem).
-mental
This weekend, I finally found the time to play a little with Inkscape and try out your suggestions. I got the layer flipping working, not yet as an extension however.
Here's what I did:
1. Added 2 actions to the key mappings in keys/default.xml
<bind key="l" action="LayerFlipToNext" display="true" />
<bind key="L" action="LayerFlipToNext" display="true" />
<bind key="k" action="LayerFlipToPrev" display="true" />
<bind key="K" action="LayerFlipToPrev" display="true" />
2. Added 2 verbs for these actions to Verb::_base_verbs[] in verbs.cpp, defined in verbs.h.
new LayerVerb(SP_VERB_LAYER_FLIP_TO_NEXT, "LayerFlipToNext", N_("_Flip to Next Layer"),
N_("Flip to the next layer."), "flip_next"),
new LayerVerb(SP_VERB_LAYER_FLIP_TO_PREV, "LayerFlipToPrev", N_("_Flip to Previous Layer"),
N_("Flip to the previous layer."), "flip_prev"),
3. Wrote 2 case blocks for the verbs.
case SP_VERB_LAYER_FLIP_TO_NEXT: {
SPItem* currentLayer = SP_ITEM(dt->currentLayer());
if( currentLayer && dt->isLayer( currentLayer ) ) {
SPItem* nextLayer = SP_ITEM( SP_OBJECT_NEXT(currentLayer) );
if( nextLayer && dt->isLayer( nextLayer ) ) {
currentLayer->setExplicitlyHidden(true);
nextLayer->setExplicitlyHidden(false);
dt->setCurrentLayer( nextLayer );
}
}
break;
}
case SP_VERB_LAYER_FLIP_TO_PREV: {
SPItem* currentLayer = SP_ITEM(dt->currentLayer());
if( currentLayer && dt->isLayer( currentLayer ) ) {
SPItem* prevLayer = SP_ITEM( SP_OBJECT_PREV(currentLayer) );
if( prevLayer && dt->isLayer( prevLayer ) ) {
currentLayer->setExplicitlyHidden(true);
prevLayer->setExplicitlyHidden(false);
dt->setCurrentLayer( prevLayer );
}
}
break;
}
This works, and so far it's all I need, but I'd still like to know how I would implement this as an extension. I didn't, because I couldn't figure out:
1. How to register extensions with keys. The verbs all seem to be mapped to internal functions.
2. How to call the extension's effect method. It's nonstatic, so I'd think need an object pointer somehow. Where can I fetch it?
For some reason, I couldn't find the corresponding code blocks for Grid or BlurEdge...
Also, I am still looking for some keys on the keyboard that are still available. "k" and "l" are maybe already used somewhere else. When I tried "," and "." (comma and period), it seemed they were already used by some stroke scaling effect, even though it was not specified in keys/default.xml. Does anyone know where these effects are specified or where I can find a full list of all keys?
Thanks for your help! Gerrit
_________________________________________________________________ Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
On 5/14/07, Gerrit . <g99k@...19...> wrote:
- How to register extensions with keys. The verbs all seem to be mapped to
internal functions.
To bind an extension to a key, you specify the extension's id from the inx file as the action in the keys binding
Also, I am still looking for some keys on the keyboard that are still available. "k" and "l" are maybe already used somewhere else. When I tried "," and "." (comma and period), it seemed they were already used by some stroke scaling effect,
Not stroke but object scaling
even though it was not specified in keys/default.xml.
Yes, some keys are not defined there because they are not verbs. We are gradually moving such stuff to new verbs, but it's far from done yet. If you can help with this it would be much appreciated.
Does anyone know where these effects are specified or where I can find a full list of all keys?
The complete list is in doc/keys.xml in the distribution or here:
http://inkscape.org/doc/keys.html
On Mon, 2007-05-14 at 22:20 +0000, Gerrit . wrote:
This weekend, I finally found the time to play a little with Inkscape and try out your suggestions. I got the layer flipping working, not yet as an extension however.
Cool, it's not crucial that it is an extension, though it's always nice.
Here's what I did:
- Added 2 actions to the key mappings in keys/default.xml
Looks good.
- Added 2 verbs for these actions to Verb::_base_verbs[] in verbs.cpp,
defined in verbs.h.
Looks good. I'm hoping you added entries to verbs.h also, but if it works, you probably did.
- Wrote 2 case blocks for the verbs.
Yup. Looks good.
This works, and so far it's all I need, but I'd still like to know how I would implement this as an extension. I didn't, because I couldn't figure out:
Okay, I'd like that too.
- How to register extensions with keys. The verbs all seem to be mapped to
internal functions.
Basically there are two types of verbs. The ones that you're looking at are all static verbs, they're created with fixed IDs mostly at compile time. There are also dynamic verbs that are created at run time, the extensions all fall into this category. There are actually a few other verbs that do this, but by and far, the majority are static. If you look at the two Verb constructors, you can see that one knows the code, and the other creates it -- those are the two categories.
- How to call the extension's effect method. It's nonstatic, so I'd think
need an object pointer somehow. Where can I fetch it?
The effect method gets called by the verb. Basically the verb that gets created is a subclass of the global Verb, called an EffectVerb. The effect verb calls the effect function. That's all taken care of, you just need to subclass Implementation.
For some reason, I couldn't find the corresponding code blocks for Grid or BlurEdge...
/src/extension/internal/grid.[cpp,h] /src/extension/internal/bluredge.[cpp,h]
You'll also need to modify:
/src/extension/internal/init.cpp
To add a line for initializing your extension. You can just search for "Internal::Grid::init()" and put it in that list. I'm working on cleaning this little messy-ness up, but haven't done so yet. (feel free if you'd like :) )
I think the biggest trick here is in that init function, basically this is where you're creating the extension. Don't forget the N_() on some of the strings, as that is how they get marked for translation.
--Ted
participants (5)
-
Bryce Harrington
-
bulia byak
-
Gerrit .
-
MenTaLguY
-
Ted Gould