Сохранение цвета элемента в БД Navisworks

Предыстория задачи


Возникла у заказчика задача, допустим, такая:


  • Скинуть в 1С элементы модели здания.
  • В 1С использовать эти части модели в договорах – ну, допустим, указать, что вот такие-то элементы уже построены, такие-то – только запланированы, и т.п..
  • В Navisworks на чертеже как-то увидеть это – например, отобразив элементы модели разными цветами. Для этого сделали к Navisworks плагин, который умеет копировать в 1С данные из таблиц Quantification (Takeoff tables), а также забирать их из 1С обратно и запихивать в Takeoff tables.
    А в 1С предполагалось у используемых в договоре элементов модели (помещений) менять цвета.

Только вот оказалось, что после изменения этих табличных данных в 1С – Navisworks не понимает, что они изменились, и надо бы их обновить. Стало быть, мне, программисту, надо ему это подсказать.


Итак, задача для программиста


После обмена с 1С изменились данные в таблице TK_Item – в частности, поле Color. Необходимо привести цвета на отображаемом чертеже в соответствие с указанными в таблице.


Ищем, как это сделать. Копаем описание. Находим функцию –


public void OverridePermanentColor(IEnumerable<ModelItem> items, Color color)

Ну, как найти соответствующие выбранному элементу TK_Item элементы модели – это другая история, в другой раз расскажу, если будет интересно. Но кому надо – и сам разберется. А вот с цветом все оказалось интереснее.
Во-первых, указанный в параметрах функции Color – это не System.Drawing.Color, а вовсе даже Autodesk.Navisworks.Api.Color, со своим блекджеком и … ну, вы поняли. Ну, пускай, зато у него есть вот такой конструктор:


public static unsafe Color FromByteRGB(byte red, byte green, byte blue)

Стало быть, без проблем сделаем такой Color, какой Автодесковскому API нужен.
(Собственно, первым делом я это и попробовать – найти элементы, соответствующие выбранному Item'у, выбрать цвет – и установить им это цвет.)


Но. В таблице-то у нас в поле Color стоит одно значение типа Int64. И как его сопоставить с объектом типа Color – непонятно.


Причем ни в документации, ни на форуме, ни в примерах мне не удалось найти, как это пишется в БД.


ОК, будем копать экспериментальным путем.


Берем Navisworks, открываем Quantification, меняем у какого-нибудь элемента цвет. Скажем, на честный беспримесный Red.


image


После этого берем наш плагин, выкачиваем им данные из таблицы TK_Item, и смотрим, что там в таблице?


(Благо, в плагине для отладочных целей был предусмотрен такой вариант – выкачать данные и показать на форме.)


Там, оказывается, стоит -65536.


image


Повторяем процедуру несколько раз и сводим результаты в текстовый файл.


Название Цвет Значение цвета в таблице Двоичное представление цвета в таблице
Стены Тип 1.1 выше отм. 0,000 Red -65536 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000
Стены Тип 1.2 выше отм. 0,000 Green -16711936 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 1111 1111 0000 0000
Стены Тип 2.1 выше отм. 0,000 Blue -16776961 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 1111 1111
Стены Тип 0.1 ниже отм. 0,000 Red=16 -15728640 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 0000 0000 0000
Стены Тип 0.2 ниже отм. 0,000 Red=17 -15663104 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0001 0000 0000 0000 0000
Стяжки на отм. 0,000 Red=193 Green=32 Blue=74 12 656 714 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100 0001 0010 0000 0100 1010

Сначала меня сильно удивили цифры в таблице, а особенно – наличие положительных и отрицательных значений.


Поэкспериментировав со значениями компонент R, G, B, я сообразил, что эти три компоненты отображаются последними тремя байтами числа.


Но тогда странно – почему старшие байты оказываются заполнены не нулями, а единицами?
Впрочем, если предположить, что их всегда заполняют единицами – то получает объяснение наличие отрицательных чисел. Просто заполняют и старший байт, определяющий знак числа.
Но ведь там не всегда отрицательные числа!


И вот только вспомнив, как работают функции >> и <<, я сообразил, что они могут тупо заполнять цифрами старшие биты, в том числе знаковый бит. А поскольку старшие биты не нужны – то и неважно, что там стоит.


Тогда вопрос – а нафига им потребовалось такое большое значение для цвета? Аж 64 бита? Посмотрел структуру таблиц, в которых хранятся эти данные – там просто для всех целых чисел используется Int64. Действительно, чего мелочиться?


Итог


Значение цвета, записываемого в таблице, получаем так:


Int64 dbColor = Rb<<16 + Gb<<8 + Bb;

Обратное преобразование – табличного цвета в используемый для элементов модели цвет – делаем так:


byte R = (byte)(dbColorValue >> 16 % 256);
byte G = (byte)(dbColorValue >> 8 % 256);
byte B = (byte) (dbColorValue % 256);
var color = Autodesk.Navisworks.Api.Color.FromByteRGB(R, G, B);
Поделиться публикацией

Похожие публикации

Комментарии 0

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое