Hi @c_hoppen. I have not tried it yet, but since there is a property for SearchBox.SearchFilter, and it is ReadOnly, and there is the SearchBox.SearchText property, which is also ReadOnly, then it would make sense for that 'SearchOptions' optional input to be a variation of the SearchBoxFilterEnum.
Wesley Crihfield
(Not an Autodesk Employee)
Hi @WCrihfield I was hoping that further filter options would allow me to filter the results more precisely.
For example: Searching "gk" but only in Author.
Would be cool to have a fast solution for this task.
Regards
Christoph
Usually, if we can not do it manually, then we can not do it by code either. When I click on the search icon at the top of my model browser tree, I get something that looks like this:
There are 3 icons under the search box. The second and third icons coincide with those two filters within the SearchBoxFilterEnum. The icon on the far left looks like a greyed out funnel until one or more of those other two are selected, then it looks like an 'X'. Then when you click the 'X', that clears any 'filters' that were selected before.
I agree that it would be pretty nice if that Search functionality were more dynamic / powerful.
If you need to find only the assembly components which have "gk" as the value of their 'Author' iProperty, then you will likely need to do so with an iLogic rule (or similar). Another way to see them might be to open the BOM, and include a column for that iProperty, so you can see which ones have that value. The rows could likely be sorted by the values in that column also. If you would like to go the iLogic rule route, and would like some help with that, just let us know.
Wesley Crihfield
(Not an Autodesk Employee)
By now you can't add or delete a BOM row comfortably by code. And I don't want to mess up the BOM when it is exported to any management systems.
Looping through the assembly with checking iProperties against any search value is EXTREMLY slow the first time an assembly is opened. I have just done a test and it took 17 seconds for 10000 occurrences. Strangely enough, all further searches take less than half a second. It seems that Inventor caches the iProperties on the first access.
I think the initial difference between first run and subsequent runs is due to most of those referenced documents only being 'initiated' (happens automatically when you open things like assembly or drawing) rather than fully loaded (opened, even if not visibly) in Inventor's session memory. The individual iProperty values themselves should not be held in memory, but some stuff definitely is. I have heard that using Apprentice can be faster, when just accessing iProperties, but that can only be used from something like a standalone EXE (not iLogic rules, VBA macros, or add-ins). There are likely ways to reduce the run time some required by the search, but with that many occurrences, the main thing I would recommend is iterating the referenced documents instead of components, if that's not what you already did. And maybe use OpenWithOptions, instead of the regular Open method, and setting 'SkipAllUnresolvedFiles' to True, and 'ExpressModeBehavior' to 'OpenExpress', or maybe even opening it in a ModelState in which the most stuff is suppressed may help. Using Inventor API code instead of iLogic API code (which runs extra code behind the scenes) may help also.
Wesley Crihfield
(Not an Autodesk Employee)
It's getting stranger and stranger...
With my test assembly (2650 files & 10000 Occurrences), the following code takes about 1.5 seconds. Always. The assembly is already open.
ComponentOccurrences occs = assmDoc.ComponentDefinition.Occurrences;
foreach (Document document in assmDoc.AllReferencedDocuments)
{
if (IsMatching(document, sd))
{
ComponentOccurrencesEnumerator leafOccs = occs.get_AllReferencedOccurrences(document);
foreach (ComponentOccurrence occ in leafOccs)
{
oCol.Add(occ);
}
}
}
Traversing the assembly occurrences leads to the same result:
foreach (ComponentOccurrence occ in assmDoc.ComponentDefinition.Occurrences)
{
if (IsMatching(occ.Definition.Document as Document, sd))
oCol.Add(occ);
if (occ.SubOccurrences.Count > 0)
TraverseAssembly(occ.SubOccurrences, sd, oCol);
}
......
private static void TraverseAssembly(ComponentOccurrencesEnumerator subOccurrences, SearchDefinition sd, ObjectCollection oCol)
{
foreach(ComponentOccurrence occ in subOccurrences)
{
if (IsMatching(occ.Definition.Document as Document, sd))
oCol.Add(occ);
if (occ.SubOccurrences.Count > 0)
TraverseAssembly(occ.SubOccurrences, sd, oCol);
}
}
But it takes 17 seconds for the first call, and a quick glance for subsequent calls ( < 500 mSec).