2021-04-21 18:02:20 +02:00
#!/usr/bin/env python3
import inkex
import subprocess
import shutil
import os
import sys
2021-05-07 22:39:01 +02:00
import warnings
2021-05-08 22:22:29 +02:00
import shlex
2021-04-21 18:02:20 +02:00
"""
Extension for InkScape 1. X
Features
- Create SVG preview file and show it in browser . Helps to quickly evaluate line order for cutting processes
Author : Mario Voigt / FabLab Chemnitz
Mail : mario . voigt @stadtfabrikanten.org
Date : 21.04 .2021
2021-05-07 22:39:01 +02:00
Last patch : 07.05 .2021
2021-04-21 18:02:20 +02:00
License : GNU GPL v3
Used version of Vivus JS library : https : / / github . com / maxwellito / vivus / releases / tag / v0 .4 .6 - MIT License
Browser config :
Firefox via about : config - > privacy . file_unique_origin = false
ToDo :
- adjust width and height ( give options )
- embed config buttons inside html to adjust time / type / . . . ( more flexible than clicking from Inkscape )
2021-04-22 17:10:06 +02:00
- we should do it the way like vivus instant - > http : / / maxwellito . github . io / vivus / https : / / maxwellito . github . io / vivus - instant
- the generated SVGs can be downloaded again and include all animations !
2021-04-21 18:02:20 +02:00
- calculate the total length of all paths and auto - adjust the speed to have good visibility
2021-05-07 22:56:36 +02:00
- Possible feature request could be to handle " animate selected objects only " . See " Export selection as ... " extension to steal that code .
2021-04-21 18:02:20 +02:00
"""
2021-05-07 22:39:01 +02:00
DETACHED_PROCESS = 0x00000008
2021-04-21 18:02:20 +02:00
class AnimateOrder ( inkex . EffectExtension ) :
2021-05-07 22:39:01 +02:00
def spawnIndependentProcess ( self , args ) : #function to spawn non-blocking inkscape instance. the inkscape command is available because it is added to ENVIRONMENT when Inkscape main instance is started
2021-05-08 22:22:29 +02:00
warnings . simplefilter ( ' ignore ' , ResourceWarning ) #suppress "enable tracemalloc to get the object allocation traceback"
2021-05-07 22:39:01 +02:00
if os . name == ' nt ' :
subprocess . Popen ( args , close_fds = True , creationflags = DETACHED_PROCESS )
else :
2021-05-08 22:22:29 +02:00
cmd = " nohup " + " " . join ( args ) + " & "
cmds = shlex . split ( cmd )
subprocess . Popen ( cmds , start_new_session = True , stdout = subprocess . DEVNULL , stderr = subprocess . DEVNULL )
warnings . simplefilter ( " default " , ResourceWarning )
2021-05-07 22:39:01 +02:00
2021-04-21 18:02:20 +02:00
def add_arguments ( self , pars ) :
pars . add_argument ( " --tab " )
2021-04-21 19:01:27 +02:00
pars . add_argument ( " --time " , type = float , default = 5.0 , help = " Duration (frames) " )
2021-04-21 18:02:20 +02:00
pars . add_argument ( " --fps " , type = int , default = 60.0 , help = " Frames per second (fps) " )
pars . add_argument ( " --sequence_type " , help = " Sequence type " )
pars . add_argument ( " --reverse " , type = inkex . Boolean , default = False , help = " Reverse order " )
pars . add_argument ( " --browser " , help = " Select your desired browser (must be installed and must exist in % PATH % variable). " )
def effect ( self ) :
#write current SVG to extensions' directory. Target name must be "drawing.svg" because it is embedded in animate_order.html statically
inFile = " drawing.svg "
extension_dir = os . path . dirname ( os . path . realpath ( __file__ ) )
shutil . copy2 ( self . options . input_file , os . path . join ( extension_dir , inFile ) )
target_html = os . path . join ( extension_dir , " animate_order.html " )
2021-05-18 12:53:43 +02:00
if os . path . exists ( target_html ) is False :
inkex . utils . debug ( " Error. Target file does not exist! " )
exit ( 1 )
2021-05-07 22:39:01 +02:00
docTitle = self . document . getroot ( ) . get ( " { http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}docname " )
if docTitle is None :
2021-04-21 18:02:20 +02:00
title = " Animate Order - Vivus JS "
2021-05-07 22:39:01 +02:00
else :
title = " Animate Order - " + docTitle
2021-04-21 18:02:20 +02:00
vivus_include = " ./vivus-0.4.6/dist/vivus.js "
duration = self . options . time * self . options . fps # we guess we have 20 ... 60 fps. depends on performance of the machine
frames_per_second = self . options . fps
type = self . options . sequence_type
reverse = str ( self . options . reverse ) . lower ( )
with open ( target_html , " w " ) as text_file :
print ( ' <html> ' , file = text_file )
print ( ' <head> ' , file = text_file )
print ( ' <meta charset= " UTF-8 " > ' , file = text_file )
print ( ' <meta http-equiv= " X-UA-Compatible " content= " IE=edge,chrome=1 " > ' , file = text_file )
print ( ' <meta name= " viewport " content= " width=device-width, initial-scale=1.0 " > ' , file = text_file )
print ( f ' <title> { title } </title> ' , file = text_file )
print ( ' <meta name= " description " content= " SVG Drawing Animation " > ' , file = text_file )
print ( ' </head> ' , file = text_file )
print ( ' <body> ' , file = text_file )
print ( ' <button onclick= " vi.reset().play(); " >replay</button> ' , file = text_file )
print ( ' <br/> ' , file = text_file )
print ( f ' <object id= " animate_order " type= " image/svg+xml " data= " { inFile } " ></object> ' , file = text_file )
print ( f ' <script src= " { vivus_include } " ></script> ' , file = text_file )
print ( ' <script> ' , file = text_file )
print ( " var vi = new Vivus( ' animate_order ' , { type: ' " + f ' { type } ' + " ' , \
duration : " + f ' {duration} ' + " , reverseStack : " + f ' {reverse} ' + " } ) ; " , file=text_file)
print ( ' </script> ' , file = text_file )
print ( ' </body> ' , file = text_file )
print ( ' </html> ' , file = text_file )
#now open firefox
args = [ self . options . browser , target_html ]
2021-05-18 12:53:43 +02:00
try :
self . spawnIndependentProcess ( args )
except FileNotFoundError as e :
inkex . utils . debug ( " Error. Check for correct browser installation and try again! " )
exit ( 1 )
2021-05-07 22:39:01 +02:00
2021-04-21 18:02:20 +02:00
if __name__ == ' __main__ ' :
AnimateOrder ( ) . run ( )