Community
Navisworks API
Welcome to Autodesk’s Navisworks API Forums. Share your knowledge, ask questions, and explore popular Navisworks API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Search for Guid matching value

6 REPLIES 6
Reply
Message 1 of 7
alexisDVJML
501 Views, 6 Replies

Search for Guid matching value

Navisworks ModelItem supports a Guid field

var guid = anItem.InstanceGuid;

 

However, I can't find a dedicated way to search for item(s) with specific Guid value.

More specifically I can't find direct support in SearchCondition and VariantData  for Guid type, so seems best I can do is:

var sc = new SearchCondition(
            new NamedConstant(@"LcOaNode"),
            new NamedConstant( @"LcOaNodeGuid"),
            SearchConditionOptions.IgnoreDisplayNames,
            SearchConditionComparison.Equal,
            VariantData.FromDisplayString(guid.ToString()));

 

Am I correct or am I missing a better way to do such search?

 

Thanks.

Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
6 REPLIES 6
Message 2 of 7
ulski1
in reply to: alexisDVJML

Lots of people have asked for how to get the same look up speed as selecting in selection tree or selection sets. There is some older threads discussing this, but I don’t think anyone have published code that works.

Ulrik
Message 3 of 7
alexisDVJML
in reply to: ulski1

The code I posted above seems to work.

I still have to try VariantData.FromIdentifierString vs VariantData.FromDisplayString to see if it works and if any performance difference. However I'm not optimistic since for example VariantData.FromIdentifierString fails to work when searching for a specific ClassName while it seems the typical use case of it...

Back to Guid specifics, a Guid is a fixed 16 bytes struct so comparing 2 Guid should be much more efficient than comparing 2 strings of variable sizes. 16 bytes = a single SIMD instructions or 2 CMD and a AND in x64 without using SIMD. Using strings, having to convert each searched item Guid to a string before making the string comparison, I would guess at best hundreds of instructions including branch instructions....

Can Navisworks Engineering team look at this?
Searching by Guid, either InstanceGuid or PDMS specific Guid, is quite common so improvements here would be appreciated.

Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
Message 4 of 7
ulski1
in reply to: alexisDVJML

The Point is you don’t want to initiate a search you want the near instant selection speed which Navisworks uses when you select an object in selection tree. I’m guessing Navisworks has a index in memory linked to each 3d object
Message 5 of 7
alexisDVJML
in reply to: alexisDVJML

Got it, slightly different but related use case 😉

On the Guid topic specifically, for those in Autodesk Engineering team who think this does not really matters, below GuidToString methods in .NET, now dare to tell me this does not make any significant performance difference vs just max 3 CPU instructions 🤣:

 

   /// <summary>Returns a string representation of the value of this instance of the <see cref="T:System.Guid" /> class, according to the provided format specifier and culture-specific format information.</summary>
    /// <param name="format">A single format specifier that indicates how to format the value of this <see cref="T:System.Guid" />. The <paramref name="format" /> parameter can be "N", "D", "B", "P", or "X". If <paramref name="format" /> is <see langword="null" /> or an empty string (""), "D" is used.</param>
    /// <param name="provider">(Reserved) An object that supplies culture-specific formatting information.</param>
    /// <returns>The value of this <see cref="T:System.Guid" />, represented as a series of lowercase hexadecimal digits in the specified format.</returns>
    /// <exception cref="T:System.FormatException">The value of <paramref name="format" /> is not <see langword="null" />, an empty string (""), "N", "D", "B", "P", or "X".</exception>
    [SecuritySafeCritical]
    public unsafe string ToString(string format, IFormatProvider provider)
    {
      switch (format)
      {
        case "":
        case null:
          format = "D";
          break;
      }
      int offset1 = 0;
      bool flag1 = true;
      bool flag2 = false;
      if (format.Length != 1)
        throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
      string str1;
      switch (format[0])
      {
        case 'B':
        case 'b':
          str1 = string.FastAllocateString(38);
          string str2 = str1;
          char* chPtr1 = (char*) str2;
          if ((IntPtr) chPtr1 != IntPtr.Zero)
            chPtr1 += RuntimeHelpers.OffsetToStringData;
          chPtr1[offset1++] = '{';
          chPtr1[37] = '}';
          str2 = (string) null;
          break;
        case 'D':
        case 'd':
          str1 = string.FastAllocateString(36);
          break;
        case 'N':
        case 'n':
          str1 = string.FastAllocateString(32);
          flag1 = false;
          break;
        case 'P':
        case 'p':
          str1 = string.FastAllocateString(38);
          string str3 = str1;
          char* chPtr2 = (char*) str3;
          if ((IntPtr) chPtr2 != IntPtr.Zero)
            chPtr2 += RuntimeHelpers.OffsetToStringData;
          chPtr2[offset1++] = '(';
          chPtr2[37] = ')';
          str3 = (string) null;
          break;
        case 'X':
        case 'x':
          str1 = string.FastAllocateString(68);
          string str4 = str1;
          char* chPtr3 = (char*) str4;
          if ((IntPtr) chPtr3 != IntPtr.Zero)
            chPtr3 += RuntimeHelpers.OffsetToStringData;
          chPtr3[offset1++] = '{';
          chPtr3[67] = '}';
          str4 = (string) null;
          flag1 = false;
          flag2 = true;
          break;
        default:
          throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
      }
      string str5 = str1;
      char* guidChars = (char*) str5;
      if ((IntPtr) guidChars != IntPtr.Zero)
        guidChars += RuntimeHelpers.OffsetToStringData;
      int num1;
      if (flag2)
      {
        char* chPtr4 = guidChars;
        int num2 = offset1;
        int num3 = num2 + 1;
        IntPtr num4 = (IntPtr) num2 * 2;
        *(short*) ((IntPtr) chPtr4 + num4) = (short) 48;
        char* chPtr5 = guidChars;
        int num5 = num3;
        int offset2 = num5 + 1;
        IntPtr num6 = (IntPtr) num5 * 2;
        *(short*) ((IntPtr) chPtr5 + num6) = (short) 120;
        int chars1 = Guid.HexsToChars(guidChars, offset2, this._a >> 24, this._a >> 16);
        int chars2 = Guid.HexsToChars(guidChars, chars1, this._a >> 8, this._a);
        char* chPtr6 = guidChars;
        int num7 = chars2;
        int num8 = num7 + 1;
        IntPtr num9 = (IntPtr) num7 * 2;
        *(short*) ((IntPtr) chPtr6 + num9) = (short) 44;
        char* chPtr7 = guidChars;
        int num10 = num8;
        int num11 = num10 + 1;
        IntPtr num12 = (IntPtr) num10 * 2;
        *(short*) ((IntPtr) chPtr7 + num12) = (short) 48;
        char* chPtr8 = guidChars;
        int num13 = num11;
        int offset3 = num13 + 1;
        IntPtr num14 = (IntPtr) num13 * 2;
        *(short*) ((IntPtr) chPtr8 + num14) = (short) 120;
        int chars3 = Guid.HexsToChars(guidChars, offset3, (int) this._b >> 8, (int) this._b);
        char* chPtr9 = guidChars;
        int num15 = chars3;
        int num16 = num15 + 1;
        IntPtr num17 = (IntPtr) num15 * 2;
        *(short*) ((IntPtr) chPtr9 + num17) = (short) 44;
        char* chPtr10 = guidChars;
        int num18 = num16;
        int num19 = num18 + 1;
        IntPtr num20 = (IntPtr) num18 * 2;
        *(short*) ((IntPtr) chPtr10 + num20) = (short) 48;
        char* chPtr11 = guidChars;
        int num21 = num19;
        int offset4 = num21 + 1;
        IntPtr num22 = (IntPtr) num21 * 2;
        *(short*) ((IntPtr) chPtr11 + num22) = (short) 120;
        int chars4 = Guid.HexsToChars(guidChars, offset4, (int) this._c >> 8, (int) this._c);
        char* chPtr12 = guidChars;
        int num23 = chars4;
        int num24 = num23 + 1;
        IntPtr num25 = (IntPtr) num23 * 2;
        *(short*) ((IntPtr) chPtr12 + num25) = (short) 44;
        char* chPtr13 = guidChars;
        int num26 = num24;
        int offset5 = num26 + 1;
        IntPtr num27 = (IntPtr) num26 * 2;
        *(short*) ((IntPtr) chPtr13 + num27) = (short) 123;
        int chars5 = Guid.HexsToChars(guidChars, offset5, (int) this._d, (int) this._e, true);
        char* chPtr14 = guidChars;
        int num28 = chars5;
        int offset6 = num28 + 1;
        IntPtr num29 = (IntPtr) num28 * 2;
        *(short*) ((IntPtr) chPtr14 + num29) = (short) 44;
        int chars6 = Guid.HexsToChars(guidChars, offset6, (int) this._f, (int) this._g, true);
        char* chPtr15 = guidChars;
        int num30 = chars6;
        int offset7 = num30 + 1;
        IntPtr num31 = (IntPtr) num30 * 2;
        *(short*) ((IntPtr) chPtr15 + num31) = (short) 44;
        int chars7 = Guid.HexsToChars(guidChars, offset7, (int) this._h, (int) this._i, true);
        char* chPtr16 = guidChars;
        int num32 = chars7;
        int offset8 = num32 + 1;
        IntPtr num33 = (IntPtr) num32 * 2;
        *(short*) ((IntPtr) chPtr16 + num33) = (short) 44;
        int chars8 = Guid.HexsToChars(guidChars, offset8, (int) this._j, (int) this._k, true);
        char* chPtr17 = guidChars;
        int num34 = chars8;
        num1 = num34 + 1;
        IntPtr num35 = (IntPtr) num34 * 2;
        *(short*) ((IntPtr) chPtr17 + num35) = (short) 125;
      }
      else
      {
        int chars1 = Guid.HexsToChars(guidChars, offset1, this._a >> 24, this._a >> 16);
        int chars2 = Guid.HexsToChars(guidChars, chars1, this._a >> 8, this._a);
        if (flag1)
          guidChars[chars2++] = '-';
        int chars3 = Guid.HexsToChars(guidChars, chars2, (int) this._b >> 8, (int) this._b);
        if (flag1)
          guidChars[chars3++] = '-';
        int chars4 = Guid.HexsToChars(guidChars, chars3, (int) this._c >> 8, (int) this._c);
        if (flag1)
          guidChars[chars4++] = '-';
        int chars5 = Guid.HexsToChars(guidChars, chars4, (int) this._d, (int) this._e);
        if (flag1)
          guidChars[chars5++] = '-';
        int chars6 = Guid.HexsToChars(guidChars, chars5, (int) this._f, (int) this._g);
        int chars7 = Guid.HexsToChars(guidChars, chars6, (int) this._h, (int) this._i);
        num1 = Guid.HexsToChars(guidChars, chars7, (int) this._j, (int) this._k);
      }
      str5 = (string) null;
      return str1;
    }

 

Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
Message 6 of 7
alexisDVJML
in reply to: alexisDVJML

I would guess/hope .Net Core now use Span<char> for this, was too busy to check but:
- we can't realistically use .Net Core in our plugin
- this would just slightly improve the situation vs a native Search for equal Guid
Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go
Message 7 of 7
alexisDVJML
in reply to: alexisDVJML

Another even more important issue than performance is comparing string depend on the Guid format used, aka 'D', N' etc. so to ensure a match we actually have to run multiple ORed conditions for each of the most common formats!
Main Scientist, Full Stack Developer & When Time Permits Director of IDIGO ► On your marks, Set, Go

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


 

Autodesk Design & Make Report