При проектировании часто приходится работать с чертежами выполненными другими людьми и, разумеется, они наделяют объекты теми цветами которые сочтут нужными. Цвета эти не всегда "по слою" и часть из них находится внутри блоков вложенных друг в друга произвольным образом. Нужен простой и быстрый способ сократить палитру чтобы не тратить лишнее время на подготовку чертежа к работе. Свой способ решения этой задачи я и хочу представить в этой статье.

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

var ut = ThisDrawing.Utility

ut.Prompt("Запуск очистки цветов блоков.")

// Получаем коллекцию блоков данного чертежа
var blocks = ThisDrawing.Blocks
// Объявляем переменную для блока понадобится позже
var block

ut.Prompt("Всего блоков (вместе с системными): " + blocks.Count)

// Проходим по всем блокам и меняем цвет всех объектов на по слою
for (i = 0; i<blocks.Count; i++) {
  // Проверяем что название блока начинается не со *
  // т.к. со * начинаются системные блоки для пространства модели и листов.
  if (blocks.Item(i).Name.charAt(0) != "*") {
    block = blocks.Item(i)
    ut.Prompt(blocks.Item(i).Name)
    // В каждом блоке проходим по всем его элементам
    for (j=0; j<block.Count; j++){
      // Меняем цвет каждого объекта.
      // Цвет 256 это как раз по слою.
      block.Item(j).Color = 256
    }
  }
}

Мы имеем доступ к текущему чертежу через глобальное имя ThisDrawing.
Utility нам пригодится чтобы выводить данные о работе программы в консоль (через Prompt). С бегущим списком редактируемых блоков ожидание воспринимается спокойнее (хотя возможно стоит добавить какой-нибудь простенький индикатор прогресса на основе количества отредактированных блоков).
И далее мы просто проходимся по всем элементам всех блоков и выставляем нужный цвет.

Как видим, скрипт выглядит совсем не сложно. Всю информацию я взял напрямую из документации, которую раздают всем желающим на форуме разработчиков (хотя обилие заполняемых форм несколько отпугивает). Далее скрипт можно без проблем зарегистрировать как команду в Нанокаде, несложную инструкцию вы можете найти там же - в документации.

Теперь перейдем к обещанному способу применения без знаний программирования. Всё что нужно это ввести в Нанокаде команду nsf и указать путь к текстовому файлу в кодировке utf-8 (формат файла при этом не принципиален, это может быть обычный .txt) с примерно следующим содержанием (структура довольно проста так что можете поправить что-то по вкусу):

<?xml version="1.0" encoding="utf-8"?>
<package>

  <description>Set all colors to 256</description>
  <command name="blocks_colors" weight="30" cmdtype="1" caps="4">
    <description>Set colors of objects inside all blocks to 256</description>
    <script lang="JScript">
      <![CDATA[




var ut = ThisDrawing.Utility

ut.Prompt("Запуск очистки цветов блоков.")

// Получаем коллекцию блоков данного чертежа
var blocks = ThisDrawing.Blocks
// Объявляем переменную для блока понадобится позже
var block

ut.Prompt("Всего блоков (вместе с системными): " + blocks.Count)

// Проходим по всем блокам и меняем цвет всех объектов на по слою
for (i = 0; i<blocks.Count; i++) {
  // Проверяем что название блока начинается не со *
  // т.к. со * начинаются системные блоки для пространства модели и листов.
  if (blocks.Item(i).Name.charAt(0) != "*") {
    block = blocks.Item(i)
    ut.Prompt(blocks.Item(i).Name)
    // В каждом блоке проходим по всем его элементам
    for (j=0; j<block.Count; j++){
      // Меняем цвет каждого объекта.
      // Цвет 256 это как раз по слою.
      block.Item(j).Color = 256
    }
  }
}




]]></script>
  </command>


</package>

После чего в Нанокаде появится команда blocks_colors, запускающая скрипт. Будьте осторожны если уже используете другие скрипты. В таком случае можете подредактировать файл со скриптами (он устроен интуитивно понятно) добавив туда написанную мной команду.

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

Комментарии (3)


  1. fonkalitin
    13.09.2023 10:52
    +1

    А это зачем:

    (blocks.Item(i).Name.charAt(0) != "*")

    ?

    В каком IDE писали код?

    Есть ли во встроенном редакторе скриптов NanoCad автокомплит методов? Или нужно всё искать в документации?


    1. Glasssparrow Автор
      13.09.2023 10:52

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

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

      Автокомплита, к сожалению, нет. Да, всё нужно искать в документации (примеры кода, к слову там тоже есть), еще можно спросить на форуме. В общем-то это основные источники информации, вне форума разработчиков информации вообще не так много (или может я искать не умею, что вполне вероятно).


      1. Glasssparrow Автор
        13.09.2023 10:52

        P.S. решил что стоит добавить комментарии к проверке условия в код в статье для улучшения читаемости кода.