Skip to content

Commit

Permalink
Merge pull request #9 from CadQuery/svg
Browse files Browse the repository at this point in the history
Adding the SVG Codec and Support for Codec Options
  • Loading branch information
jmwright authored Jan 29, 2021
2 parents 1c3b353 + f928cf5 commit 0c8c9ed
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ If a development installation is desired, see the [Contributing](#contributing)

## Usage

usage: cq-cli.py [-h] [--codec CODEC] [--infile INFILE] [--outfile OUTFILE] [--errfile ERRFILE] [--params PARAMS] [--validate VALIDATE]
usage: cq-cli.py [-h] [--codec CODEC] [--infile INFILE] [--outfile OUTFILE] [--errfile ERRFILE] [--params PARAMS] [--outputopts OPTS] [--validate VALIDATE]

Command line utility for converting CadQuery script output to various other output formats.

Expand All @@ -49,6 +49,7 @@ optional arguments:
* --outfile OUTFILE File to write the converted CadQuery output to. Prints to stdout if not specified.
* --errfile ERRFILE File to write any errors to. Prints to stderr if not specified.
* --params PARAMS A colon and semicolon delimited string (no spaces) of key/value pairs representing variables and their values in the CadQuery script. i.e. var1:10.0;var2:4.0;
* --outputopts OPTS A colon and semicolon delimited string (no spaces) of key/value pairs representing options to pass to the selected codec. i.e. width:100;height:200;
* --validate VALIDATE Setting to true forces the CLI to only parse and validate the script and not produce converted output.

## Examples
Expand Down Expand Up @@ -77,6 +78,10 @@ optional arguments:
```
cat /input/path/script.py | cq-cli.py --codec step | wc -l
```
7. Convert a CadQuery script to SVG, passing in output options to influence the resulting image.
```
./cq-cli.py --codec svg --infile /input/path/script.py --outfile /output/path/newfile.svg --outputopts "width:100;height:100;marginLeft:12;marginTop:12;showAxes:False;projectionDir:(0.5,0.5,0.5);strokeWidth:0.25;strokeColor:(255,0,0);hiddenColor:(0,0,255);showHidden:True;"
```

## Drawbacks

Expand Down
33 changes: 31 additions & 2 deletions cq-cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def main():
codec = None
codec_module = None
params = {}
output_opts = {}

# Find the codecs that have been added.
loaded_codecs = loader.load_codecs()
Expand All @@ -101,6 +102,7 @@ def main():
parser.add_argument('--outfile', dest='outfile', help='File to write the converted CadQuery output to. Prints to stdout if not specified.')
parser.add_argument('--errfile', dest='errfile', help='File to write any errors to. Prints to stderr if not specified.')
parser.add_argument('--params', dest='params', help='A colon and semicolon delimited string (no spaces) of key/value pairs representing variables and their values in the CadQuery script. i.e. var1:10.0;var2:4.0;')
parser.add_argument('--outputopts', dest='opts', help='A colon and semicolon delimited string (no spaces) of key/value pairs representing options to pass to the selected codec. i.e. width:100;height:200;')
parser.add_argument('--validate', dest='validate', help='Setting to true forces the CLI to only parse and validate the script and not produce converted output.')

args = parser.parse_args()
Expand Down Expand Up @@ -189,7 +191,34 @@ def main():
groups = args.params.split(';')
for group in groups:
param_parts = group.split(':')
params[param_parts[0]] = param_parts[1]
# Protect against a trailing semi-colon
if len(param_parts) == 2:
params[param_parts[0]] = param_parts[1]

#
# Output options handling
#
# Check whether any output options were passed
if args.opts != None:
# Convert the string of options into a output_opts dictionary
groups = args.opts.split(';')
for group in groups:
opt_parts = group.split(':')
# Protect against a trailing semi-colon
if len(opt_parts) == 2:
op1 = opt_parts[1]

# Handle the option data types properly
if op1 == "True" or op1 == "False":
op = opt_parts[1] == "True"
elif op1[:1] == "(":
op = tuple(map(float, opt_parts[1].replace("(", "").replace(")", "").split(',')))
elif "." in op1:
op = float(opt_parts[1])
else:
op = int(opt_parts[1])

output_opts[opt_parts[0]] = op

#
# Parse and build the script.
Expand All @@ -216,7 +245,7 @@ def main():
# Build, parse and let the selected codec convert the CQ output
try:
# Use the codec plugin to do the conversion
converted = codec_module.convert(build_result, outfile, errfile)
converted = codec_module.convert(build_result, outfile, errfile, output_opts)

# If converted is None, assume that the output was written to file directly by the codec
if converted != None:
Expand Down
2 changes: 1 addition & 1 deletion cqcodecs/cq_codec_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import cadquery as cq
import cqcodecs.codec_helpers as helpers

def convert(build_result, output_file=None, error_file=None):
def convert(build_result, output_file=None, error_file=None, output_opts=None):
# Create a temporary file to put the STL output into
temp_dir = tempfile.gettempdir()
temp_file = os.path.join(temp_dir, "temp_step.step")
Expand Down
2 changes: 1 addition & 1 deletion cqcodecs/cq_codec_stl.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import cadquery as cq
import cqcodecs.codec_helpers as helpers

def convert(build_result, output_file=None, error_file=None):
def convert(build_result, output_file=None, error_file=None, output_opts=None):
# Create a temporary file to put the STL output into
temp_dir = tempfile.gettempdir()
temp_file = os.path.join(temp_dir, "temp_stl.stl")
Expand Down
20 changes: 20 additions & 0 deletions cqcodecs/cq_codec_svg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os, tempfile
from cadquery import exporters
import cadquery as cq
import cqcodecs.codec_helpers as helpers

def convert(build_result, output_file=None, error_file=None, output_opts=None):
# Create a temporary file to put the STL output into
temp_dir = tempfile.gettempdir()
temp_file = os.path.join(temp_dir, "temp_svg.svg")

# The exporters will add extra output that we do not want, so suppress it
with helpers.suppress_stdout_stderr():
# Put the STEP output into the temp file
exporters.export(build_result.results[0].shape, temp_file, exporters.ExportTypes.SVG, opt=output_opts)

# Read the STEP output back in
with open(temp_file, 'r') as file:
step_str = file.read()

return step_str
12 changes: 12 additions & 0 deletions tests/test_svg_codec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import tests.test_helpers as helpers

def test_svg_codec():
"""
Basic test of the SVG codec plugin.
"""
test_file = helpers.get_test_file_location("cube.py")

command = ["python", "cq-cli.py", "--codec", "svg", "--infile", test_file, "--outputopts", "width:100;height:100;marginLeft:12;marginTop:12;showAxes:False;projectionDir:(0.5,0.5,0.5);strokeWidth:0.25;strokeColor:(255,0,0);hiddenColor:(0,0,255);showHidden:True;"]
out, err, exitcode = helpers.cli_call(command)

assert out.decode().split('\n')[0].replace('\r', '') == "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"

0 comments on commit 0c8c9ed

Please sign in to comment.