Recently, I was asked if DP/CATIA VB had a better method for finding objects than FindObjectsByName. Short Answer: No. Long Answer: Yes, but with a lot of work and it’s not worth it.
First off, FOBN is a method at the Part level. It uses a string as a check against anything in the model. Starting from the top, the code will parse thru the specifications tree until it finds the first object with that exact name (case-sensitive).
It should come without much surprise that the size of the tree corresponds directly to the amount of time required to find an object. This is the first red flag that this method should be avoided. This waiting time is compounded whenever a user must search a single PartBody or Geometrical Set with thousands of objects. For some reason, as the number of HybridShapes increases, it exponentially increases the search time. For these reasons, FOBN should never be placed inside a loop. Also, try to avoid using it at the end of the code, because most scripts will generate a lot of geometry.
FOBN will find anything with the string as a name. So if you are searching for a Fill Surface named “Fill.1,” it will find the first instance of that name. If you declare your VB fill as a HybridShapeFill, and it finds a Geometrical Set named “Fill.1” somewhere higher in the tree, you’ll get a VB declaration error. Also FOBN only searches a Part. If you are scripting in a Product assembly, you are screwed.
Enough complaining. What can we do about it. First, I can tell you what GT Dev would say: “Use Selection Searching.” This is where you use CATIA.ActiveDocument.Selection.Search with typical UI search strings to find objects. The simplest form is
If you think this is a viable way to work, go right ahead. At least this version will give you all satisfying name strings, not just the first object in the spec tree. And also it will cost you your memory and time. Selecting objects in scripting is probably the worst policy in DS API development to date. It’s unbearably slow, costly, and buggy. Plus have fun putting together those nested parentheses in your search string if you want to combine workbench searching–it’s literally worse than AutoLISP. That’s saying something.
The next thing you can do is set up your code to pick objects by the user. This only works if you are using FOBN at the beginning of your code to find specific pieces of geometry.
GSel = CATIA.ActiveDocument.Selection.SelectElement2(InputObjectType, "Select something", False)
Just make sure your InputObjectType is an undeclared array of declaration-type strings. This filter the geometry for you when you are selecting them. There are other types of selecting options, and you can find them in the V5Automation page for Selection. However, this is a limited case for finding objects, and clearly cannot be used inside of a loop.
Another way to find geometry without FOBN: Make a matrix of objects from a lead set. Let’s say you have several objects in a set and need the object named “Obj.344.” You could set up an initial loop to store all of the objects in that part as a string array. Then make a secondary array of objects with their original datatypes. Once setup, one would only need to construct a simple function to search the array and return the index. This sounds like an awesome solution to large models and highly-populated sets, but this is a short-term gain. One thing a scripter needs to remember is the human factor; you may be perfect, but your colleagues that don’t think like a computer may not care about proper naming conventions. Being completely reliant on name strings will always result in a problems in the long run. If a user happens to change a name or duplicate a hybridshape name, it may stop your code. I’ve been burned too many times by models that had sloppy naming procedures, and it took so long to debug that it was hardly worth scripting. Plus you’ll have all the same problems with the duplicate naming issues of FOBN.
I’ve written a few functions to make searching faster without selection of FOBN. For example is you are looking to find the first object in a set with just a simple loop, you could use my FindObjByStringInGeomSet function, currently open for use from my post on the GTWiki:
Function FindObjByStringInGeomSet(GeoSet As HybridBody, StrSeg As String) As HybridShape Dim numb_set As Integer numb_set = GeoSet.HybridShapes.Count Dim loop_x As Integer For loop_x = 1 To numb_set If InStr(GeoSet.HybridShapes.Item(loop_x).Name, StrSeg) <> 0 Then Set FindObjByStringInGeomSet = GeoSet.HybridShapes.Item(loop_x) loop_x = numb_set End If Next loop_x End Function
So, is there anything we can do? Nothing really. DS isn’t upgrading V5 for anyone unless you want more OMBUNDOERR’s. You’ll have to use the aforementioned examples for whatever situation suites your needs. If only CATIA.Selection would return an array instead of a frigg’n selection… [dreamy emoticon]…