📜 ⬆️ ⬇️

Preserving the element color in the Navisworks database

Background of the problem


There was a customer task, for example, such:



But it turned out that after changing these tabular data in 1C - Navisworks does not understand that they have changed, and it would be necessary to update them. So, I, a programmer, need to tell him that.


So, the task for the programmer


After the exchange with 1C, the data in the TK_Item table has changed - in particular, the Color field. It is necessary to bring the colors on the displayed drawing in accordance with those indicated in the table.


We are looking for how to do it. Digging a description. Find the function -


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

Well, how to find the elements of the model that match the selected item TK_Item is another story, another time I will tell if it will be interesting. But who needs - and he will understand. But with the color everything turned out to be more interesting.
First of all, the Color specified in the function parameters is not System.Drawing.Color, but even Autodesk.Navisworks.Api.Color, with its own blackjack and ... well, you understand. Well, let him, but he has this constructor:


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

So, without any problems we will make such a Color, which Avtodeskovsky API is needed.
(Actually, the first thing I do is try - find the items that match the selected Item, choose a color - and set it to them.)


But. In the table, we have one value of type Int64 in the Color field. And how to compare it with an object of type Color is not clear.


And neither in the documentation, nor on the forum, nor in the examples I could not find how it is written in the database.


OK, we will dig experimentally.


Take Navisworks, open Quantification, change the color of some element. Let's say honest to the pure Red.


image


After that, we take our plugin, we extort data from the TK_Item table, and see what is in the table?


(Fortunately, in the plugin for debugging purposes, this option was provided - download the data and show it on the form.)


There, it turns out, is -65536.


image


We repeat the procedure several times and reduce the results to a text file.


TitleColourColor value in the tableBinary color representation in the table
Walls Type 1.1 above mark 0,000Red-655361111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000
Walls Type 1.2 above mark. 0,000Green-167119361111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 1111 1111 0000 0000
Walls Type 2.1 above mark. 0,000Blue-167769611111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 1111 1111
Walls Type 0.1 below mark 0,000Red = 16-157286401111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 0000 0000 0000
Walls Type 0.2 below mark 0,000Red = 17-156631041111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0001 0000 0000 0000 0000
Screeds at mark 0,000Red = 193 Green = 32 Blue = 7412,656,7140000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1100 0001 0010 0000 0100 1010

At first I was very surprised by the numbers in the table, and especially by the presence of positive and negative values.


Experimenting with the values ​​of the components R, G, B, I realized that these three components are displayed in the last three bytes of the number.


But then it is strange - why are the high bytes turned out to be filled not with zeros, but with ones?
However, if we assume that they are always filled with units, then the presence of negative numbers is explained. Just fill and high byte, which determines the sign of the number.
But there are not always negative numbers!


And just remembering how the functions >> and << work, I realized that they can stupidly fill in the high bits, including the sign bit, with digits. And since the high-order bits are not needed, it doesn’t matter what stands there.


Then the question is - but what the hell did they need so much importance for the color? Already 64 bits? I looked at the structure of the tables in which this data is stored - Int64 is simply used for all integers. Indeed, why trivial?


Total


The color value recorded in the table, we obtain as follows:


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

Inverse transformation - table color to the color used for model elements - do this:


 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); 

')

Source: https://habr.com/ru/post/450248/


All Articles