SS - SVG Import tool (v1.12) [Layer Grouping, Masking, matched Colors and Adobe Illustrator/Affinity friendly]

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

User avatar
SimplSam
Posts: 1048
Joined: Thu Mar 13, 2014 5:09 pm
Location: London, UK
Contact:

SS - SVG Import tool (v1.12) [Layer Grouping, Masking, matched Colors and Adobe Illustrator/Affinity friendly]

Post by SimplSam »

SS SVG Import (v1.12)

SimplSam’s SVG Import is a Moho tool that allows you to reliably and faithfully import Scalable Vector Graphics (SVG) assets into Moho - ready for animation and presentation.

Image
The tool was developed as an upgrade/replacement to the existing built-in SVG import process, and provides a range of enhanced features to improve 3rd party SVG application compatibility and end-user productivity:

Enhanced Features:
  • SVG Grouping & Elements translate to Moho Groups, Layers & Shapes - allowing you to retain naming & folder structures
  • Vastly improved compatibility with Adobe Illustrator exported SVGs
  • Support for Element & Group Transforms (translate, rotate, scale, matrix, skewX/Y)
  • Handles CSS Class, Inline Style and Presentation attribute styling - with Hex #000000 / #000, Named and RGB/RGBA colors
  • Full support for Masking with both ClipPath and Mask masks
  • Provides support for Arcs, Rounded Rect’s, Use (referencing) and partial support for inline embedded SVGs
  • Like-for-Like point count & positioning (no extraneous points)
  • Multiple Image Sizing & Layer consolidation options during import
  • Retain SVG element ID’s in Moho groups, layers and/or shapes
  • Partial support for Gradients (Gradients are averaged to a single color)
  • Respect/Ignore comments / comment blocks in the SVG files
  • Provides a handy MRU feature for re-loading Most Recent Used imported files
  • Dialog Options which determine the import workflow: Dialog > Browse > Load -or- Browse > Dialog > Load -or- Browse > Load
So … Why do you need the SVG Import tool?

The tool allows for a much greater range of vector based Characters, Props, Scenery and Artwork to be imported directly into Moho - allowing you to faithfully reproduce, manipulate and incorporate artwork from Illustrator, Inkscape, Affinity Designer, CorelDraw and many other graphics/designer tools and SVG image repositories.

