I am working on a way to validate assembly STEP exports by automatically reimporting them into NX, overlaying the imported assembly with the original, and making sure every sheet/solid body has a matching twin.
I am currently using a method to identify bodies using two parameters, their number of faces and ufSession.Modl.AskBoundingBox() for the loose bounding box. I then calculate the center of the bounding box for the approximate position of the body.
However, I noticed that STEP imports (without simplify/optimize geometry enabled) deviate from their origin by +/- 0.1mm and by +/- 5 faces, depending on geometry. So I have a 2.5% tolerance for matching two bodies.
One stubborn body went from 480 to 590 faces upon re-importing it into NX, forcing me to abandon face count as a identifying feature. My next attempt will substitute the volume of the bounding box, using its overall length, width, and height.
Is there another parameter I could use? Body volume will not work since we have sheet bodies, and I don't know how performance intensive calculating total surface area of the body would be.
re: body compare
Some CAD systems do not support 360° cylindrical faces, they break them up into 2 faces. When exporting to STEP, these faces are broken up. For your use case, I'd suggest importing with the "optimize" option turned on (this will re-combine the faces into a single cylindrical face) or running "optimize face" on the imported bodies before the comparison (this might give you more control over the optimization process).
I wrote some code to do something similar recently (comparing bodies). I used the bounding body dims, the number of faces, the number of edges, the volume of the body, and the surface area. The code to get the volume and surface area is straightforward and runs quickly (in my experience, at least). A code snippet is below. I this case, I'm iterating through the .Body collection and "tempBody" is the current one being processed. Note that you can use the .IsSolidBody property to help distinguish between solid and sheet bodies, though sheet bodies should work fine and just return 0 for the volume.
'body volume and surface area
Dim mm As MeasureManager = theSession.Parts.Work.MeasureManager()
Dim massUnits(4) As Unit
massUnits(0) = theSession.Parts.Work.UnitCollection.GetBase("Area")
massUnits(1) = theSession.Parts.Work.UnitCollection.GetBase("Volume")
massUnits(2) = theSession.Parts.Work.UnitCollection.GetBase("Mass")
massUnits(3) = theSession.Parts.Work.UnitCollection.GetBase("Length")
Dim mb As MeasureBodies = mm.NewMassProperties(massUnits, 0.99, {tempBody})
mb.InformationUnit = MeasureBodies.AnalysisUnit.PoundInch
lw.WriteLine(" Surface Area = " & mb.Area.ToString() & " " & massUnits(0).Symbol)
lw.WriteLine(" Volume = " & mb.Volume.ToString() & " " & massUnits(1).Symbol)
If you are using NX2206 or higher, there is a nice "compare body" command. It might work better for your case. Unfortunately, I've not (yet) attempted to automate it, so I don't have any example code for it.
re: body compare
We are on NX2306, and I noticed body compare, but I assumed it would be slower than grabbing bounding box variables.
What I am also trying (along side your proposed solution) is the exact bounding UF_Session command, which gives the directions, vectors, and min corner of the bounding box. It's really exact and I'm getting much better comparison values between import and export.
Interestingly enough, I tried to turn on optimize geometry for the STEP import setting and that did not affect the model. In this case it was a STEP imported into CREO and then translated to NX, so it's changed so many hands already. The STEP conversion ended up sub-dividing a lot of faces that resulted from the intersection of blends/fillets.
I've been requested into creating a journal that can perform "compare body" on an assembly level, so it'd be interesting the combine the two and performing on compare body on two bodies that are close, but still out of tolerance of each-other.
Thank you for the sample code! I'll take look at integrating into my code as a sort-of backup comparison in case the first one fairs to pair a solid.