Fundo da tarefa
Por exemplo, surgiu um problema para o cliente:
- Jogue fora os elementos do modelo de construção em 1C.
- Em 1C, use essas partes do modelo em contratos - bem, digamos, indique que tais e tais elementos já foram construídos, tais e quais são apenas planejados etc.
- No Navisworks, você pode ver isso de alguma forma em um desenho - por exemplo, exibindo elementos do modelo em cores diferentes. Para fazer isso, eles criaram um plug-in para o Navisworks que pode copiar dados das tabelas Quantification (tabelas Takeoff) para 1C, além de retirá-los do 1C e colocá-los nas tabelas Takeoff.
E em 1C, supunha-se que os elementos do modelo (salas) utilizados no contrato mudassem de cor.
Somente agora ocorreu que, depois de alterar esses dados tabulares no 1C - o Navisworks não entende que eles foram alterados, e seria necessário atualizá-los. Portanto, eu, o programador, preciso dizer isso a ele.
Então, a tarefa do programador
Após a troca com 1C, os dados na tabela TK_Item foram alterados - em particular, o campo Cor. É necessário trazer as cores no desenho exibido de acordo com as indicadas na tabela.
Estamos procurando como fazer isso. Nós cavamos a descrição. Nós encontramos a função -
public void OverridePermanentColor(IEnumerable<ModelItem> items, Color color)
Bem, como encontrar elementos de modelo que correspondam ao elemento TK_Item selecionado é outra história, contarei outra vez se for interessante. Mas quem precisa - e ele descobrirá. Mas com a cor, tudo acabou sendo mais interessante.
Em primeiro lugar, a cor especificada nos parâmetros da função não é System.Drawing.Color, mas mesmo o Autodesk.Navisworks.Api.Color, com seu blackjack e ... bem, você entende. Bem, deixe estar, mas ele tem um construtor assim:
public static unsafe Color FromByteRGB(byte red, byte green, byte blue)
Portanto, sem problemas, criaremos uma cor conforme a API da Autodesk.
(Na verdade, a primeira coisa que devo tentar é encontrar os elementos que correspondem ao item selecionado, selecionar uma cor - e definir essa cor.)
Mas Na tabela, temos no campo Cor um valor do tipo Int64. E como compará-lo com um objeto do tipo Cor não é claro.
Além disso, nem na documentação, nem no fórum, nem nos exemplos, eu pude encontrar como está escrito no banco de dados.
OK, vamos cavar experimentalmente.
Pegamos o Navisworks, abrimos a Quantificação, mudamos a cor de um elemento. Diga, em um vermelho honesto e limpo.

Depois disso, pegamos nosso plug-in, bombeamos os dados da tabela TK_Item e olhamos, o que há na tabela?
(Felizmente, o plug-in para fins de depuração forneceu essa opção - faça o download dos dados e mostre-os no formulário.)
Acontece que há -65536.

Repita o procedimento várias vezes e reduza os resultados para um arquivo de texto.
No começo, fiquei muito surpreso com os números da tabela e, principalmente, com a presença de valores positivos e negativos.
Tendo experimentado os valores dos componentes R, G, B, percebi que esses três componentes são exibidos com os últimos três bytes do número.
Mas então é estranho - por que os bytes altos são preenchidos com unidades, não zeros?
No entanto, se assumirmos que eles estão sempre preenchidos com unidades, a presença de números negativos recebe uma explicação. Basta preencher o byte alto que define o sinal do número.
Mas nem sempre existem números negativos!
E, lembrando-me de como as funções >> e << funcionam, percebi que elas podem estupidamente preencher os bits mais altos com números, incluindo o sinal. E como os bits mais significativos não são necessários, não importa o que está lá.
Então a questão é: para que eles precisavam de tanta importância para a cor? Já 64 bits? Eu olhei para a estrutura das tabelas em que esses dados estão armazenados - ele apenas usa Int64 para todos os números inteiros. Realmente, por que brincar?
Sumário
O valor da cor registrada na tabela é obtido da seguinte forma:
Int64 dbColor = Rb<<16 + Gb<<8 + Bb;
A transformação inversa - a cor da tabela na cor usada para os elementos do modelo - fazemos isso:
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);