Some of the shortcomings of the built-in tool were its inability to fully support Grouping, Masking, CSS Styles, Short hex colors (#000), Use referencing and Arcs. Many of these features are used frequently in SVG imagery - which previously could lead to disfigured or discoloured artwork - or imported assets which failed to retain any grouping / layer structure or element naming.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Image
Mashed Up example: car.svg image file imported with the default tool (Picasso would be proud). When the asset was imported with new SVG Import tool, the SVG image was more faithfully reproduced.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Image
Layers & Naming example: monkey.svg image file imported with the default tool - which looks OK, but has no layers. When the asset was imported with the new SVG Import tool - the layer structure was retained.

----------------------------------------------------------------------------------------------------------------------------------------------------------------

Video Demo

Image

Tool Options

ImageImage
  • Specify the SVG Filename to be imported, or browse for a SVG file
  • Use the Recently Used (MRU) feature to quickly select a previously imported file name. The delete button can be used to remove selected entries from the list
  • Set Scaling to scale the size of the imported image asset relative to the Canvas screen size or relative to the original size of the asset (default: 50% Screen)
  • Use Center to align the imported image to the middle-center location of the Canvas
  • Use Consolidation to minify or reduce the number of Groups & Layers created in Moho (default)
    • Select Vector Layers to combine adjacent vector layers into one (default)
    • Select Group Layers to fold/ungroup Group Layers than only have one Vector layer in it - resulting in just a Vector Layer (default)
    • Use Only Unnamed will avoid consolidating named Elements (i.e. Elements with SVG IDs)
    • Post-operation reduction will aggressively reduce Groups and Layers after initial import. Good for getting absolute minimum number of layers (whilst respecting masking), but generally bad if you are planning character-type animation. The process can also be Slow
  • Expand Group Tree will expand the imported layer group tree to show all groups & layers
  • Use Reset to restore default settings. OK to load & process the specified SVG file. Cancel to Cancel
Tool Preferences

There is an additional Preference settings menu (top right) which allows you to:
ImageImage
  • Browse for file First when the tool button is clicked. More like a traditional File-Open experience. The main Dialog will be shown after the File Browse
  • Use Debug Info to show some limited process and error information during the import process
  • Use Hide Me to completely hide the main dialog (on subsequent imports). The importer will behave even-more like a traditional File-Open-process experience. ** This would typically be used if your settings remain the same during the majority of your imports. You can cancel out of Hide Me mode by Restarting/Reloading Moho
Version:
  • version: 01.12 MH12.5+ #521104
  • release: 1.12
  • by Sam Cogheil (SimplSam)
Download:
How do I get set up ?
  • To install:
    • Use the Moho ‘Scripts’ > ‘Install Script …’ menu (after you Download for Install Script, and extract the zip files)
    – or –
    • Save the ‘ss_svg_import.lua’ and ‘ss_svg_import.png’ files to your computer into your <custom>/scripts/tool folder
    • Save the ‘XmlParser.lua’, ‘xml2lua.lua’ and ‘dom.lua’ files your computer into <custom>/scripts/ScriptResources/xml2lua folder
    • Save the ‘ss_bin.png’ file to your computer into <custom>/scripts/ScriptResources/ss_tools folder
    • Reload Moho scripts (or Restart Moho)
  • To use:
    • Run the SVG Import tool from the Tools palette
    • A popup panel will appear allowing you to select a file and then review/adjust the import settings
Notes & Limitations

The tool was designed to enhance the Moho SVG import capabilities whilst supporting most common SVG 1.1 features and respecting SVG grouping. The tool is not and never will be 100% SVG 1.1 compliant, and as such has some limitations:

Known Limitations:
  • SVG Document and Viewport dimensions are ignored
  • Measurement Units are ignored (i.e. em, px, pt, cm, mm, in, %). All treated as pixels (px)
  • Gradients are averaged to a single color (scripting limitation)
  • No support for SVG <animate> or Filter effects
  • Limited support for ‘stroke-linecap’. No support for ‘stroke-linejoin’ (platform limitation)
  • Image, Text, Marker, Symbol, Pattern and ‘Hidden/Hide’ keywords are not supported
  • Limited SVG Syntax checking. SVG files should be valid before attempting import
  • Moho only supports the even-odd fill-rule
Additional Notes:
  • The tool has an external dependency on the XML 2 Lua parser (pure Lua)
  • Compatible with MH12.5+
  • Optimized for MH13.5+
Changelog:
  • 1.12 - Fix: Clipboard copy buffer
  • 1.11 - Fix: Filled Polyline’s
  • 1.10 - Add: Faux Gradient. Fix: line-width during Matrix scale. respect Unnamed during group & post-op reduce. un-default Unnamed option. +minor bugs.

Special Thanks to:
Last edited by SimplSam on Wed Mar 15, 2023 6:25 am, edited 6 times in total.
Moho 14.1 » Win 11 Pro 64GB » NVIDIA GTX 1080ti 11GB
Moho 14.1 » Mac mini 2012 8GB » macOS 10.15 Catalina
Tube: SimplSam


Sam
User avatar
lucasfranca
Posts: 128
Joined: Sat Oct 07, 2017 11:47 pm

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by lucasfranca »

Hey, how amazing! Our problems ended with the clipping mask that comes from Illustrator!

Thank you!
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.

I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.

https://youtube.com/animai2D
User avatar
Rai López
Posts: 2244
Joined: Sun Aug 08, 2004 1:41 pm
Location: Spain
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by Rai López »

WOW! (Super) Impressive work! I take my hat off to you 😌, it will not have been easy to get there... Congrats!
...
User avatar
Greenlaw
Posts: 9270
Joined: Mon Jun 19, 2006 5:45 pm
Location: Los Angeles
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by Greenlaw »

Wow! Yes, this looks VERY impressive SimplSam. Can't wait to try it out.

Thanks for sharing!
Daxel
Posts: 996
Joined: Wed Mar 27, 2019 8:34 pm

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by Daxel »

This is awesome! Thanks for sharing.
User avatar
hayasidist
Posts: 3529
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by hayasidist »

I'm on the road right now - back at base in a few days -- where I have an SVG file that Moho would never load properly ... this, I hope, will be the answer! Great work!
User avatar
lucasfranca
Posts: 128
Joined: Sat Oct 07, 2017 11:47 pm

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by lucasfranca »

Just for the record: Transparency isn't accepted yet, right?
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.

I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.

https://youtube.com/animai2D
User avatar
SimplSam
Posts: 1048
Joined: Thu Mar 13, 2014 5:09 pm
Location: London, UK
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by SimplSam »

lucasfranca wrote: Thu Oct 27, 2022 7:52 pm Just for the record: Transparency isn't accepted yet, right?
Transparency (Opacity) is accepted. What is the specific issue....?
Moho 14.1 » Win 11 Pro 64GB » NVIDIA GTX 1080ti 11GB
Moho 14.1 » Mac mini 2012 8GB » macOS 10.15 Catalina
Tube: SimplSam


Sam
User avatar
lucasfranca
Posts: 128
Joined: Sat Oct 07, 2017 11:47 pm

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by lucasfranca »

I did a quick test and the layers with transparency were gray...
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.

I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.

https://youtube.com/animai2D
User avatar
synthsin75
Posts: 9981
Joined: Mon Jan 14, 2008 11:20 pm
Location: Oklahoma
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by synthsin75 »

Wow, that looks like a ton of work.
Amazing, Sam.
User avatar
SimplSam
Posts: 1048
Joined: Thu Mar 13, 2014 5:09 pm
Location: London, UK
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by SimplSam »

lucasfranca wrote: Thu Oct 27, 2022 9:39 pm I did a quick test and the layers with transparency were gray...
The only time that should happen is if the layer/shape has a Gradient. Whilst Moho has gradients, there is currently no way to create them via scripting. So at the moment the tool 'ignores' all Gradient settings (including opacity) and renders them plain Gray. I have an update planned to render them in a color midway between the Gradient settings - to make it appear better, but still not 100%.

You can also feel free to post the file / sample somewhere and I will take a look.
Moho 14.1 » Win 11 Pro 64GB » NVIDIA GTX 1080ti 11GB
Moho 14.1 » Mac mini 2012 8GB » macOS 10.15 Catalina
Tube: SimplSam


Sam
User avatar
lucasfranca
Posts: 128
Joined: Sat Oct 07, 2017 11:47 pm

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by lucasfranca »

Oh yes. It's the gradient then. OK I understand now.
An old guy [since 1983] who was raised in front of the TV.
Passionate about animation, after getting old, he decides to make it his hobby.

I share tutorials, reviews, tips and tricks from this vast world of animation on my channel.

https://youtube.com/animai2D
User avatar
Lukas
Posts: 1297
Joined: Fri Apr 09, 2010 9:00 am
Location: Netherlands
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by Lukas »

Wow! Thanks for sharing, that's impressive.
User avatar
hayasidist
Posts: 3529
Joined: Wed Feb 16, 2011 8:12 pm
Location: Kent, England

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by hayasidist »

SimplSam wrote: Fri Oct 28, 2022 2:33 am The only time that should happen is if the layer/shape has a Gradient. Whilst Moho has gradients, there is currently no way to create them via scripting. ...
a couple pointers that might set you on a path to a solution.

yes - there's currently no way to create a gradient.

BUT take a look at how the scatterbrush works. That has a library of moho files and it does a copy/paste of a moho vector from its library into the current doc.. so if you had a doc with sample gradients (e.g. different shapes with (say) 2,3,4,5... stops and with radial / linear etc) you could import a "template". That template shape can then get the paths modified and the control handle placed using scripting.

the next challenge is setting the colours and the position of the gradient stops. This can be done via scripting - but it means accessing the animation channels.
here are two examples of that in action from earlier this year:



the scripts for those are not stand-alone (they're implemented as "plug-ins" to my test harness) - both based on the same fundamental structure. This is the one for the "rainbow circles":

Code: Select all

function HS_GradientPlay:Run(moho, view)

	HS_Test_harness:tracePrint (thisUUT, self:Name(), self:Version())

	moho.document:PrepUndo(moho.layer)
	moho.document:SetDirty()
	
	local layer = moho.layer
	local doc = moho.document

	local i, j, k, m, n, p, s, w
	local Pos = LM.Vector2:new_local()

	local mesh = moho:Mesh()

	local shape


	local orange = LM.ColorOps:RgbColor(255, 150, 0, 255)
	local indigo = LM.ColorOps:RgbColor(75, 0, 130, 255)
	local violet = LM.ColorOps:RgbColor(238, 130, 238, 255)



	local colours = {
		LM.ColorOps.Clear,
		LM.ColorOps.Red,
		orange,
		LM.ColorOps.Yellow,
		LM.ColorOps.Green,
		LM.ColorOps.Blue,
		indigo
	}

	local interval = 15 -- frames

--[[
--diagnostic
	HS_Test_harness:diagnosePrint (thisUUT, "# colours", #colours)
	local rgbCol = LM.rgb_color:new_local()
	for i = 1, #colours do
		rgbCol.r = colours[i].r
		rgbCol.g = colours[i].g
		rgbCol.b = colours[i].b
		rgbCol.a = colours[i].a
		HS_Test_harness:diagnosePrint (thisUUT, "colour", i, rgbCol)
	end
]]

	local cSS
	local selShapes = {}

	local selShapeEffectsChan, selSubChans
	local ctChannels
	local chInfo = MOHO.MohoLayerChannel:new_local()


-- find selected shapes
	for i = 0, mesh:CountShapes() - 1 do
		if mesh:Shape(i).fSelected then
			table.insert (selShapes, mesh:Shape(i))
		end
	end
	cSS = #selShapes
--	HS_Test_harness:diagnosePrint (thisUUT, "found", cSS, "selected shapes")


-- deselect all shapes
	for i = 0, mesh:CountShapes() - 1 do
		mesh:Shape(i).fSelected = false
	end

-- select shapes one by one
	for i = 1, cSS do
		shape = selShapes[i]
		shape.fSelected = true

-- get the shape effects channel for the selected shape
		ctChannels = layer:CountChannels()
--		HS_Test_harness:diagnosePrint (thisUUT, "Found", ctChannels, "channels in layer", layer:Name())

		selShapeEffectsChan = nil
		for j = 0, ctChannels do 

			layer:GetChannelInfo(j, chInfo)

			if chInfo.channelID == CHANNEL_SHAPEFX_SEL then
				HS_Test_harness:diagnosePrint (thisUUT, "Found Channel", chInfo.name:Buffer(), "With", chInfo.subChannelCount, "Sub Channels")
--				selShapeEffectsChan = layer:Channel(j, 0, doc)
				selShapeEffectsChan = j
				selSubChans = chInfo.subChannelCount
				break
			end
		end


-- get the gradient subchannels
		local gradCol = {}
		local gradStops = {}
		local gradChan, stopChan

		HS_Test_harness:diagnosePrint (thisUUT, "in layer", layer:Name(), "channel #", selShapeEffectsChan, "has", selSubChans, "subchannels")


		if selShapeEffectsChan then
			local stages = math.floor(doc:EndFrame()/interval)
			local stops = selSubChans / 2
			HS_Test_harness:diagnosePrint (thisUUT, "loops", stages, "stops", stops, "colours", #colours)

			for k = 1, selSubChans, 2 do
--				HS_Test_harness:diagnosePrint (thisUUT, "in layer", layer:Name(), "channel #", selShapeEffectsChan, "subchannel", k)

				gradChan = layer:Channel(selShapeEffectsChan, k, doc)
				if not gradChan then
					HS_Test_harness:tracePrint (thisUUT, "ooops" , k, "not a channel")
					break
--				else
--					HS_Test_harness:diagnosePrint (thisUUT, "sub chan is of type" , gradChan:ChannelType())
				end

				if gradChan:ChannelType() == MOHO.CHANNEL_COLOR then
					table.insert (gradCol, moho:ChannelAsAnimColor(gradChan))
--					HS_Test_harness:diagnosePrint (thisUUT, "sub chan" , k, "stored. Table has", #gradCol, "entries")
				else
					HS_Test_harness:diagnosePrint (thisUUT, "sub chan" , k, "is not a colour channel")
				end
			end


			for k = 0, selSubChans-1, 2 do
--				HS_Test_harness:diagnosePrint (thisUUT, "in layer", layer:Name(), "channel #", selShapeEffectsChan, "subchannel", k)

				stopChan = layer:Channel(selShapeEffectsChan, k, doc)
				if not stopChan then
					HS_Test_harness:tracePrint (thisUUT, "ooops" , k, "not a channel")
					break
--				else
--					HS_Test_harness:diagnosePrint (thisUUT, "sub chan is of type" , stopChan:ChannelType())
				end

				if stopChan:ChannelType() == MOHO.CHANNEL_VAL then
					table.insert (gradStops, moho:ChannelAsAnimVal(stopChan))
--					HS_Test_harness:diagnosePrint (thisUUT, "sub chan" , k, "stored. Table has", #gradStops, "entries")
				else
					HS_Test_harness:diagnosePrint (thisUUT, "sub chan" , k, "is not a value channel")
				end
			end



-- initialise the current gradient
                       	local interp = MOHO.InterpSetting:new_local()
                        interp.interpMode = MOHO.INTERP_LINEAR

			local frame = 1
			local oldCols = {}

			for k = 1, stops do
				gradCol[k]:SetValue(frame, colours[1])
				gradCol[k]:SetKeyInterp(frame, interp)
				gradCol[k]:ClearAfter(frame)
				oldCols[k] = 1

				gradStops[k]:SetValue(frame, (k-1) * (1 / (stops-1)))
				gradStops[k]:ClearAfter(frame)
--				HS_Test_harness:diagnosePrint (thisUUT, "set stop" , k, "to", (k-1) * (1 / (stops-1)))
			end


-- set the gradient values
			frame = 0
			local newCol
			local rgbCol = LM.rgb_color:new_local()

			for m = 1, stages do
				frame = m * interval
				newCol = 1 + math.fmod (m, #colours)
--				HS_Test_harness:diagnosePrint (thisUUT, "stage" , m, "frame", frame, "new colour is", newCol, colours[newCol])


				for k = stops, 1, -1 do
					if k == 1 then
						oldCols[1] = newCol
					else
						oldCols[k] = oldCols[k-1]
					end
					p = oldCols[k]
					rgbCol.r = colours[p].r
					rgbCol.g = colours[p].g
					rgbCol.b = colours[p].b
					rgbCol.a = colours[p].a
--					HS_Test_harness:diagnosePrint (thisUUT, "set colour", k, "to", rgbCol)
					gradCol[k]:SetValue(frame, rgbCol)
					gradCol[k]:SetKeyInterp(frame, interp)
				end
--[[
				s = "{"
				for n = 1, #oldCols do
					s = s .. tostring(oldCols[n]) .. ", "
				end
				s = s:sub(1, #s-2) .. "}"
				HS_Test_harness:diagnosePrint (thisUUT, "Old colours after stage", m, "are", s)
]]

			end

		end
		shape.fSelected = false

	end


-- restore selected shapes
	for i = 1, cSS do
		selShapes[i].fSelected = true
	end


end
User avatar
SimplSam
Posts: 1048
Joined: Thu Mar 13, 2014 5:09 pm
Location: London, UK
Contact:

Re: SS - SVG Import tool [Layer Grouping, Masking, matched Colors and Adobe Illustrator friendly]

Post by SimplSam »

hayasidist wrote: Fri Oct 28, 2022 2:59 pm a couple pointers that might set you on a path to a solution ...
Thanks. A very interesting approach. Something I may need to chew on for a while.
Moho 14.1 » Win 11 Pro 64GB » NVIDIA GTX 1080ti 11GB
Moho 14.1 » Mac mini 2012 8GB » macOS 10.15 Catalina
Tube: SimplSam


Sam
Post Reply