Add new extension qcad_svg_to_modern_dxf
This commit is contained in:
parent
40b802def8
commit
bc87968598
@ -0,0 +1,32 @@
|
|||||||
|
include("scripts/ImportExport/SvgImporter/SvgImporter.js")
|
||||||
|
include("scripts/ImportExport/SvgImporter/SvgImporterInit.js");
|
||||||
|
include("scripts/Pro/Draw/Polyline/PolylineFromSelection/PolylineFromSelection.js");
|
||||||
|
include("scripts/Pro/Modify/Detection/Duplicates/Duplicates.js");
|
||||||
|
|
||||||
|
RFileImporterRegistry.registerFileImporter(new SvgImporterFactory());
|
||||||
|
qApp.applicationName = "SVG-DXF";
|
||||||
|
|
||||||
|
var storage = new RMemoryStorage();
|
||||||
|
var spatialIndex = new RSpatialIndexSimple();
|
||||||
|
var doc = new RDocument(storage, spatialIndex);
|
||||||
|
var di = new RDocumentInterface(doc);
|
||||||
|
var tolerance = $QCAD_TOLERANCE$;
|
||||||
|
|
||||||
|
const importer = new SvgImporter(doc);
|
||||||
|
|
||||||
|
di.importFile("$SVG_PATH$");
|
||||||
|
|
||||||
|
var purge_duplicates = $QCAD_PURGE_DUPLICATES$;
|
||||||
|
if (purge_duplicates === true) {
|
||||||
|
Duplicates.findDuplicates(di, true, tolerance, 0.0, true);
|
||||||
|
var counter = doc.countSelectedEntities();
|
||||||
|
var op = new RDeleteSelectionOperation();
|
||||||
|
di.applyOperation(op);
|
||||||
|
print("Purged duplicates: " + counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
di.selectAll();
|
||||||
|
|
||||||
|
PolylineFromSelection.autoJoinSegments(di, tolerance);
|
||||||
|
di.exportFile("$EXPORT_PATH$", "$QCAD_DXF_FORMAT$");
|
||||||
|
di.destroy();
|
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||||
|
<name>QCAD SVG to modern DXF</name>
|
||||||
|
<id>fablabchemnitz.de.qcad_svg_to_modern_dxf</id>
|
||||||
|
<param name="tab" type="notebook">
|
||||||
|
<page name="tab_settings" gui-text="Settings">
|
||||||
|
<param name="qcad_dxf_format" type="optiongroup" appearance="combo" gui-text="DXF export type">
|
||||||
|
<option value="R32 DXF">R32/2018 (OpenDesign)</option>
|
||||||
|
<option value="R27 DXF">R27/2013 (OpenDesign)</option>
|
||||||
|
<option value="R24 DXF">R24/2010 (OpenDesign)</option>
|
||||||
|
<option value="R21 DXF">R21/2007 (OpenDesign)</option>
|
||||||
|
<option value="R18 DXF">R18/2004 (OpenDesign)</option>
|
||||||
|
<option value="R15 DXF">R15/2000 (OpenDesign)</option>
|
||||||
|
<option value="dxflib">R15/2000 (dxflib)</option>
|
||||||
|
<option value="R14 DXF">R14 (OpenDesign)</option>
|
||||||
|
<option value="R13 DXF">R13 (OpenDesign)</option>
|
||||||
|
<option value="R12 DXF">R12 (OpenDesign)</option>
|
||||||
|
<option value="R11 DXF">R11 (OpenDesign)</option>
|
||||||
|
<option value="R10 DXF">R10 (OpenDesign)</option>
|
||||||
|
<option value="R9 DXF">R9 (OpenDesign)</option>
|
||||||
|
</param>
|
||||||
|
<param name="qcad_tolerance" type="float" min="0.0000001" max="999999" precision="3" gui-text="Polyline tolerance" gui-description="">0.001</param>
|
||||||
|
<param name="qcad_purge_duplicates" type="bool" gui-text="Purge duplicate lines">false</param>
|
||||||
|
<param name="qcad_pro_path" type="path" mode="file" gui-text="QCAD Pro executable path" gui-description="Do not use Community Edition, as it will not work.">~/opt/qcad-3.28.2-pro-linux-x86_64/qcad</param>
|
||||||
|
<param name="debug" type="bool" gui-text="Show debug info">false</param>
|
||||||
|
<param name="open_in_qcad" type="bool" gui-text="Open export file in QCAD">false</param>
|
||||||
|
|
||||||
|
</page>
|
||||||
|
<page name="tab_about" gui-text="About">
|
||||||
|
<label appearance="header">QCAD SVG to modern DXF</label>
|
||||||
|
<label>This extension uses QCAD Pro 3.28 to convert an Inkscape SVG file to a nice DXF file, which has continuous polylines.</label>
|
||||||
|
<label>2024 / written by Mario Voigt (Stadtfabrikanten e.V. / FabLab Chemnitz)</label>
|
||||||
|
<spacer/>
|
||||||
|
<label appearance="header">Online Documentation</label>
|
||||||
|
<label appearance="url">https://y.stadtfabrikanten.org/qcad_svg_to_modern_dxf</label>
|
||||||
|
<spacer/>
|
||||||
|
<label appearance="header">Contributing</label>
|
||||||
|
<label appearance="url">https://gitea.fablabchemnitz.de/FabLab_Chemnitz/mightyscape-1.2</label>
|
||||||
|
<label appearance="url">mailto:mario.voigt@stadtfabrikanten.org</label>
|
||||||
|
<spacer/>
|
||||||
|
<label appearance="header">MightyScape Extension Collection</label>
|
||||||
|
<label>This piece of software is part of the MightyScape for Inkscape Extension Collection and is licensed under GNU GPL v3</label>
|
||||||
|
<label appearance="url">https://y.stadtfabrikanten.org/mightyscape-overview</label>
|
||||||
|
</page>
|
||||||
|
<page name="tab_donate" gui-text="Donate">
|
||||||
|
<label appearance="header">Coffee + Pizza</label>
|
||||||
|
<label>We are the Stadtfabrikanten, running the FabLab Chemnitz since 2016. A FabLab is an open workshop that gives people access to machines and digital tools like 3D printers, laser cutters and CNC milling machines.</label>
|
||||||
|
<spacer/>
|
||||||
|
<label>You like our work and want to support us? You can donate to our non-profit organization by different ways:</label>
|
||||||
|
<label appearance="url">https://y.stadtfabrikanten.org/donate</label>
|
||||||
|
<spacer/>
|
||||||
|
<label>Thanks for using our extension and helping us!</label>
|
||||||
|
<image>../000_about_fablabchemnitz.svg</image>
|
||||||
|
</page>
|
||||||
|
</param>
|
||||||
|
<output>
|
||||||
|
<extension>.dxf</extension>
|
||||||
|
<mimetype>image/dxf</mimetype>
|
||||||
|
<filetypename>QCAD DXF (*.dxf)</filetypename>
|
||||||
|
<filetypetooltip>AutoDesk DXF - OpenDesign/dxflibs</filetypetooltip>
|
||||||
|
<dataloss>true</dataloss>
|
||||||
|
</output>
|
||||||
|
<script>
|
||||||
|
<command location="inx" interpreter="python">qcad_svg_to_modern_dxf.py</command>
|
||||||
|
</script>
|
||||||
|
</inkscape-extension>
|
@ -0,0 +1,109 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import inkex
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
'''
|
||||||
|
Simple extension to utilize QCAD Pro for some neat DXF operations. Based on:
|
||||||
|
- https://ribbonsoft.com/rsforum/viewtopic.php?t=6801
|
||||||
|
- https://qcad.org/rsforum/viewtopic.php?t=8471
|
||||||
|
|
||||||
|
written 14.01.2024 by Mario Voigt / Stadtfabrikanten e.V.
|
||||||
|
|
||||||
|
ToDos
|
||||||
|
- black colored paths are getting blue or brown when using DXF Export of QCAD. Why? How to change this?
|
||||||
|
- keep canvas format
|
||||||
|
- keep original SVG Unit
|
||||||
|
'''
|
||||||
|
|
||||||
|
class QCAD_SVG(inkex.OutputExtension):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
inkex.Effect.__init__(self)
|
||||||
|
|
||||||
|
def add_arguments(self, pars):
|
||||||
|
pars.add_argument("--tab")
|
||||||
|
pars.add_argument("--qcad_dxf_format", default="dxflib", help="DXF Export Type")
|
||||||
|
pars.add_argument("--qcad_tolerance", type=float, default=0.001, help="Polyline Tolerance")
|
||||||
|
pars.add_argument("--qcad_purge_duplicates", type=inkex.Boolean, default=False, help="Purge duplicate lines")
|
||||||
|
pars.add_argument("--qcad_pro_path", default="~/opt/qcad-3.28.2-pro-linux-x86_64/qcad", help="Location of qcad pro executable")
|
||||||
|
pars.add_argument("--debug", type=inkex.Boolean, default=False, help="Show debug info")
|
||||||
|
pars.add_argument("--open_in_qcad", type=inkex.Boolean, default=False, help="Open export file in QCAD")
|
||||||
|
|
||||||
|
def inplace_change(self, filename, old_string, new_string):
|
||||||
|
with open(filename) as f:
|
||||||
|
s = f.read()
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
s = s.replace(old_string, new_string)
|
||||||
|
f.write(s)
|
||||||
|
|
||||||
|
def effect(self):
|
||||||
|
so = self.options
|
||||||
|
qcad_pro_path = os.path.relpath(so.qcad_pro_path)
|
||||||
|
tmpdir_path = os.path.dirname(so.input_file)
|
||||||
|
export_path = self.document_path()
|
||||||
|
qcad_script = "qcad-dxf-script.js"
|
||||||
|
if so.qcad_purge_duplicates is True:
|
||||||
|
qcad_purge_duplicates = "true"
|
||||||
|
else:
|
||||||
|
qcad_purge_duplicates = "false"
|
||||||
|
qcad_tolerance = "{:6.6f}".format(so.qcad_tolerance)
|
||||||
|
qcad_dxf_format = so.qcad_dxf_format
|
||||||
|
|
||||||
|
if so.debug is True:
|
||||||
|
inkex.utils.debug("/tmp dir Path:{}".format(tmpdir_path))
|
||||||
|
inkex.utils.debug("Export Path{}".format(export_path))
|
||||||
|
inkex.utils.debug("QCAD Pro Path: {}".format(qcad_pro_path))
|
||||||
|
inkex.utils.debug("QCAD Polyline Tolerance: {}".format(qcad_tolerance))
|
||||||
|
inkex.utils.debug("QCAD DXF Format: {}".format(qcad_dxf_format))
|
||||||
|
|
||||||
|
#we must copy the input file to a new file with ending *.svg. Otherwise QCAD does not recognise the file type
|
||||||
|
target_file = self.options.input_file + ".svg"
|
||||||
|
shutil.copy2(self.options.input_file, target_file)
|
||||||
|
|
||||||
|
#copy the qcad-dxf-script.js file to temporary location and modify its content
|
||||||
|
shutil.copy2(qcad_script, tmpdir_path)
|
||||||
|
qcad_script_tmp = os.path.join(tmpdir_path, qcad_script)
|
||||||
|
self.inplace_change(qcad_script_tmp, "$SVG_PATH$", target_file)
|
||||||
|
self.inplace_change(qcad_script_tmp, "$QCAD_TOLERANCE$", qcad_tolerance)
|
||||||
|
self.inplace_change(qcad_script_tmp, "$EXPORT_PATH$", export_path)
|
||||||
|
self.inplace_change(qcad_script_tmp, "$QCAD_DXF_FORMAT$", qcad_dxf_format)
|
||||||
|
self.inplace_change(qcad_script_tmp, "$QCAD_PURGE_DUPLICATES$", qcad_purge_duplicates)
|
||||||
|
|
||||||
|
#build the command and execute the script
|
||||||
|
command = [qcad_pro_path + " -autostart \"" + qcad_script_tmp + "\""]
|
||||||
|
proc = subprocess.Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
|
||||||
|
stdout, stderr = proc.communicate()
|
||||||
|
if proc.returncode != 0: #in this case we exit
|
||||||
|
inkex.utils.debug("QCAD Console Output: %d %s %s" % (proc.returncode, stdout, stderr))
|
||||||
|
if "Application already running" in stderr.decode('UTF-8'):
|
||||||
|
inkex.utils.debug("Warning. QCAD already running. Please close it and run this extension again!")
|
||||||
|
|
||||||
|
if so.debug is True:
|
||||||
|
inkex.utils.debug(stdout.decode('UTF-8'))
|
||||||
|
inkex.utils.debug(stderr.decode('UTF-8'))
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
if so.open_in_qcad is True:
|
||||||
|
command = [qcad_pro_path + " " + export_path]
|
||||||
|
proc = subprocess.Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
|
||||||
|
stdout, stderr = proc.communicate()
|
||||||
|
if proc.returncode != 0: #in this case we exit
|
||||||
|
inkex.utils.debug("QCAD Console Output: %d %s %s" % (proc.returncode, stdout, stderr))
|
||||||
|
|
||||||
|
if so.debug is True:
|
||||||
|
inkex.utils.debug(stdout.decode('UTF-8'))
|
||||||
|
inkex.utils.debug(stderr.decode('UTF-8'))
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
#this is just implemented to avoid a warning. The file gets written twice, because its already generated by QCAD, then it gets written again by save() method
|
||||||
|
def save(self, stream):
|
||||||
|
with open(self.document_path(), 'rb') as finalfile:
|
||||||
|
stream.write(finalfile.read())
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
QCAD_SVG().run()
|
Loading…
Reference in New Issue
Block a user