Page 1 of 2

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

Posted: Thu Oct 27, 2022 11:44 am
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:

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

Posted: Thu Oct 27, 2022 1:19 pm
by lucasfranca
Hey, how amazing! Our problems ended with the clipping mask that comes from Illustrator!

Thank you!

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

Posted: Thu Oct 27, 2022 2:30 pm
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!

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

Posted: Thu Oct 27, 2022 6:41 pm
by Greenlaw
Wow! Yes, this looks VERY impressive SimplSam. Can't wait to try it out.

Thanks for sharing!

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

Posted: Thu Oct 27, 2022 6:43 pm
by Daxel
This is awesome! Thanks for sharing.

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

Posted: Thu Oct 27, 2022 7:10 pm
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!

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

Posted: Thu Oct 27, 2022 7:52 pm
by lucasfranca
Just for the record: Transparency isn't accepted yet, right?

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

Posted: Thu Oct 27, 2022 8:31 pm
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....?

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

Posted: Thu Oct 27, 2022 9:39 pm
by lucasfranca
I did a quick test and the layers with transparency were gray...

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

Posted: Thu Oct 27, 2022 11:54 pm
by synthsin75
Wow, that looks like a ton of work.
Amazing, Sam.

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

Posted: Fri Oct 28, 2022 2:33 am
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.

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

Posted: Fri Oct 28, 2022 4:28 am
by lucasfranca
Oh yes. It's the gradient then. OK I understand now.

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

Posted: Fri Oct 28, 2022 12:33 pm
by Lukas
Wow! Thanks for sharing, that's impressive.

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

Posted: Fri Oct 28, 2022 2:59 pm
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

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

Posted: Fri Oct 28, 2022 5:02 pm
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.