Color values to skm code

cheers, it’s not really worth a wrapper in that case…

the PHP alternative for a ‘plugin’ would be to use Ruby for the ‘xml’, ‘Chuncky_PNG.gem’ for the Thumbnail, and ‘Rubyzip’ to create the skm…

a quick test returned png’s are a third of the size?

john

I checked the link you gave me … the documentation is slanted toward webservers which I find misleading and requires me to first download the Microsoft Web Platform Installer … however, in only a few minutes, I was able to download one of the binaries from “PHP For Windows: Binaries and sources Releases” and edit the system PATH and PATHEXT variables to get the CLI to work. Not terribly difficult to do, but it seems like a lot of work to add an import function to SketchUp. Normally, I advise against potentially invasive installs on a workstation to accomplish a single task (as a work-around, in this case). However, that said, the files are only about 42MB in size, require no registry edits, and now gives me a way to run PHP on my computer if I should ever need to do so. It’s a lot less invasive than installing Perl on my computer :wink:

1 Like

I cobbled a ruby version together …

you need ruby 2 version of SU use Gem.install ‘chunky_png’ and ‘rubyzip’,in Ruby Console, if you don’t have them…

require 'fileutils'
require 'chunky_png'
require 'zip' unless defined? Zip::File # workaround for SCF install...

  file = UI.openpanel('Select CSV File', '~', 'CSV Files|*.csv;||')
  base = File.basename(file, '.csv')
  mats = Sketchup.find_support_file('Materials')
  main = File.join(mats, base)
  Dir.mkdir(main) unless Dir.exist?(main)
  input = File.open(file, 'r')
  while (line = input.gets)
    values = line.split(',')
    name = values[1].rstrip
    r = values[2].to_i
    b = values[3].to_i
    g = values[4].to_i
    next if name == 'Name'
    png = ChunkyPNG::Image.new(64, 64, ChunkyPNG::Color::TRANSPARENT)
    for y in 1...64
      for x in 1...64
        png[x, y] = ChunkyPNG::Color.rgba(r, b, g, 255)
      end
    end
    col = File.join(main, name)
    Dir.mkdir(col) unless Dir.exist?(col)
    thumb = File.join(col, 'doc_thumbnail.png')
    png.save(thumb, interlace: true)

    document = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<materialDocument xmlns="http://sketchup.google.com/schemas/sketchup/1.0/material" xmlns:mat="http://sketchup.google.com/schemas/sketchup/1.0/material" xmlns:r="http://sketchup.google.com/schemas/1.0/references" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sketchup.google.com/schemas/sketchup/1.0/material http://sketchup.google.com/schemas/sketchup/1.0/material.xsd">

  <mat:material colorBlue="#{b}" colorGreen="#{g}" colorRed="#{r}" colorizeType="0" hasTexture="0" name="[#{name}]" trans="0" type="0" useTrans="0"/>

</materialDocument>

XML

    col_document = File.join(col, 'document.xml')
    File.open(col_document, 'w') { |f| f << document }

    refs = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<references xmlns="http://sketchup.google.com/schemas/1.0/references" xmlns:r="http://sketchup.google.com/schemas/1.0/references" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sketchup.google.com/schemas/1.0/references http://sketchup.google.com/schemas/1.0/references.xsd"/>

