@johnwmcc said:
Sorry I didn't make myself clearer. I'm coding in Ruby. I use the InputPoint.pick method and when I click on a face, it reports via the InputPoint.face method (@ip1.face in the code sample in the onLButtonClick method) whether it has clicked on a face, and if so, which face. But it doesn't say whether it is a 'loose geometry' face, inside a group, or inside a component.
And the reported face.normal differs between a face in a component, and one thas is in a group or loose.
The thing I found (and still find) very confusing is that the reported normal for a face in a rotated component is not the normal to the geometrical face. What is is reported by the .normal method seems by experiment to be the normal to where the face was in World coordinates in the original ComponentDefinition for an un-rotated component. But I suppose on reflection that it is the normal (the Y-axis) in the ComponentInstance's own coordinate system. But I didn't originally see it that way.
I have now worked out how deal with it, by first detecting if the face.parent object is a ComponentDefinition (which equally applies to a Component or a Group), then checking if face.parent.group? is true to see if it is a group, and so not a ComponentInstance) but it seemed originally more complicated and confused me for several hours while I figured out where I needed either the reported World Coordinate normal vector, or the component instance coordinate normal vector.
I believe that what has confused you is that a ComponentInstance does not actually own any entities. Instead, they are all owned by its ComponentDefinition. The things you see in the model view are transformed representations of those entities, not separate objects. That's why when you edit a ComponentInstance the change is instantly repeated in all the other instances of the same ComponentDefinition no matter where they are placed or how they are rotated.
So, when your InputPoint pick finds a Face within a ComponentInstance, the object it returns is actually the original in the associated ComponentDefinition, and the normal to that Face is the normal in the ComponentDefinition's coordinates, not in global model coordinates. You need to transform it back to global coordinates to get the version corresponding to the ComponentInstance you clicked. That is why InputPoint also has a #transformation method to retrieve the transformation associated with whatever it found. This Transformation is an identity if the object is free geometry or in a Group, and is the ComponentInstance's transformation if the object is from one.
So, no offense intended, but the only bug was in your understanding