2024-01-14 19:43:34 +01:00
#!/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 " )
2024-01-18 00:54:22 +01:00
pars . add_argument ( " --qcad_join_polylines " , type = inkex . Boolean , default = True , help = " Join Polylines " )
2024-01-14 19:43:34 +01:00
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
2024-01-18 00:54:22 +01:00
if os . path . exists ( so . input_file ) is False :
inkex . utils . debug ( " WARNING: File was not saved yet! Try again after saving. " )
exit ( 1 )
2024-01-14 19:43:34 +01:00
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 "
2024-01-18 00:54:22 +01:00
if so . qcad_join_polylines is True :
qcad_join_polylines = " true "
else :
qcad_join_polylines = " false "
qcad_tolerance = " {:6.6f} " . format ( so . qcad_tolerance )
2024-01-14 19:43:34 +01:00
if so . qcad_purge_duplicates is True :
qcad_purge_duplicates = " true "
else :
qcad_purge_duplicates = " false "
qcad_dxf_format = so . qcad_dxf_format
if so . debug is True :
2024-01-18 00:54:22 +01:00
inkex . utils . debug ( " Input file: {} " . format ( so . input_file ) )
2024-01-14 19:43:34 +01:00
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 )
2024-01-18 00:54:22 +01:00
self . inplace_change ( qcad_script_tmp , " $QCAD_JOIN_POLYLINES$ " , qcad_join_polylines )
2024-01-14 19:43:34 +01:00
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 ( )