Joshua Stream Pre
  1. #1

    Generating LOS via SVG from GIMP

    Hi all,

    I create a lot of my own maps, and wanted the ability to use GIMP to select the negative areas of the maps, and use that as the basis for my walls.
    I know theres been some conversations about how to create LOS Walls, in the forums, but this is my own take on it.

    The process is based around making a selection in GIMP.
    Screenshot 2020-10-25 154041.png

    Convert that to a PATH, (Menu: Select-> To Path)


    Now Export it as a SVG File.
    Screenshot 2020-10-25 154140.png

    The SVG export from GIMP seems to be pretty specific SVG format, so I don't promise this works for all SVGs.
    Screenshot 2020-10-25 155356.png

    Then run the below powershell script that, for all SVG files in a directory:
    1. Gets the image size. (This is needed to convert to FGU's Frame of Reference: 0,0 at the centre, and orientation: Y axis reversed)
    2. Parse the path coords, and storing them in a List.
    3. Parse the List, removing doubles, (I extended this to reduce the number of points, by distance.)
    4. Output the list to the same filename as the svg, in the XML Occluder format that FGU's db.xml expects.

    Then you take that xml, find your Image Layer in your dbxml and put it in there.
    Screenshot 2020-10-25 155432.png

    Done!!
    Screenshot 2020-10-25 155537.png


    Note it only handles walls. But of course, you could just make selection paths for all the different features in gimp, and just toggle their type in the db.xml.

    Hope this helps someone!!
    Muklin

    Here is the powershell:

    Code:
    param(
        [String]$filePath = $PWD,
        [Int]$SmoothDistance = 10
    )
    
    if(test-path -path $filePath){
        $files = Get-ChildItem -name $filePath -Include *.svg
    }
    
    $files | %{
        $file= $filePath+"\"+$_
        $filename = $_ -replace ".svg",".occ"
        Write-Output "Processing $file..."
    
        if([System.IO.File]::Exists($file)){
            $content = get-content $file
        }else{
            Write-Error "Could not find file $file"
            exit 2
        }
    
        $matchResult = [regex]::Match($content,"viewBox=\`"0 0 ([0-9]+) ([0-9]+)\`"")
        $xWide = $matchResult.Groups[1].Value
        $yHigh = $matchResult.Groups[2].Value
    
        Write-Host "Detected an image $xWide by $yHigh"
    
        $xWideMod = $xWide/2
        $yHighMod = $yHigh/2 
    
        "<occluders>" | Out-file -Filepath $filename
        $occludercount = 0 
        $m = Select-String -InputObject $content -Pattern "C[0-9., `r`n]+Z" -AllMatches
        $array = [System.Collections.ArrayList]@()
        $m.Matches | %{
            $line = $_.Value.trim("C").trim("Z")
            $matching = Select-String -InputObject $line -Pattern "([0-9\.,]+)" -AllMatches
    
            foreach($match in $matching.Matches){
                $coord = $match.Value.split(",")
                $coord[0] = $coord[0] -as [int]
                $coord[1] = $coord[1] -as [int]
                                
                if($array.Count -gt 0 -and [Math]::Pow($array[-1][0]-$coord[0],2)+[Math]::Pow($array[-1][1]-$coord[1],2) -lt [Math]::Pow($SmoothDistance,2) ) {
                    #"discarded a point"
                }else{
                    $array.Add($coord) | Out-Null
                }
            }
            $out = ""
            $array | %{
                $modX = $_[0]-$xWideMod -as [String]
                $modY = $yHighMod-$_[1] -as [String]
                $out = $out+$modX+","+$modY+","
            }
            
            "`t<occluder>" | Out-file -append -Filepath $filename 
            "`t`t<id>$occludercount</id>" | Out-file -append -Filepath $filename 
            "`t`t<points>$($out.trim(","))</points>" | Out-file -append -Filepath $filename 
            "`t`t<closedpolygon>true</closedpolygon>" | Out-file -append -Filepath $filename 
            "`t</occluder>" | Out-file -append -Filepath $filename 
            $occludercount++
            $array.RemoveRange(0,$array.Count)
        }
        "</occluders>" | Out-file -append -Filepath $filename 
    }
    Last edited by muklin; October 26th, 2020 at 23:07.

  2. #2
    yako2020's Avatar
    Join Date
    Sep 2012
    Location
    São Carlos, São Paulo - Brazil
    Posts
    1,198
    I would like to take some questions:
    1 - Can I do this type of export only with GIMP?
    2 - Are the colors defined by the Pen Tool that define the type of LoS or not?
    3 - Where would that Script be used at the end?
    [FGC AND FGU ULTIMATE LICENSE HOLDER][BRAZILIAN][GMT-3]
    [D&D 5 PLAYER][CALL OF CTHULHU PLAYER][SAVAGE WORLDS PLAYER][GURPS PLAYER AND LOVER]
    [FANTASY GROUNDS STREAMER ON TWITCH]


  3. #3
    1. The workflow I described is only tested using Gimp to create an SVG. Potentially, some other SVGs would work, but probably not. Potentially even other versions of GIMP wouldn't work.
    2. This is for FGU. See the LOS videos you can find linked in various places on this forum to see how LOS in FGU works.
    3. The script converts the SVG to the occluder data, to be inserted into the db.xml file for your campaign. So you'd use it after you created the SVG. As mentioned in the post.

  4. #4
    This is cool, thanks. Any chance of a brief step by step video explaining it further for those familiar with GIMP but not the dbxml files? (I don’t even know what those are).

  5. #5
    Quote Originally Posted by TheFabulousIronChef View Post
    This is cool, thanks. Any chance of a brief step by step video explaining it further for those familiar with GIMP but not the dbxml files? (I don’t even know what those are).
    db.xml is the main xml file that FG and FGU use to store the state of your campaign.

    You can find the file by browsing to the Fantasy Grounds Data directory.
    There are various links to this directory in the application, but also see:
    https://www.fantasygrounds.com/wiki/...Files_Overview

    Which says:
    "The Fantasy Grounds data folder is specified in the FG Settings when installing FG.
    The easiest way to access the data directory is to click the folder icon in the top right of the main FG startup screen. This will open a new file explorer window at the root of the data directory. "

    Inside here, browse to campaigns/<your campaign name
    db.xml will be in there, and is just a big ol xml file with the data in your campaign.

    A few notes and disclaimers on working with db.xml
    DISCLAIMER: All this information is what I've reverse engineered from using FG over the years. Take it with a grain of salt. It worked for me. I don't take responsibility for any loss of data.
    1. Before anything else, BACKUP your current db.xml. If you make a mistake, then you might end up losing everything. Having a back up is always a good idea.
    2. I recommend you only edit db.xml while your campaign is not loaded. This will save you heartache of making lots of edits in the file, only for FG to overwrite it when you make changes in the application.
    2a. Alternatively, you can use the /reload and /save command lines in FG to force it to load changes.
    3. Load the image you want to change into the campaign first, then close the campaign. this will create the image xml node in the db.xml.
    4. Alter the image node to have, (or replace, or alter) the generated <occluders> sub node.
    5. Save your file.
    6. Reload your campaign.
    7. Open the map and see if your occluders are set as you need them.
    8. Rinse and repeat til you're happy.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
FG Spreadshirt Swag

Log in

Log in