diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74e3c2b..71ca392 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,12 @@ Activate / deactivate layer opacity according to prefix
Activate / deactivate all masks using MA layers
-->
+1.5.0
+
+- added: swf export (include binary for linux and windows)
+- added: pdf single multipage file exports
+
+
1.4.1
- added: expose button for output file de-numbering
diff --git a/OP_render_pdf.py b/OP_render_pdf.py
index 01704e2..53d39d3 100644
--- a/OP_render_pdf.py
+++ b/OP_render_pdf.py
@@ -1,4 +1,6 @@
import bpy
+import sys
+import subprocess
from . import fn
from pathlib import Path
from itertools import groupby
@@ -71,9 +73,36 @@ def export_all_selected_frame_as_svg():
print('Done')
-def pdf_render(fp):
+def pdf_render(fp, multi_page=False):
+ '''Render a sequence of pdf and return path to folder
+ or render a multipage pdf (in place of parent folder) and return path to file
+ '''
scn = bpy.context.scene
+
+ if multi_page:
+ ## Set folder name (when using sequence) as output with pdf extension
+ fp = fp.parent
+
fp.parent.mkdir(parents=True, exist_ok=True) # mode=0o777
+
+ if multi_page:
+ ## In case of sequence path:
+ ## Remove padding separator (or add scene range: "0100-0230" ?)
+ # fp = fp.with_stem(fp.stem.rstrip('-_. ')) # strip typical padding separator
+
+ fp = fp.with_suffix('.pdf')
+
+ # print('Exporting multi-page pdf at: ', fp)
+ bpy.ops.wm.gpencil_export_pdf(filepath=str(fp),
+ check_existing=False, # True by default
+ use_fill=True,
+ selected_object_type='ACTIVE', # VISIBLE, SELECTED
+ stroke_sample=0,
+ use_normalized_thickness=False,
+ frame_mode='SCENE')
+ return fp
+
+ ## Sequence
for fnum in range(scn.frame_start, scn.frame_end + 1):
# print('fnum: ', fnum)
scn.frame_current = fnum
@@ -92,6 +121,107 @@ def pdf_render(fp):
stroke_sample=0,
use_normalized_thickness=False,
frame_mode='ACTIVE')
+ return fp.parent
+
+def swf_render(fp):
+ '''
+ Render as pdf then convert to swf using pdf2swf
+
+ -h , --help Print short help message and exit
+ -V , --version Print version info and exit
+ -o , --output file.swf Direct output to file.swf. If file.swf contains '%' (file%.swf), then each page goes to a separate file.
+ -p , --pages range Convert only pages in range with range e.g. 1-20 or 1,4,6,9-11 or
+ -P , --password password Use password for deciphering the pdf.
+ -v , --verbose Be verbose. Use more than one -v for greater effect.
+ -z , --zlib Use Flash 6 (MX) zlib compression.
+ -i , --ignore Allows pdf2swf to change the draw order of the pdf. This may make the generated
+ -j , --jpegquality quality Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)
+ -s , --set param=value Set a SWF encoder specific parameter. See pdf2swf -s help for more information.
+ -w , --samewindow When converting pdf hyperlinks, don't make the links open a new window.
+ -t , --stop Insert a stop() command in each page.
+ -T , --flashversion num Set Flash Version in the SWF header to num.
+ -F , --fontdir directory Add directory to the font search path.
+ -b , --defaultviewer Link a standard viewer to the swf file.
+ -l , --defaultloader Link a standard preloader to the swf file which will be displayed while the main swf is loading.
+ -B , --viewer filename Link viewer filename to the swf file.
+ -L , --preloader filename Link preloader filename to the swf file.
+ -q , --quiet Suppress normal messages. Use -qq to suppress warnings, also.
+ -S , --shapes Don't use SWF Fonts, but store everything as shape.
+ -f , --fonts Store full fonts in SWF. (Don't reduce to used characters).
+ -G , --flatten Remove as many clip layers from file as possible.
+ -I , --info Don't do actual conversion, just display a list of all pages in the PDF.
+ -Q , --maxtime n Abort conversion after n seconds. Only available on Unix.
+
+ ##with -s arg:
+ PDF Parameters:
+
+ PDF device global parameters:
+ fontdir=
a directory with additional fonts
+ font= an additional font filename
+ pages= the range of pages to convert (example: pages=1-100,210-)
+ zoom= the resultion (default: 72)
+ languagedir= Add an xpdf language directory
+ multiply= Render everything at the resolution
+ poly2bitmap Convert graphics to bitmaps
+ bitmap Convert everything to bitmaps
+ SWF Parameters:
+
+ SWF layer options:
+ jpegsubpixels= resolution adjustment for jpeg images (same as jpegdpi, but in pixels)
+ ppmsubpixels= shortcut for setting both jpegsubpixels and ppmsubpixels
+ drawonlyshapes convert everything to shapes (currently broken)
+ ignoredraworder allow to perform a few optimizations for creating smaller SWFs
+ linksopennewwindow make links open a new browser window
+ linktarget target window name of new links
+ linkcolor==6)
+ bboxvars store the bounding box of the SWF file in actionscript variables
+ dots Take care to handle dots correctly
+ reordertags=0/1 (default: 1) perform some tag optimizations
+ internallinkfunction= when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called
+ externallinkfunction= when the user clicks an external link (e.g. http://www.foo.bar/) on the converted file, this actionscript function is called
+ disable_polygon_conversion never convert strokes to polygons (will remove capstyles and joint styles)
+ caplinewidth= the minimum thichness a line needs to have so that capstyles become visible (and are converted)
+ insertstop put an ActionScript "STOP" tag in every frame
+ protect add a "protect" tag to the file, to prevent loading in the Flash editor
+ flashversion= the SWF fileversion (6)
+ framerate= SWF framerate
+ minlinewidth= convert horizontal/vertical boxes smaller than this width to lines (0.05)
+ simpleviewer Add next/previous buttons to the SWF
+ animate insert a showframe tag after each placeobject (animate draw order of PDF files)
+ jpegquality= set compression quality of jpeg images
+ splinequality= Set the quality of spline convertion to value (0-100, default: 100).
+ disablelinks Disable links.
+ '''
+
+ # Convert pdf to swf
+ if sys.platform == 'linux':
+ binary = Path(__file__).parent / 'bin' / 'linux' / 'pdf2swf'
+ elif sys.platform.startswith('win'):
+ binary = Path(__file__).parent / 'bin' / 'windows' / 'pdf2swf.exe'
+ else:
+ print('Render to SWF is only supported on mat and linux')
+ return
+
+ pdf_fp = pdf_render(fp, multi_page=True)
+
+ swf_fp = pdf_fp.with_suffix('.swf')
+ cmd = [
+ str(binary),
+ '-s', f'framerate={bpy.context.scene.render.fps}',
+ # -z, # use zlib
+ str(pdf_fp),
+ # '-o', # no need to put output flag
+ str(swf_fp)
+ ]
+ subprocess.call(cmd)
+
+ # Remove single pdf file
+ pdf_fp.unlink()
+ return swf_fp
class GPEXP_OT_export_as_pdf(bpy.types.Operator):
bl_idname = "gp.export_as_pdf"
@@ -103,6 +233,17 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
def poll(cls, context):
return True
+ # multi_page : bpy.props.BoolProperty(name='multi page pdf', default=False)
+ export_type : bpy.props.StringProperty(name='Export Type', default='pdf_sequence')
+
+ @classmethod
+ def description(cls, context, properties) -> str:
+ if properties.export_type == 'pdf':
+ return 'Export layers as individual pdf file (multi-page) using scene range'
+ elif properties.export_type == 'pdf_sequence':
+ return 'Export layers as sequence of single-paged pdf file, using scene range'
+ return 'Export layers as individual SWF files, using scene range'
+
def execute(self, context):
# rd_scn = bpy.data.scenes.get('Render')
# if not rd_scn:
@@ -228,6 +369,7 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
# fo_socket.name isn't right
idx = [i for i in fo_node.inputs].index(fo_socket)
+
subpath = fo_node.file_slots[idx].path
fp = Path(fo_node.base_path.rstrip('/')) / subpath
fp = Path(bpy.path.abspath(str(fp)).rstrip("/"))
@@ -242,7 +384,14 @@ class GPEXP_OT_export_as_pdf(bpy.types.Operator):
if not l.hide:
print(f'-> {l.info}') #Dbg
- pdf_render(fp)
+ if self.export_type == 'pdf_sequence':
+ pdf_render(fp, multi_page=False)
+ elif self.export_type == 'pdf':
+ ## TODO: change fp to parent and adapt in pdf render ?
+ pdf_render(fp, multi_page=self.multi_page)
+ elif self.export_type == 'swf':
+ swf_render(fp)
+
print()
### restore
diff --git a/__init__.py b/__init__.py
index 2387d40..61d2fb0 100644
--- a/__init__.py
+++ b/__init__.py
@@ -2,7 +2,7 @@ bl_info = {
"name": "GP Render",
"description": "Organise export of gp layers through compositor output",
"author": "Samuel Bernou",
- "version": (1, 4, 1),
+ "version": (1, 5, 0),
"blender": (3, 0, 0),
"location": "View3D",
"warning": "",
diff --git a/bin/linux/pdf2swf b/bin/linux/pdf2swf
new file mode 100644
index 0000000..1b7fa9a
Binary files /dev/null and b/bin/linux/pdf2swf differ
diff --git a/bin/windows/pdf2swf.exe b/bin/windows/pdf2swf.exe
new file mode 100644
index 0000000..f0a1f7c
Binary files /dev/null and b/bin/windows/pdf2swf.exe differ
diff --git a/ui.py b/ui.py
index 20b5664..3d73acf 100644
--- a/ui.py
+++ b/ui.py
@@ -249,11 +249,17 @@ class GPEXP_PT_gp_dopesheet_ui(Panel):
layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors')
layout.separator()
+
+ # row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='Render All to PDF Sequences')
+ layout.label(text='Render All To Vector:')
+ col= layout.column()
+ row = col.row(align=True)
+ row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF Sequences').export_type = 'pdf_sequence'
+ row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF File').export_type = 'pdf'
+ col.operator('gp.export_as_pdf', icon='RENDER_STILL', text='SWF File').export_type = 'swf'
- row = layout.row()
- row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='Render All to PDF Sequences')
if bpy.app.version < (3,0,0):
- row.label(text='Not Blender 3.0.0+')
+ col.label(text='Not Blender 3.0.0+ !')
## Append GP Render workspace (usefull for user with disabled 'load_UI')
if not bpy.data.workspaces.get('GP Render'):