Just ran it again, all the cylinder faces and the fillet have u_status = "1" and v_status = "0". U_period is 6.283... and v_period is 0. Also same on all.
I made a test part, and I have to say my expectations were wrong about the periodicity!
I really thought that a cylindrical face with less than 360 degrees would be non-periodic.
Please accecpt my (embarrassing!) apology!
Just to add to this I would do the following:
To eliminate partial cylinders get the face edges. If the number of edges is 2 then we either have a closed cylinder (ignoring divided cylinders) or a closed blend. To eliminate the closed blend I would get the curvatures at a point on the face. If both values are non-zero (within tolerance) then reject the face as a closed blend.
Now for each of the two face edges I would get the adjacent faces. If the adjacent face has 1 or 2 edges then it will be one of the faces to include. 1 edge would be either the flat or conical bottom face of the hole. 2 edges would be either the chamfer or the annulus of the cbore hole. The 2 edge faces would need to be further checked until you reached a point when the number of edges is greater than 2.
It is not a easy task to solve all kind of holes. We even use drilling for open holes. This depends of course on material, tool and machine type. We use face, edge and edge type concave convex to get position, orientation, acessvector and size, depth start end to evalute holes and hole type and sort them in alogical way. Snap is also no option for us because it is not availible on all platforms.
> I would respectfully disagree regarding SNAP.
> Since it is an added cost module, it is not available to everyone.
I said it was the easiest, not the cheapest. And you only need one author license, remember. Depends how much your time is worth.
> Will check into the documentation to see the methods and then look for the corresponding NXOpen functions.
The only place you'll find loops in NX/Open is in the UFBrep functions, and these are callable only from C/C++ code. But you can reconstruct the loops yourself, starting from the edges, if you want to. In most holes, each loop consists of only a single edge, anyway. And, with each edge, you can call NXOpen.UF.UFModl.AskEdgeVerts. If you get zero vertices, you know you have a closed edge. These edges will usually be circles, but you might also get some ellipses and intersection edges. And on an imported model, if you haven't yet "cleaned" it, you'll probably find a lot of edges whose type is "tolerant edge". But, the geometry type doesn't really matter very much; it's only the number of vertices that you care about, I think.
Another thing I forgot to mention, that might be useful -- look at edge convexity. Again, this is easier in SNAP (Snap.NX.Edge.Convexity), but you can probably figure it out from surface normals in NX/Open. A convex edge often indicates the place where the hole enters or exists the main part.
Regarding UF_MODL_ask_face_periodicity. The functions is somewhat misnamed. It's telling you the periodicity of the underlying surface, not the face. That's why you get 2*Pi for every cylinder.
You might get what you want from UF_MODL_ask_face_uv_minmax, though.
Also UF_MODL_ask_face_topology looks useful. A cylindrical blend will have a type equal to UF_MODL_FLAT_TOPOLOGY.
That is pretty close to what I tried. I used AskAdjacFaces while cycling through the faces to find all with 2 or less adjacent faces. That works for the most part, but as I suspected, if a hole is in a round boss, the boss face and O.D. gets included for color changing. That may only be a cosmetic issue, since FBM will recognize the actual hole and all the pertinent faces will be the same color to allow my mapping to function. I'm going to thump on it a bit more to see if I can resolve it and then go on to testing the FBM code.
The AskFaceTopology has eliminated selection of blends and fillets. Will want to do more thorough testing, but looks very promising right now.
Here is the result:
Here is the color changing code, holeObjects is the array of selected cylindrical faces:
REM Set face colors displayModification1 = theSession.DisplayManager.NewDisplayModification() displayModification1.ApplyToAllFaces = False displayModification1.NewColor = 17 For i = 0 To holeObjects.Count - 1 Dim k As Integer = 0 Dim l As Integer = 0 Dim adjFaceTag(l) As Tag Dim origAdjFacesTag() As Tag Dim nextAdjFacesTag() As Tag Dim checkFace As Tag Dim done As Boolean Dim found As Boolean Dim dispObj(k) As DisplayableObject dispObj(k) = CType(NXObjectManager.Get(holeObjects(i).Tag), DisplayableObject) adjFaceTag(l) = holeObjects(i).Tag theUfSession.Modl.AskAdjacFaces(holeObjects(i).Tag, origAdjFacesTag) For j = 0 To origAdjFacesTag.Length - 1 done = False checkFace = origAdjFacesTag(j) l += 1 ReDim Preserve adjFaceTag(l) adjFaceTag(l) = checkFace While Not done theUfSession.Modl.AskAdjacFaces(checkFace, nextAdjFacesTag) If nextAdjFacesTag.Length = 1 Then k += 1 ReDim Preserve dispObj(k) dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject) done = True ElseIf nextAdjFacesTag.Length = 2 Then For n = 0 To 1 found = False For m = 0 To adjFaceTag.Length - 1 If adjFaceTag(m) = nextAdjFacesTag(n) Then found = True End If Next If Not found Then k += 1 ReDim Preserve dispObj(k) dispObj(k) = CType(NXObjectManager.Get(checkFace), DisplayableObject) l += 1 ReDim Preserve adjFaceTag(l) adjFaceTag(l) = nextAdjFacesTag(n) checkFace = nextAdjFacesTag(n) End If Next Else done = True End If End While Next displayModification1.Apply(dispObj) Next
Use face vector and normal to find out it is a hole or boss face.
Hole face all vectors show to center axis.
Boss face all vectors show away from center axis.
Use face normal vector and face radius as vector scale to check vector shows to vector axis.
If not, it is a boss.
Btw. also the radius size is a indicator for holes or not. (depends on your company work)
You should also test holes that are drilled true each other.
Here's a quick function that I wrote to test if the cylindrical face is a "hole" face or a "boss" face. I've not done extensive testing, but so far it seems to work OK. If anyone finds a case where it doesn't work, please let me know.
Function IsHoleFace(ByVal cylindricalFace As Face) As Boolean 'distinguish between a hole face and a boss face 'hole face: face normal points toward the face axis 'boss face: face normal points away from the face axis 'ask face type Dim faceType As Integer theUfSession.Modl.AskFaceType(cylindricalFace.Tag, faceType) Select Case faceType Case Is = UFConstants.UF_MODL_CYLINDRICAL_FACE 'so far, so good Case Else Return False End Select 'find cylindrical face axis and point on the axis Dim axisPt(2) As Double Dim axisDir(2) As Double Dim bbox(5) As Double Dim faceMajorRadius As Double Dim faceMinorRadius As Double Dim normalReversed As Integer theUfSession.Modl.AskFaceData(cylindricalFace.Tag, faceType, axisPt, axisDir, bbox, faceMajorRadius, faceMinorRadius, normalReversed) 'get a u,v location and corresponding point on the face given the point on the axis Dim faceParm(1) As Double Dim faceParmPt(2) As Double theUfSession.Modl.AskFaceParm(cylindricalFace.Tag, axisPt, faceParm, faceParmPt) 'get face normal at point on face, use the face point from the AskFaceParm function call Dim u1(2) As Double Dim u2(2) As Double Dim v1(2) As Double Dim v2(2) As Double Dim faceNorm(2) As Double Dim principalRadii(1) As Double theUfSession.Modl.AskFaceProps(cylindricalFace.Tag, faceParm, faceParmPt, u1, v1, u2, v2, faceNorm, principalRadii) 'create vector from axis to surface normal point 'a "boss" face surface normal will point in the same direction 'a "hole" face surface normal will point in the opposite direction Dim bossVec(2) As Double bossVec(0) = faceParmPt(0) - axisPt(0) bossVec(1) = faceParmPt(1) - axisPt(1) bossVec(2) = faceParmPt(2) - axisPt(2) 'is normal facing away from axis (boss) or is normal facing toward axis (hole)? Dim normAngle As Double theUfSession.Vec3.AngleBetween(faceNorm, bossVec, axisDir, normAngle) If normAngle > 0.1 Then 'hole face, surface normal points toward cylindrical face axis Return True Else 'boss face, surface normal points away from cylindrical face axis Return False End If End Function
I recomand to use measure distance of tow points on same section in vector direction using vector scale of the radius.
// * ^ // * __|_ // * / | \ // * <-|- > * | // * / \ ___ / // * / / // * / * / // * \ _ _ / // *