Google SketchUp закрыть файл - PullRequest
       3

Google SketchUp закрыть файл

1 голос
/ 13 февраля 2011

API Ruby для Google SketchUp имеет функцию open_file, но я не могу найти функцию close_file. Так как мне нужно обрабатывать много файлов в пакетном режиме, я хочу закрыть каждый файл, прежде чем переходить к следующему, в противном случае программа вылетит из-за нехватки памяти.

Как лучше всего программно закрыть файлы SketchUp?

Я использую Mac OS X и хочу использовать функции AppleScript, чтобы сигнализировать о закрытии окна.

EDIT

Я рассматриваю несколько подходов, которые до сих пор оказались бесплодными.

  1. Использование приложения Ruby Gem, как описано в этот вопрос . Проблема в том, что Я не могу заставить SketchUp распознавать мои установленные драгоценные камни .
  2. Аналогичным образом я пытаюсь использовать osascript (программа bash, которая выполняет сценарии AppleScripts из оболочки), чтобы закрыть окно. То есть я вызываю оболочку из окна консоли SketchUp Ruby, используя одно из следующих действий:

    % x [osascript -e 'говорит приложению "SketchUp" закрыть окно 1']

    % x [osascript -e 'говорит приложению "SketchUp" закрыть окно 1' &]

    % x [osascript -e 'сообщает приложению "SketchUp", чтобы оно закрывало каждое окно "]

    % x [osascript -e 'говорит приложению "SketchUp" закрыть каждое окно "&]

    Всякий раз, когда я пробую этот второй подход, SketchUp просто зависает. Однако когда я выполняю любую этих команд из IRB или непосредственно из приглашения Bash вне SketchUp, я получаю желаемое поведение: окно модели закрывается (кстати, окно консоли Ruby остается открытым, что штраф).

  3. Иметь главный скрипт, который запускает подчиненный скрипт для обработки каждой модели. Подчиненный будет работать в программе Google SketchUp, пока мастер ждет. Когда ведомое устройство заканчивается, оно сигнализирует мастеру, и мастер закрывает файл SketchUp. Чтобы сделать это межпроцессное взаимодействие, я попытался использовать drb . Однако, когда я пытаюсь потребовать drb в SketchUp, я получаю следующее сообщение:

Ошибка: LoadError: (eval): 5: в 'require': такой файл не загружается - drb

РЕДАКТИРОВАТЬ 2

Постоянно работающий отдельный процесс, который закрывает окна Google Sketchup с помощью AppleScript при получении сигнала, является неуклюжим по ряду причин. Во-первых, некрасиво иметь отдельный процесс, посвященный закрытию окон Sketchup. Во-вторых, единственный эффективный способ связи с внешним сценарием - создание файлов, что является расточительным, а доступ к диску может замедлять работу.

Однако наиболее серьезная проблема заключается в том, что Sketchup медленно реагирует на команды AppleScript. У меня в Sketchup запущен довольно требовательный к вычислениям сценарий, и он, похоже, лишает ответа AppleScript, что означает, что время ожидания osascript истекло до закрытия окон. Sketchup реагирует на AppleScript только тогда, когда в Sketchup появляется диалоговое окно, которое приостанавливает выполнение моего сценария с интенсивными вычислениями.

РЕДАКТИРОВАТЬ 3

Я изменил свою функцию close_file, чтобы приостановить выполнение скрипта, отображая диалоговое окно. По сути, это возвращает текущий поток и позволяет потоку, который отвечает на команды AppleScript, выполнить:

def close_file()
  f = '/temp/mutex.txt' # for finer control, use different mutex for each window you want closed
  File.new(f, 'w').close
  result = UI.messagebox "Click OK when window has closed."
end

Тогда отдельный скрипт ruby, который закрывает окна через AppleScript, дополнительно должен будет нажать «ОК» в диалоговом окне. AppleScript, чтобы сделать это:

tell application "System Events"
    tell process "SketchUp"
        set frontmost to true
        keystroke return
    end tell
end tell

Эта модификация является улучшением. Он исправляет «наиболее серьезную проблему», упомянутую в EDIT 2, но другие проблемы остаются.

Ответы [ 4 ]

2 голосов
/ 21 августа 2011

Существует важное ограничение при использовании внешнего AppleScript, чтобы заставить SketchUp что-то делать. SketchUp не будет принимать пользовательский ввод во время выполнения сценария меню.

Я обнаружил это, пытаясь настроить решение для автоматического рендеринга. Я добавил пункт меню, который открывает WebDialog, чтобы получить список моделей для загрузки с сервера. Затем он проходит по списку и использует cURL для загрузки каждой модели. После загрузки он загружает модель, выдает ее, загружает изображения снова, используя cURL, и переходит к следующей модели.

Я хотел активировать AppleScript после рендеринга каждой модели (используя решение для файла mutex, показанное выше) и закрыть окно модели. К сожалению, поскольку скрипт меню все еще выполняется, SketchUp не будет отвечать ни на что, что AppleScript говорит ему делать. Только после того, как все модели будут обработаны и сценарий меню завершится, AppleScript, наконец, запустится.

Это было бы не так плохо, если бы все вызовы AppleScript были поставлены в очередь, но это не так. Кажется, что только последние два признаются (это число может быть просто случайностью, зависящей от времени, когда мои вызовы AppleScript были сделаны относительно завершения сценария меню).

Из-за этого ограничения я не смог использовать функцию mutex wait () в моем коде Ruby меню. Так как AppleScript не был в состоянии выполнить, он никогда не создавал свой мьютексный файл «Я закончил», и поэтому функция wait () в Ruby никогда не получала сигнал о том, что может продолжаться. В результате между AppleScript и SketchUp возникла тупиковая ситуация, так что SketchUp просто зависает (ну, на самом деле, он просто застрял в очень тесном цикле в функции wait ()).

Итак, когда вы подходите к этой проблеме, подумайте об AppleScript как о средстве очистки, которое вы можете вызвать, когда закончится вся ваша обработка.

0 голосов
/ 21 февраля 2011

С SketchUp вы можете многое сделать, используя applecript и / или Automator.

tell application "SketchUp"
activate
tell application "System Events"
    delay 1.0 --close window, adjust delay to suit
    --key code 13 using command down -- Press ⌘W or you can use
    keystroke "w" using command down
end tell

конец сказать

У меня есть несколько пунктов строки состояния для открытия нового, вставки в консоль, закрытия, уничтожения SU и т. Д.

Это крошечные файлы, которые запускают сочетания клавиш SU и могут использоваться извне, из 'Ruby Console' или как часть плагина.

Я не уверен, какого типа «конвертирование» вы пытаетесь достичь, но Я использовал Automator для преобразования большинства моих старых файлов v5, V6, v7 в v8 сегодня ... 100 из них, и вы, вероятно, знаете, что при открытии вы получите предупреждение, что сохранение преобразует файл в последнюю версию (что я и хотел).

Сложно нажимать это «ОК» программно.

Сам по себе Automator довольно ограничен, но вы можете добавить в рабочий процесс appleScript, и я обнаружил, что если вы используете его «функцию записи», чтобы продемонстрировать, что вам нужно сделать.

Затем вы можете скопировать / вставить этот код в «Редактор сценариев», избавиться от битов «dowithTimeout», скопировать его обратно в рабочий процесс с задержками по обе стороны и запустить.

Мне пришлось потренироваться с задержками, чтобы вместить несколько больших файлов, но я добился> 95% успеха. [Успешно выбрать все, щелкнуть правой кнопкой мыши, Создать иконку и Предварительный просмотр.]

К сожалению, я затем скопировал рабочий процесс, но мог бы воссоздать его, если вы хотите посмотреть.

0 голосов
/ 26 февраля 2011

успех, в Ruby Console system("osascript -e 'tell application \"suoff\"' -e 'activate' -e 'end tell'") и этот скрипт внутри Automator.app в папке приложений ....

    on run
    -- Make sure SU is foremost, don't click on anything else either
    tell application "System Events"
    tell process "SketchUp"
        set frontmost to true
        -- gives a message if you try to select when SU's not running
        delay 0.2
        tell application "SketchUp" to quit saving no
        -- no dialog box etc...
        delay 0.1

    end tell
    end tell
    end run

проблема в том, что SU имеет рубин анти-самоуничтожения, который добывает любые связанные файлы и прерывает все попытки закрыть его ... изнутри.

так что тебе нужно его похоронить ...

эта комбинация работает на 10.5.8 с SU8.1.

если вы загляните на форум SketchUcation [Developer], я оставил вызов для тестировщиков mac / applecript ... С тех пор я переписал приложение, но если вы отправите мне в личку, я вышлю вам открытую копию биты у меня работают ..

джон

0 голосов
/ 14 февраля 2011

Одним из решений является непрерывный запуск отдельного процесса, который будет закрывать окна Google Sketchup с помощью AppleScript при получении сигнала. Описанный здесь подход использует файлы для межпроцессного взаимодействия (похоже, что drb не работает).

Сначала убедитесь, что Sketchup поддерживает AppleScripting . Для этого выполните в командной строке следующее (с соответствующими заменами для разных версий Sketchup и т. Д.):

$ defaults write /Applications/Google\ SketchUp\ 8/SketchUp.app/Contents/Info NSAppleScriptEnabled -bool YES

Теперь создайте отдельный файл, который закроет окна Sketchup. Вот мой closer.rb файл:

#!/usr/bin/ruby

## closer.rb ##

def wait(f)
  while !File::exists?(f)
  end 
  File.delete(f)
end

def signal(f)
  File.new(f, 'w').close
end

while true
  wait('~/temp/mutex.txt')
  msg = %x[osascript -e 'tell application "SketchUp" to close every window'] 
  signal('~/temp/conf.txt')
end

Запустите этот скрипт из оболочки. Он ждет, пока файл ~/temp/mutex.txt не будет создан. После создания файла он запускает osascript (по сути, AppleScript), чтобы закрыть все окна в Sketchup, а затем сообщает, что окна были закрыты, создав файл ~/temp/conf.txt.

Вот код клиента (который может быть помещен в ваши плагины Sketchup), который сигнализирует ближайший скрипт:

def wait(f)
  while !File::exists?(f)
  end 
  File.delete(f)
end

def signal(f)
  File.new(f, 'w').close
end

def close_file
  signal('~/temp/mutex.txt')
  wait('~/temp/conf.txt')
end

close_file сигнализирует ближайший сценарий и затем ожидает подтверждения, что файл был закрыт, прежде чем вернуться. Теперь вы можете закрывать файлы в Sketchup.

...