1
$\begingroup$

I have been experimenting with importing SVG files to use as Curves in Blender. However, when I import them using File → Import → Scalable Vector Graphics (.svg), they appear tiny and with a slightly-wrong aspect ratio. As an example, here is a simple SVG I tested:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
    <rect width="100" height="100"/>
</svg>

This should have a width in the X dimension of 100 and a width in the Y dimension of 100. However, when imported, it appears with an X dimension of 0.0282228 m and a Y dimension of 0.0282168 m, requiring an X-scale of 3543.23454795 and a Y-scale of 3543.98797879 to bring it up to the correct size. I've tested several different SVGs with different sizes, and they all need close to (but not exactly) the same scale factors.

Why do imported SVGs have those particular scale factors, and why is the scale factor slightly different in each dimension?

A logical assumption is that Blender treats SVGs as using different units than Blender itself, but I can't figure out what units that would be. It seems that 100 SVG-units equals approximately 28.2198 mm or 1.11102 inches, neither of which is a clean number, so it doesn't appear that Blender's SVG units are metric or imperial. And whatever units it's actually using, I can't figure out why they differ between dimensions.

$\endgroup$
2
  • $\begingroup$ because your values are too small. instead of using 76.555, use 765.55 instead because blender interprets the values as mm. $\endgroup$ Dec 4, 2023 at 3:00
  • $\begingroup$ @HarryMcKenzie I tried bumping the SVG values all the way up to 7655.5 and the scale factor needed to bring it to the correct size is still 35.432287 by 35.439812 -- closer to uniform, but still an unexpected number. It can't be assuming the SVG units are millimeters, or even metric, because I have Blender's units set to meters, so if it was treating the SVG units as metric as well the scale factor would at least be a power of ten. $\endgroup$
    – Lawton
    Dec 4, 2023 at 14:07

1 Answer 1

2
$\begingroup$

The importer reads the information in your SVG file - like in which units it was created. Then converts it to Blender units set in the Scene properties. This may not work very well if you have different scene units.

It will work best if you match them before importing. For example if your SVG document uses Millimeters - set the Blender Unit system to Metric and Length to Millimeters.

In case there is no any information about the metric system as in your example it will import it with default settings.

To fix it just add "mm" after the width and height:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100mm" height="100mm" viewBox="0 0 100 100">
    <rect width="100" height="100"/>
</svg>

and import using the bolded out recommendation above

To match the dimensions of the unit-less SVG file to a Metric unit - Millimeters, multiply the scale of your objects by 3.54331 after importing, then scale the shapes up or down by (10, 100 ... or 0.1, 0.01... etc.) to match them to another unit (cm, m, etc).

Parts of the code related to the units can be found in the add-on files in ..4.0\scripts\addons\io_curve_svg

svg_util.py

units = {"": 1.0,
     "px": 1.0,
     "in": 90.0,
     "mm": 90.0 / 25.4,
     "cm": 90.0 / 2.54,
     "pt": 1.25,
     "pc": 15.0,
     "em": 1.0,
     "ex": 1.0,
     "INVALID": 1.0,  # some DocBook files contain this
     }

and import_svg.py

        if len(viewbox) == 4 and unit in ('cm', 'mm', 'in', 'pt', 'pc'):

        #convert units to BU:
        unitscale = units[unit] / 90 * 1000 / 39.3701

        #apply blender unit scale:
        unitscale = unitscale / bpy.context.scene.unit_settings.scale_length

        matrix = matrix @ Matrix.Scale(unitscale, 4, Vector((1.0, 0.0, 0.0)))
        matrix = matrix @ Matrix.Scale(unitscale, 4, Vector((0.0, 1.0, 0.0)))
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .