C++ FindByUserString

The C# API has a ObjectTable.FindByUserString function. Is there an equivalent function available to the C++ API?

Hi @mike14,

No, there is no C++ equivalent. However, you can use a CRhinoObjectIterator to iterate objects in the document and look for objects that have your user strings. For example:

int RhinoFindObjectsByUserString(
  CRhinoDoc& doc,
  const wchar_t* key,
  const wchar_t* value,
  bool bCaseSensitive,
  bool bSearchGeometry,
  bool bSearchAttributes,
  ON_SimpleArray<const CRhinoObject*>& objects
)
{
  if (nullptr == key || nullptr == value)
    return 0;

  ON_ClassArray<ON_wString> geokeys;
  ON_ClassArray<ON_wString> attkeys;

  CRhinoObjectIterator it(
    CRhinoObjectIterator::normal_objects, 
    CRhinoObjectIterator::active_objects
  );
  it.IncludeLights(FALSE);
  it.IncludeGrips(false);
  it.IncludePhantoms(false);

  CRhinoObject* obj = nullptr;
  for (obj = it.First(); nullptr != obj; obj = it.Next())
  {
    geokeys.Destroy();
    attkeys.Destroy();

    const ON_Geometry* geo = (bSearchGeometry) ? obj->Geometry() : nullptr;
    if (bSearchGeometry && geo)
      geo->GetUserStringKeys(geokeys);
    if (bSearchAttributes)
      obj->Attributes().GetUserStringKeys(attkeys);

    if (geokeys.Count() == 0 && attkeys.Count() == 0)
      continue;

    bool bAdded = false;

    for (int i = 0; nullptr != geo && i < geokeys.Count(); i++)
    {
      bool bMatch = bCaseSensitive 
        ? geokeys[i].WildCardMatch(key) 
        : geokeys[i].WildCardMatchNoCase(key);
      if (!bMatch)
        continue;

      ON_wString str;
      if (!geo->GetUserString(geokeys[i], str))
        continue;

      bMatch = bCaseSensitive 
        ? str.WildCardMatch(value) 
        : str.WildCardMatchNoCase(value);
      if (!bMatch)
        continue;

      objects.Append(obj);
      bAdded = true;
      break;
    }

    if (!bAdded)
    {
      for (int i = 0; i < attkeys.Count(); i++)
      {
        bool bMatch = bCaseSensitive 
          ? attkeys[i].WildCardMatch(key) 
          : attkeys[i].WildCardMatchNoCase(key);
        if (!bMatch)
          continue;

        ON_wString str;
        if (!obj->Attributes().GetUserString(attkeys[i], str))
          continue;

        bMatch = bCaseSensitive 
          ? str.WildCardMatch(value) 
          : str.WildCardMatchNoCase(value);
        if (!bMatch)
          continue;

        objects.Append(obj);
        bAdded = true;
        break;
      }
    }
  }

  return objects.Count();
}

– Dale

OK. Thanks.