Face Area

Currently I'm trying to figure out how to get the area of a face. I have an array of faces and I want to know the area of each face so I can find the face with the largest area.



I've tried following this post http://www.eng-tips.com/viewthread.cfm?qid=346332, however, it doesn't seem like it will fit my exact needs.


Here's the code from the link:

Dim mFaces As New List(Of Face)

Dim boundaryFaces1(-1) As Face
Dim faceTangentRule1 As FaceTangentRule
faceTangentRule1 = workPart.ScRuleFactory.CreateRuleFaceTangent(mySelObj, boundaryFaces1, 0.5)

Dim unit1 As Unit = CType(workPart.UnitCollection.FindObject("SquareMilliMeter"), Unit)

Dim unit2 As Unit = CType(workPart.UnitCollection.FindObject("MilliMeter"), Unit)

Dim rules1(0) As SelectionIntentRule
rules1(0) = faceTangentRule1
measureFaceBuilder1.FaceCollector.ReplaceRules(rules1, False)

Dim measureFaces1 As MeasureFaces
For Each tempFace As TaggedObject In measureFaceBuilder1.FaceCollector.GetObjects
mFaces.Add(CType(tempFace, Face))
Next
measureFaces1 = workPart.MeasureManager.NewFaceProperties(unit1, unit2, 0.99, mFaces.ToArray)

'Dim measure1 As Measure
'measure1 = measureFaces1.CreateFeature()

lw.Open()

lw.WriteLine("to string :" & myselobj.tostring)
lw.WriteLine("journalidentifier :" & myselobj.journalidentifier)
lw.WriteLine("color :" & myselobj.color)
lw.WriteLine("name :" & mySelObj.name)
lw.WriteLine("number of faces collected: " & measureFaceBuilder1.FaceCollector.GetObjects.Length.ToString)

Dim x1, x2 As Double
x1 = measureFaces1.Area
x2 = measureFaces1.Perimeter

lw.WriteLine("Area :" & x1)
lw.WriteLine("Perimeter :" & x2)


If you use a list object instead of an array, you can write a custom comparison function and sort the faces by area, see:

http://nxjournaling.com/content/sort-list-nx-objects

Below is some code that takes a solid body as input and returns the largest (by area) 'revolved' face. Perhaps you could modify it to your needs or at least use the same principles.



Function LargestRevolvedFace(ByVal inputSolid As Body) As Face

Dim nullNXObject As NXObject = Nothing
Dim measureFaceBuilder1 As MeasureFaceBuilder
measureFaceBuilder1 = workPart.MeasureManager.CreateMeasureFaceBuilder(nullNXObject)

Dim unit1 As Unit = CType(workPart.UnitCollection.FindObject("SquareInch"), Unit)
Dim unit2 As Unit = CType(workPart.UnitCollection.FindObject("Inch"), Unit)

Dim objects1(0) As IParameterizedSurface
Dim measureFaces1 As MeasureFaces

Dim myFaces() As Face
myFaces = inputSolid.GetFaces
Dim largestFace As Face = myFaces(0)
Dim largestArea As Double
Dim added1 As Boolean
Dim i As Integer = 0

For Each tempFace As Face In myFaces
Select Case tempFace.SolidFaceType
Case 2, 3, 5
'type 2 = cylindrical
'type 3 = conical
'type 5 = surface of revolution
i += 1
'lw.WriteLine("case 2,3,5: " & tempFace.SolidFaceType.ToString)
measureFaceBuilder1.FaceObjects.Clear()
added1 = measureFaceBuilder1.FaceObjects.Add(tempFace)
objects1(0) = tempFace
measureFaces1 = workPart.MeasureManager.NewFaceProperties(unit1, unit2, 0.999, objects1)
If i = 1 Then
largestFace = tempFace
largestArea = measureFaces1.Area
'lw.WriteLine("initial face:")
'lw.WriteLine("area: " & largestArea)
'largestFace.Highlight()
Else
If measureFaces1.Area > largestArea Then
'largestFace.Unhighlight()
largestFace = tempFace
'largestFace.Highlight()
largestArea = measureFaces1.Area
'lw.WriteLine("new largest face, area: " & largestArea)

End If
End If

Case Else
'skip to next face
End Select
Next

measureFaces1.Dispose()
measureFaceBuilder1.FaceObjects.Clear()
measureFaceBuilder1.Destroy()

If i = 0 Then
Return Nothing
Else
Return largestFace
End If

End Function

Here's a much shorter way. It uses the SNAP function face.Area, which (predictably) returns the area of a given face. Using this, we can create a "lambda" function face => face.Area, which we can then use to sort the faces in a given body.


using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
public static Snap.NX.Face LargestFace(Snap.NX.Body body)
{
// Create a list of all the faces in the given body
List faceList = new List(body.Faces);

// Sort the faces in descending area, using a lambda function
faceList = faceList.OrderByDescending(face => face.Area).ToList();

// Output the largest face (the first one in the list)
return faceList[0];
}
}

Here's the same thing written in VB, instead. Everything is pretty much the same, except the syntax for defining a lambda function is different.


Option Infer On
Imports System.Collections.Generic
Imports System.Linq
Imports Snap

Public Class MyProgram

Public Shared Function LargestFace(myBody As NX.Body) As NX.Face

' Create a list of all the faces in the given body
Dim faceList As New List(Of NX.Face)(myBody.Faces)

' Sort the faces in descending area, using a lambda function
faceList = faceList.OrderByDescending(Function(face) face.Area).ToList

' Output the largest face (the first in the list)
return faceList(0)

End Function

End Class