XML

    ref_document = File.join(col, 'references.xml')
    File.open(ref_document, 'w') { |f| f << refs }

    timestamp = Time.now.strftime('%F%Z%T.%LZ')

    documentProperties = <<XML
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<documentProperties xmlns="http://sketchup.google.com/schemas/1.0/documentproperties" xmlns:dp="http://sketchup.google.com/schemas/1.0/documentproperties" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://sketchup.google.com/schemas/1.0/documentproperties http://sketchup.google.com/schemas/1.0/documentproperties.xsd">

  <dp:title>[#{name}]</dp:title>

  <dp:description></dp:description>

  <dp:creator>csv2skm</dp:creator>

  <dp:keywords></dp:keywords>

  <dp:lastModifiedBy></dp:lastModifiedBy>

  <dp:revision>0</dp:revision>

  <dp:created>#{timestamp}</dp:created>

  <dp:modified>#{timestamp}</dp:modified>

  <dp:thumbnail>doc_thumbnail.png</dp:thumbnail>

  <dp:generator dp:name="Material" dp:version="1"/>

</documentProperties>

XML

    doc_Properties = File.join(col, 'documentProperties.xml')
    File.open(doc_Properties, 'w') { |f| f << documentProperties }

    input_filenames = [ 'document.xml', 'references.xml', 'documentProperties.xml', 'doc_thumbnail.png']
    zipfile_name = col + '.skm'
    Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
      input_filenames.each do |filename|
        zipfile.add(filename, col + '/' + filename)
      end
    end

    FileUtils.rm_rf(col)
  end
  input.close

3 Likes

I like this approach much better than having to install PHP to create the PNG files and zip them. Once again, @john_drivenupthewall, you’ve gone way over the top :slight_smile:

When I get back from vacation next year, I’ll add your code to my computer. My little netbook for-the-road only has SketchUp 8 so I can’t do it on here (but now it has PHP when I need it).

happy new year @ all.

@ lori

i have a script that change me RGB to skm

format is a csv file to import

color name,R,G,B

if you need this… i have this from Sd mitch in the scetchucation forum.
so i write this in excel and export this and than import.

4000 color is a little bit heavy… the script would work however a little bit waitig for result.

@john_drivenupthewall - it worked great John! the only issue was Sketchup got very cranky and unstable loading all 4000+ colors. I ended up separating the materials libraries into smaller chunks (1500 per library) and that made everyone happy. Thanks again for your help - it’s safe to say I wouldn’t have made the deadline without it :smile:

that’s good news…
did you use the ruby or php version?

was that when using the ruby script or on restarting SU with a 4000 material folder?

john

I used the php version. The unstable part was after restarting with loading 4000 materials folder. I used SU 2015 since 2016 had warnings about backwards compatibility so I’m not sure if it would’ve worked better with 2016.

The Sketchup plugin what i use work with 2016 and you can safe in all other formats like 2015 and older

@john_drivenupthewall Hi! You were so kind as to create the awesome PHP script in this thread for me back at the end of 2015. I have to perform the same task again and have completely forgotten how to use the PHP script. Would it be possible for you to refresh my memory? ~ lori

Since SU2017 this can all be done by the SketchUp API without the gems.

1 Like

hi Dan, lori has upgraded to SU v16…

else material.save_as(filename) would do the trick…

john

okay, well Sketchup::Material#write_thumbnail has been around since SketchUp 8.0 M1, so probably no need for Chunky at least. Still will need RubyZip.

1 Like

@lori, see if you can go to SU v17 at least…

john

@john_drivenupthewall I just updated to SU 2020 pro. Does that help?

2 Likes

@lori

this works in v19 and v20 on my mac…

    version = Sketchup.version.to_i
    osx     = Sketchup.platform == :platform_osx
    # select a colour list
    file = UI.openpanel(
      'Select CSV File',
      osx ? '~' : ENV['HOME'],
      osx ? '*.csv' : 'CSV Files|*.csv||'
    )

    if version >= 17
      # extract folder name
      dir = File.basename(file, '.csv')

      # create array of name and hex value
      require 'csv.rb'
      csv_data = CSV.foreach(file, headers: true).map do |row|
        h = row.to_h
        n = h['Name'].split(' ').map(&:capitalize).join(' ').rstrip
        c = [ h['R'].to_i, h['G'].to_i, h['B'].to_i ]
        [n,c]
      end

      #create new material
      # Get a handle to all the materials in the current model.
      model = Sketchup.active_model
      mats = model.materials
      path = Sketchup.find_support_file('Materials')
      main = File.join(path, dir)
      Dir.mkdir(main) unless Dir.exist?(main)

      # process data
      mats.purge_unused
      @mat = mats.add('placeholder')
      csv_data.each do |name,colour|
        filename = File.join(main, name + '.skm')
        @mat.name = name
        @mat.color = Sketchup::Color.new(colour.entries)
        @mat.save_as(filename)
      end
    end

the test css I used is color-samples.zip (439 Bytes)

to run either copy paste the code into Ruby Console or use

EDIT removed file for now…

load ' <drag the downloaded file here, replacing this text> '

and hit Enter…

john

1 Like

This is awesome! One quick thing - I’m on a PC, do I need to add something to the top part where osx is?

No Lori that’s just a local reference used for conditional expressions.

Just note that …

file = UI.openpanel('Select CSV File', '~', 'CSV Files|*.csv;||')

… on Windows defaults to the current working directory which is probably your user Documents folder.


@John… it’s safer & cross platform to use ENV["HOME"] instead of "~" (SketchUp adds the HOME variable to the environment when it loads on Windows.)

Oh … ADD: … another thing for windows filetype filters, only use a semicolon when there are multiple types listed. Your example displays as …

image

… so the semicolon after “*.csv” is frivolous and looks a bit weird as if the choice has a semicolon as part of the file extension.

1 Like

Actually john didn’t even use the osx reference, but could have like …

    file = UI.openpanel(
      'Select CSV File',
      osx ? '~' : ENV['HOME'],
      osx ? '*.csv' : 'CSV Files|*.csv||'
    )

… instead of the 5th statement.

1 Like

I’ll update the code as I normally do similar to Dan’s suggestion for UI.openpanel

the reference was there for some mac SU version testing…

totally useless on a windows PC…

      if osx & (version != 20)
        %x[
          osascript -e 'tell application "System Events" to key code 124 using control down'
          sleep 1
          osascript -e 'tell application "System Events" to key code 123 using control down'
        ]
      end

john