diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9f50a9f..df827c2 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -87,7 +87,7 @@ jobs:
asset_name: conduct.exe
asset_content_type: application/octet-stream
- release-integrations:
+ release-blender-integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -107,4 +107,26 @@ jobs:
upload_url: ${{ github.event.release.upload_url }}
asset_path: integration/conduct-blender.zip
asset_name: conduct-blender.zip
- asset_content_type: application/zip
\ No newline at end of file
+ asset_content_type: application/zip
+
+ release-inkscape-integration:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Zip Inkscape Integration
+ run: |
+ cd integration
+ mv inkscape conduct-inkscape
+ zip -r conduct-inkscape.zip conduct-inkscape
+
+ - name: Upload to release
+ if: github.event_name == 'release'
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ github.event.release.upload_url }}
+ asset_path: integration/conduct-inkscape.zip
+ asset_name: conduct-inkscape.zip
+ asset_content_type: application/zip
diff --git a/example/basic/manifest.yaml b/example/basic/manifest.yaml
index 148a08a..be4d493 100644
--- a/example/basic/manifest.yaml
+++ b/example/basic/manifest.yaml
@@ -12,6 +12,10 @@ programs:
.glb: import_glb_mesh.py
.shadergraph.blend: import_blend_shadergraph.py
.mesh.blend: import_blend_library_mesh.py
+ inkscape:
+ exports:
+ .png: export_png_512.py
+ .2x.png: export_png_1024.py
departments:
anim:
@@ -72,6 +76,13 @@ assets:
departments:
layout:
- !depends(defaultCubeA;defaultCubeB) cubeInstancer
+ 2d:
+ icons:
+ - iconA:
+ departments:
+ design:
+ - vector
+ - 2x
shots:
'103':
diff --git a/example/basic/scripts/inkscape/export_png_1024.py b/example/basic/scripts/inkscape/export_png_1024.py
new file mode 100644
index 0000000..f4f613a
--- /dev/null
+++ b/example/basic/scripts/inkscape/export_png_1024.py
@@ -0,0 +1,33 @@
+
+class InkscapeDataExport():
+
+ def log(self, object):
+ import inkex
+ inkex.utils.debug(object)
+
+ def export(self, effect_context, directory=None, file_name=None, extension=None, items=None, ):
+ from tempfile import TemporaryDirectory
+ import inkex
+ import os
+
+ with TemporaryDirectory(prefix='inkscape-command-') as tmpdir:
+
+ svg_file = inkex.command.write_svg(effect_context.svg, tmpdir, 'input.svg')
+ output = os.path.join(directory, file_name + extension)
+
+ pages = effect_context.svg.namedview.get_pages()
+ index = pages.index(items[0])
+
+ page = items[0]
+
+ height = 1024
+ ratio = page.width / page.height
+ width = round(ratio * height)
+
+ out = inkex.command.inkscape(svg_file,
+ "--export-filename=%s" % output,
+ '--export-type=png',
+ '--export-width=%d' % width,
+ '--export-height=%d' % height,
+ '--export-page=%d' % (index + 1))
+
\ No newline at end of file
diff --git a/example/basic/scripts/inkscape/export_png_512.py b/example/basic/scripts/inkscape/export_png_512.py
new file mode 100644
index 0000000..4a6c8fc
--- /dev/null
+++ b/example/basic/scripts/inkscape/export_png_512.py
@@ -0,0 +1,33 @@
+
+class InkscapeDataExport():
+
+ def log(self, object):
+ import inkex
+ inkex.utils.debug(object)
+
+ def export(self, effect_context, directory=None, file_name=None, extension=None, items=None, ):
+ from tempfile import TemporaryDirectory
+ import inkex
+ import os
+
+ with TemporaryDirectory(prefix='inkscape-command-') as tmpdir:
+
+ svg_file = inkex.command.write_svg(effect_context.svg, tmpdir, 'input.svg')
+ output = os.path.join(directory, file_name + extension)
+
+ pages = effect_context.svg.namedview.get_pages()
+ index = pages.index(items[0])
+
+ page = items[0]
+
+ height = 512
+ ratio = page.width / page.height
+ width = round(ratio * height)
+
+ out = inkex.command.inkscape(svg_file,
+ "--export-filename=%s" % output,
+ '--export-type=png',
+ '--export-width=%d' % width,
+ '--export-height=%d' % height,
+ '--export-page=%d' % (index + 1))
+
\ No newline at end of file
diff --git a/example/basic/setup/asset/design/iconA/iconA_design.svg b/example/basic/setup/asset/design/iconA/iconA_design.svg
new file mode 100644
index 0000000..351257e
--- /dev/null
+++ b/example/basic/setup/asset/design/iconA/iconA_design.svg
@@ -0,0 +1,165 @@
+
+
+
+
diff --git a/integration/common/conduct.py b/integration/common/conduct.py
index 15d67ac..70b864f 100644
--- a/integration/common/conduct.py
+++ b/integration/common/conduct.py
@@ -4,6 +4,9 @@
import subprocess
import json
+def log(info):
+ print(info)
+
class Conduct:
conduct_exe = ""
current_program = ""
@@ -24,12 +27,13 @@ def run_process(self, args):
startupinfo.dwFlags = subprocess.CREATE_NO_WINDOW
creation_flags = subprocess.CREATE_NO_WINDOW
- print("Executing: " + str(args))
+ log("Executing: " + str(args))
- process=subprocess.Popen(args, cwd=os.path.dirname(self.conduct_exe), startupinfo=startupinfo, stdout=subprocess.PIPE, encoding='utf-8', creationflags=creation_flags)
+ process=subprocess.Popen(args, cwd=os.path.dirname(self.conduct_exe), startupinfo=startupinfo, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, encoding='utf-8', creationflags=creation_flags)
data = process.communicate()[0]
- print(data)
+
+ log(data)
return json.loads(data)
@@ -53,6 +57,18 @@ def dialog_load_asset(self, department, shot=None, asset=None ):
return self.run_process(args)
+ def dialog_export(self, department, asset, items, prev_state=None, shot=None, ):
+ args = ["dialog", "export", "--", "--program", self.current_program, "--department", department, "--asset", asset, "--items", items ]
+ if shot != None and shot != "":
+ args.append("--shot")
+ args.append(shot)
+
+ if prev_state != None and prev_state != "":
+ args.append("--prev-state")
+ args.append(prev_state)
+
+ return self.run_process(args)
+
def list_export_formats(self, department):
return self.run_process(["list-export-formats", "--from", self.current_program, "--department", department])
@@ -65,7 +81,7 @@ def export(self, department, format, asset, element, shot=None):
return self.run_process(args)
def get_from_manifest_path(manifest_path, current_program):
- print("Getting exe from manifest path: " + manifest_path)
+ log("Getting exe from manifest path: " + manifest_path)
dir_path = os.path.dirname(manifest_path)
exe = "conduct"
@@ -76,7 +92,7 @@ def get_from_manifest_path(manifest_path, current_program):
return Conduct(path, current_program)
def find_from_current_path(current_file, current_program):
- print("Looking for conduct path for file: " + current_file)
+ log("Looking for conduct path for file: " + current_file)
path = os.path.dirname(current_file)
while path != "":
checks = [
@@ -86,7 +102,7 @@ def find_from_current_path(current_file, current_program):
for check in checks:
if os.path.isfile(check):
- print("found:" + check)
+ log("found:" + check)
return get_from_manifest_path(check, current_program)
path = os.path.dirname(path)
diff --git a/integration/inkscape/conduct b/integration/inkscape/conduct
new file mode 120000
index 0000000..8332399
--- /dev/null
+++ b/integration/inkscape/conduct
@@ -0,0 +1 @@
+../common/
\ No newline at end of file
diff --git a/integration/inkscape/conduct_create_setup.inx b/integration/inkscape/conduct_create_setup.inx
new file mode 100644
index 0000000..fbd9261
--- /dev/null
+++ b/integration/inkscape/conduct_create_setup.inx
@@ -0,0 +1,15 @@
+
+
+ Create Setup
+ com.lagmachine.conduct.create_setup
+
+
+ all
+
+
+
+
+
+
\ No newline at end of file
diff --git a/integration/inkscape/conduct_create_setup.py b/integration/inkscape/conduct_create_setup.py
new file mode 100644
index 0000000..277e1df
--- /dev/null
+++ b/integration/inkscape/conduct_create_setup.py
@@ -0,0 +1,58 @@
+import inkex
+from inkex import command
+import os
+from conduct import conduct
+import subprocess
+
+def log_stub(info):
+ pass
+
+def log(info):
+ inkex.utils.debug(info)
+
+class ConductCreateSetup(inkex.EffectExtension):
+
+ def add_arguments(self, pars):
+ pars.add_argument("-m", "--manifest", default="", help="Manifest File Path")
+
+
+ def effect(self):
+ manifest_path = self.options.manifest
+ conduct.log = log_stub
+ c = conduct.get_from_manifest_path(manifest_path, "inkscape")
+ result = c.setup('.svg')
+
+ if result['result'] != 'ok':
+ return
+
+ dialog_data = result['data']
+
+ self.svg.set("com.lagmachine.conduct.asset", dialog_data['asset'])
+ self.svg.set("com.lagmachine.conduct.department", dialog_data['department'])
+ if dialog_data['shot'] is not None:
+ self.svg.set("com.lagmachine.conduct.shot", dialog_data['shot'])
+
+ # write to new file, and open it in a new instance of inkscape
+ # this is the best i can do, there is no function for changing the current file to a different location
+ data = self.svg.tostring().decode('utf-8')
+
+ path = dialog_data['path']
+ with open(path, mode='w') as f:
+ f.write(data)
+
+ exe = inkex.command.which('inkscape')
+
+ if(exe.startswith('/tmp/.mount')):
+ log("Detected running in an AppImage, this process will hang until the new instance is closed!")
+ inkex.command.inkscape(path)
+ return
+
+ #if we could find a good way to kill the original inkscape instance after starting the new one, that would be ideal
+ if os.name == 'nt':
+ creation_flags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.DETACHED_PROCESS
+ proc = subprocess.Popen([exe, path], creationflags=creation_flags, start_new_session=True)
+ else:
+ proc = subprocess.Popen([exe, path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL)
+
+if __name__ == '__main__':
+ ConductCreateSetup().run()
\ No newline at end of file
diff --git a/integration/inkscape/conduct_export.inx b/integration/inkscape/conduct_export.inx
new file mode 100644
index 0000000..8f1a0f6
--- /dev/null
+++ b/integration/inkscape/conduct_export.inx
@@ -0,0 +1,14 @@
+
+
+ Export
+ com.lagmachine.conduct.export
+
+ all
+
+
+
+
+
+
\ No newline at end of file
diff --git a/integration/inkscape/conduct_export.py b/integration/inkscape/conduct_export.py
new file mode 100644
index 0000000..cfda649
--- /dev/null
+++ b/integration/inkscape/conduct_export.py
@@ -0,0 +1,77 @@
+import inkex
+from inkex import command
+import os
+from conduct import conduct
+import subprocess
+import json
+import inspect
+
+def log_stub(info):
+ pass
+
+def log(info):
+ inkex.utils.debug(info)
+
+class SvgReader(inkex.extensions.InputExtension):
+ pass
+
+class ConductExportEffect(inkex.EffectExtension):
+
+ def effect(self):
+ conduct.log = log_stub
+
+ file_path = os.path.join(self.svg_path(), self.svg.name)
+ department = self.svg.get("com.lagmachine.conduct.department")
+ asset = self.svg.get("com.lagmachine.conduct.asset")
+
+ prev_state = self.svg.get("com.lagmachine.conduct.export_save_state")
+ prev_state = json.loads(prev_state)
+
+ c = conduct.find_from_current_path(file_path, "inkscape")
+
+ pages = self.svg.namedview.get_pages()
+ items = ','.join([page.label for page in pages])
+
+
+ result = c.dialog_export(department, asset, items, prev_state=prev_state)
+
+ if result['result'] != 'ok':
+ return
+
+ save_state = result['data']['save_state']
+ self.svg.set("com.lagmachine.conduct.export_save_state", save_state)
+
+ for export in result['data']['exports']:
+ items = export['items']
+ export_data = export['result']
+ if 'error' in export_data:
+ log(export_data['error'])
+ return
+ export_pages = [page for page in pages if page.label in items]
+
+ locals = {}
+ globals = {}
+ script = export_data['script']
+ exec(script, locals, globals)
+
+ for item in globals:
+ instance = globals[item]
+
+ if not inspect.isclass(instance):
+ continue
+
+ exporter_instance = instance()
+
+ exporter_instance.export(
+ self,
+ directory=export_data['directory'],
+ file_name=export_data['recommended_file_name'],
+ extension=export_data['file_format'],
+ items = export_pages
+ )
+
+ return
+
+
+if __name__ == '__main__':
+ ConductExportEffect().run()
diff --git a/integration/inkscape/shell.nix b/integration/inkscape/shell.nix
new file mode 100644
index 0000000..8019118
--- /dev/null
+++ b/integration/inkscape/shell.nix
@@ -0,0 +1,12 @@
+
+let pkgs = import {};
+
+shell = pkgs.mkShell {
+ buildInputs = with pkgs; [
+ inkscape
+ ];
+
+ WEBKIT_DISABLE_COMPOSITING_MODE=1;
+};
+
+in shell