-
Notifications
You must be signed in to change notification settings - Fork 5
Description
If opening sample.svg in a current version of inkscape, the first thing shown is a dialogue window related to changes to dpi handling. We can proceed to see that the path in this file is 10 mm × 18 mm, or 39 px × 66 px.
The object dimensions in sample.scad are 35 mm × 61 mm.
My understanding is that svg:s were essentially lacking units back when SVG2SCAD was first created. It thus used px as the unit, which ended up as mm. The slight difference between the numbers is likely due the 96 dpi/90 dpi factor and details on how inkscape calculates dimensions including stroke thickness or what not.
While SVG2SCAD is documented as only handling inkscape svg:s, I wasn't primarily interested in one generated with potrace. That one turned out 33½ times bigger than expected, regardless if I ran svg2scad directly or after importing and scaling it in inkscape. A looking at the actual svg code revealed a transform taking place.
By taking the factor from the transform and patching the script as below, I managed to get the a resulting scad file to contain a correctly sized object.
diff --git a/svg2scad b/svg2scad
index 7d907da..4a25221 100755
--- a/svg2scad
+++ b/svg2scad
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# --- SVG 2 SCAD, written by Rene K. Mueller <spiritdude@gmail.com>
#
@@ -13,6 +13,8 @@ my $Version = '0.006';
# 2012/08/02: 0.002: extended with some functionality
# 2012/08/01: 0.001: first rudimentary version
+use constant SCALE_FACTOR = 0.02821831;
+
use Math::Trig;
use XML::Simple;
use Math::Bezier;
@@ -162,6 +164,8 @@ sub decodePath {
if($c eq 'm'||$c eq 'M') {
# -- moveto
my($x,$y) = getArgs(\@s,2);
+ $x *= SCALE_FACTOR;
+ $y *= SCALE_FACTOR;
$xp += $x, $yp += $y if($c eq 'm');
$xp = $x, $yp = $y if($c eq 'M');
pushPoint(\@o,$xp,$yp); $pc++;
@@ -171,6 +175,8 @@ sub decodePath {
} elsif($c eq 'l'||$c eq 'L') {
# -- lineto
my($x,$y) = getArgs(\@s,2);
+ $x *= SCALE_FACTOR;
+ $y *= SCALE_FACTOR;
$xp += $x, $yp += $y if($c eq 'l');
$xp = $x, $yp = $y if($c eq 'L');
pushPoint(\@o,$xp,$yp); $pc++;
@@ -179,6 +185,12 @@ sub decodePath {
# -- curveto
my($steps) = $a{bzsteps};
my($x1,$y1,$x2,$y2,$x,$y) = getArgs(\@s,6);
+ $x1 *= SCALE_FACTOR;
+ $y1 *= SCALE_FACTOR;
+ $x2 *= SCALE_FACTOR;
+ $y2 *= SCALE_FACTOR;
+ $x *= SCALE_FACTOR;
+ $y *= SCALE_FACTOR;
if($c eq 'c') {
$x1 += $xp; $y1 += $yp;
$x2 += $xp; $y2 += $yp;
@@ -199,6 +211,7 @@ sub decodePath {
} elsif($c eq 'h'||$c eq 'H') {
# -- hlineto
my($x) = getArgs(\@s,1);
+ $x *= SCALE_FACTOR;
$xp += $x if($c eq 'h');
$xp = $x if($c eq 'H');
pushPoint(\@o,$xp,$yp); $pc++;
@@ -206,6 +219,7 @@ sub decodePath {
} elsif($c eq 'v'||$c eq 'V') {
# -- vlineto
my($y) = getArgs(\@s,1);
+ $y *= SCALE_FACTOR;
$yp += $y if($c eq 'v');
$yp = $y if($c eq 'V');
pushPoint(\@o,$xp,$yp); $pc++;It would of course be ideal if the script resolved transforms and took units into account. Maybe replacing the XML::Simple with something with better context awareness from cpan might make that feasible? Until someone sufficiently motivated shows up with such a properly functioning pull request, I'm leaving the patch in this issue. Just in case it might help anyone with similar needs as mine.