Saving item color in Navisworks database
Task background
For example, a problem arose for the customer:
- Throw off the building model elements in 1C.
- In 1C, use these parts of the model in contracts - well, let's say, indicate that such and such elements have already been built, such and such are only planned, etc.
- In Navisworks, you can somehow see this in a drawing — for example, by displaying model elements in different colors. To do this, they made a plug-in for Navisworks that can copy data from Quantification tables (Takeoff tables) to 1C, as well as take them back from 1C and put them into Takeoff tables.
And in 1C, it was supposed that the model elements (rooms) used in the contract should change colors.
Only now 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. Therefore, I, the programmer, need to tell him this.
So, the task for the programmer
After the exchange with 1C, the data in the TK_Item table changed - in particular, the Color field. It is necessary to bring the colors in the displayed drawing in accordance with those indicated in the table.
We are looking for how to do it. We dig the description. We find the function -
public void OverridePermanentColor(IEnumerable items, Color color)
Well, how to find model elements that correspond to the selected TK_Item element is another story, I’ll tell you another time if it’s interesting. But who needs it - and he will figure it out. But with color, everything turned out to be more interesting.
Firstly, the Color specified in the parameters of the function is not System.Drawing.Color, but even Autodesk.Navisworks.Api.Color, with its blackjack and ... well, you understand. Well, let it be, but he has such a constructor:
public static unsafe Color FromByteRGB(byte red, byte green, byte blue)
Therefore, without problems, we will make such a Color as the Autodesk API is needed.
(Actually, the first thing I should try is to find the elements that correspond to the selected Item, select a color - and set it to this color.)
But. In the table, we have in the field Color one value of type Int64. And how to compare it with an object of type Color is unclear.
Moreover, neither in the documentation, nor in the forum, nor in the examples I could find how it is written in the database.
OK, we will dig experimentally.
We take Navisworks, open Quantification, change the color of an element. Say, on an honest, clean Red.
After that, we take our plugin, pump them the data from the TK_Item table, and look, what's in the table?
(Fortunately, the plug-in for debugging purposes provided such an option - download data and show on the form.)
It turns out there is -65536.
Repeat the procedure several times and reduce the results to a text file.
Title | Color | Color value in table | Binary representation of color in a table |
---|---|---|---|
Wall Type 1.1 above mark 0,000 | Red | -65536 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 |
Wall Type 1.2 above mark 0,000 | Green | -16711936 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 1111 1111 0000 0000 |
Wall Type 2.1 above mark 0,000 | Blue | -16776961 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 1111 1111 |
Wall Type 0.1 below mark 0,000 | Red = 16 | -15728640 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0000 0000 0000 0000 0000 |
Wall Type 0.2 below mark 0,000 | Red = 17 | -15663104 | 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 0001 0001 0000 0000 0000 0000 |
Ties on an elev. 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 |
At first, I was very surprised by the numbers in the table, and especially by the presence of positive and negative values.
Having experimented with the values of the components R, G, B, I realized that these three components are displayed with the last three bytes of the number.
But then it’s strange - why are the high bytes filled with units, not zeros?
However, if we assume that they are always filled with units, then the presence of negative numbers gets an explanation. Just fill in the high byte, which determines the sign of the number.
But there are not always negative numbers!
And just remembering how the >> and << functions work, I realized that they can stupidly fill in the high bits with numbers, including the sign bit. And since the most significant bits are not needed, it doesn’t matter what is there.
Then the question is - what for did they need so much importance for color? Already 64 bits? I looked at the structure of the tables in which this data is stored - it just uses Int64 for all integers. Really, why trifle?
Total
The value of the color recorded in the table is obtained as follows:
Int64 dbColor = Rb<<16 + Gb<<8 + Bb;
The inverse transformation - the table color to the color used for the model elements - we 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);