Hi all,
As in the picture, I tried to delete the extra extruded body after measuring.
https://drive.google.com/file/d/1MFi-ikkWcdx-focQtQ04XGkNzOKSwWiU/view?u...
I found an example of component deletion in the forum which is similar to my recorded journal. Thus I parameterized them a little bit and they work fine with most parts except for the NX example "PlateWithHoles". The extrusion somehow stays there.
Is it because the plate is a sheet body?
If so, how can I deal with it?
I tried the DeleteBody class by referring to API reference and p.47 in Getting Started with NXOpen, and puzzled the first 6 lines of codes.
The problem is that I get NXException: target body missing.
There is indeed body in the partBodiesArray2, so why is the target body missing?
Thanks for your reply in advance and happy new year!
Best regards,
Ray
my codes
''Lösche die Extrusion / Delete the Extrusion
'Dim deleteBody As NXOpen.Features.DeleteBody = Nothing
'Dim deleteBodyBuilder As NXOpen.Features.DeleteBodyBuilder
'deleteBodyBuilder = workPart.Features.CreateDeleteBodyBuilder(deleteBody)
'partBodiesArray2(1) = deleteBodyBuilder.Commit
'deleteBodyBuilder.Destroy
Dim markId1 As NXOpen.Session.UndoMarkId = Nothing
markId1 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Delete Extrusion")
theSession.UpdateManager.ClearErrorList()
Dim markId2 As NXOpen.Session.UndoMarkId = Nothing
markId2 = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Delete Extrusion")
Dim objects1(0) As NXOpen.TaggedObject
'Dim extrude1 As NXOpen.Features.Extrude = CType(workPart.Features.FindObject("EXTRUDE(32)"), NXOpen.Features.Extrude)
objects1(0) = partBodiesArray2(1)
Dim nErrs1 As Integer = Nothing
nErrs1 = theSession.UpdateManager.AddObjectsToDeleteList(objects1)
Dim id1 As NXOpen.Session.UndoMarkId = Nothing
id1 = theSession.NewestVisibleUndoMark
Dim nErrs2 As Integer = Nothing
nErrs2 = theSession.UpdateManager.DoUpdate(id1)
theSession.DeleteUndoMark(markId1, Nothing)
re: delete body
Are there any features that depend on the body in partBodiesArray2? If so, NX may not let you delete it without confirming what you want done with the dependent features.
If you are creating an extrusion just for measurement purposes, I'd suggest setting an undo mark, creating the extrusion, taking the measurement, and rolling back to the undo mark. Pseudo code below:
Dim measureResult as double
dim anUndoMark as undoMark
create extrusion
measureResult = your measure
roll back to anUndoMark
An example can be found in the "measure bounded plane" example that I gave you here:
https://nxjournaling.com/comment/6572#comment-6572
Re: Delete and Measure the Extrusion
Hello NXJournaling,
I can finally delete the body, by adjusting the index of the object() array :D
Dim objects1(0) As NXOpen.TaggedObject
Dim upperBound As Integer
upperBound = UBound(partBodiesArray2)
objects1(0) = partBodiesArray2(upperBound)
Dim nErrs1 As Integer = Nothing
nErrs1 = theSession.UpdateManager.AddObjectsToDeleteList(objects1)
Dim id1 As NXOpen.Session.UndoMarkId = Nothing
id1 = theSession.NewestVisibleUndoMark
Dim nErrs2 As Integer = Nothing
nErrs2 = theSession.UpdateManager.DoUpdate(id1)
theSession.DeleteUndoMark(markId1, Nothing)
I measured both bodies (plate and extrusion) and all the normal vectors on every face. Then I save the faces whose normal vectors are contrary to the selected face (dispObj1) in the list “allBodyFaces”. There should be two this kind of faces, one on the plate, one on the extrusion.
I access the extruded face and measure it (see my codes below). However, the area of the extruded face is still the same as the plate with hole (1793,1416mm^2), instead of 2500mm^2. And to my surprise, both areas in the allBodyFaces array are the same as 1793,1416mm^2, which should be 1793,1416mm^2 and 2500mm^2 respectively…
Even if I measured the two faces whose normal vectors are the same as the selected face, the areas are both 1793,1416mm^2.
What’s the logic pitfall in my methodology?
'greifen die extrudierte fläche durch den normalvektor, der gegenseitigen von der ausgewählten fläche ist.
'/ access the extruded face by getting the opposite normal vector from the selected face
Dim partBodiesArray2() As Body
Dim theBody2 As Body
Dim partBodies2 As BodyCollection
partBodies2 = workPart.Bodies
partBodiesArray2 = partBodies2.ToArray()
Dim norm3(2) As Double
Dim allBodyFaces As New List(Of Face)()
For Each theBody2 In partBodiesArray2
For Each bodyFace As Face In theBody2.GetFaces()
theUfSession.Modl.AskFaceProps(bodyFace.Tag, param, pt, u1, v1, u2, v2, norm3, radii)
lw.WriteLine("Normalvektor X:" & formatnumber(norm3(0), 2).ToString & " Y:" &
formatnumber(norm3(1), 2).ToString & " Z:" &
formatnumber(norm3(2), 2).ToString)
If norm3(0) = norm(0) * -1 AndAlso norm3(1) = norm(1) * -1 AndAlso norm3(2) = norm(2) * -1 Then
allBodyFaces.Add(bodyFace)
End If
Next bodyFace
Next theBody2
Dim arrayAllBodyFaces() As Face = allBodyFaces.ToArray()
Dim targetExtrudedBodyFace() As Face = {arrayAllBodyFaces(1)}
Dim measureFaces3 As MeasureFaces
For Each tempFace As Face In arrayAllBodyFaces
If allBodyFaces.Count > 0 Then
'Messe die tangente Flächengröße der Extrusion / measure the tagent face of the extrusion
measureFaces3 = workPart.MeasureManager.NewFaceProperties(areaUnit, lengthUnit, 0.999, arrayAllBodyFaces)
Dim x5, x6 As Double
x5 = measureFaces1.Area
x6 = measureFaces1.Perimeter
lw.WriteLine("Flächengröße: " & x5)
lw.WriteLine("äußerer Umfang der Extrusion: " & x6)
Else
lw.WriteLine("No target extruded face found.")
End If
Next
re: delete body
Since your code is creating the body with an extrude feature, you can just delete the extrude feature in code when you are done with it. This will eliminate any potential errors of deleting the wrong body.
Also, you can use extrudeFeature.GetBodies to get the body created by the temporary extrude and process it separately. This way you know which faces belong to your temporary extrude and which do not.
"What’s the logic pitfall in my methodology?"
It is impossible for me to definitively answer this question based on the small code snippet posted. But I do have a few comments that I hope are helpful:
For planar faces, the normal vector is the same across the entire face and it does not matter where you take the measurement. This is only true for planar faces. All other faces (cylindrical, spherical, etc), the normal vector will depend on the point location chosen on the face. Face.SolidFaceType will tell you what type of face you are dealing with.
Comparing 2 floating point values with the "equals" operator is bad practice. Do a websearch on "floating point problem" if you want to know why. To compare the face normal vectors, I suggest using the "negate" function on one of them and then using the "IsParallel" method (it uses a given tolerance value to compare the vectors) to see if they represent the same direction (or in your case, opposite directions since you negated one of them before the comparison).
For debugging purposes, I recommend using the face.Highlight method to highlight all the faces that you are interested in. This will help determine that your code is processing the intended faces. The highlighting will persist after the journal exits and can be removed by running a part cleanup with the "remove extraneous highlighting" option.
Re: delete body
Hello NXJournaling,
Nice! extrudeFeature.GetBodies saving the effort to iterate all the bodies. I’ll implement it tomorrow.
For laser cutting the face should be planar, but I’ll try Face.SolidFaceType tomorrow.
I read the Microsoft reference; is the negate function you mentioned like this?
If Not norm3(0) = norm(0) * -1 AndAlso norm3(1) = norm(1) * -1 AndAlso norm3(2) = norm(2) * -1 Then
Since the tolerance in isParallel is given like you said, can I just leave the argument empty? Or should I write something like 0.99?
https://docs.plm.automation.siemens.com/data_services/resources/nx/10/nx...
re: negate and isParallel
The Vec3 negate function will multiply each element of the array by -1 for you.
https://docs.plm.automation.siemens.com/data_services/resources/nx/10/nx...
The Vec3 isParallel function calculates the angle between the given vectors. If the sine of the angle is less than your supplied tolerance value, isParallel returns TRUE. Below is a snippet where we are testing to see if the plane of an arc is parallel to the absolute XZ plane within 0.25 degrees.
Dim angularTolerance As Double = 0.25 'angular tolerance in degrees
Dim vecTol As Double = Math.Sin(angularTolerance * Math.PI / 180) 'tolerance value converted for the vector function
'absolute Y vector
Dim YVec(2) As Double
YVec(0) = 0
YVec(1) = 1
YVec(2) = 0
For Each temp As Arc In workPart.Arcs
Dim arcZvec(2) As Double
arcZvec(0) = temp.Matrix.Element.Zx
arcZvec(1) = temp.Matrix.Element.Zy
arcZvec(2) = temp.Matrix.Element.Zz
Dim isParallel As Boolean = False
theUfSession.Vec3.IsParallel(YVec, arcZvec, vecTol, isParallel)
If isParallel Then
XZarcs.Add(temp)
End If
Re: Negate Function, IsParallel, Highlight
Hello NXJournaling,
I print Face.SolidFaceType, and all parts which we discussed before return 1. I suppose they are planar because when I try the example part „ShellModel“, it returns 5 which is SurfaceOfRevolution.
https://docs.plm.automation.siemens.com/data_services/resources/nx/12/nx...
I implement IsParallel and Face.Highlight (for this purpose I temporarily terminate extrude deletion). It does select the parallel faces (see the picture in the link), and my measurement does measure the highlighted faces. Nevertheless the measured area is 1793,1416mm^2 (with hole) instead of 2500mm^2, which is the same as the result of normal vector * -1…
What else can I try?
https://drive.google.com/file/d/1hVVjtHDC6rhvHv6bjBygS7xttOdX1r3d/view?p...
Here is my implementation, and I can also post my whole codes if needed.
Dim partBodiesArray2() As Body = extrudeFeature.GetBodies()
Dim theBody2 As Body
Dim norm3(2) As Double
Dim allExtrudedFaces As New List(Of Face)()
'Finden die parallele extrudierte Fläche zur ausgewählten Fläche durch IsParallel / Use IsParallel to find the parallel extruded face
Dim angularTolerance As Double = 0.25 'angular tolerance in degrees
Dim vectorTolerance As Double = System.Math.Sin(angularTolerance * System.Math.PI / 180)
Dim isParallel As Boolean = False
If partBodiesArray2.Length > 0 Then
For Each theBody2 In partBodiesArray2
For Each bodyFace As Face In theBody2.GetFaces()
theUfSession.Modl.AskFaceProps(bodyFace.Tag, param, pt, u1, v1, u2, v2, norm3, radii)
lw.WriteLine("Normalvektor X:" & formatnumber(norm3(0), 2).ToString & " Y:" &
formatnumber(norm3(1), 2).ToString & " Z:" &
formatnumber(norm3(2), 2).ToString)
theUfSession.Vec3.IsParallel(norm3, norm, vectorTolerance, isParallel)
If isParallel Then
allExtrudedFaces.Add(bodyFace)
End If
Next bodyFace
Next theBody2
Else
lw.WriteLine("No extruded body")
End If
Dim arrayExtrudedBodyFaces() As Face = allExtrudedFaces.ToArray()
Dim targetExtrudedBodyFace() As Face = {arrayExtrudedBodyFaces(0)}
Dim measureFaces3 As MeasureFaces
For Each tempFace As Face In arrayExtrudedBodyFaces
If allExtrudedFaces.Count > 0 Then
'Messe die tangente Flächengröße der Extrusion / measure the tagent face of the extrusion
measureFaces3 = workPart.MeasureManager.NewFaceProperties(areaUnit, lengthUnit, 0.999, arrayExtrudedBodyFaces)
Dim x5, x6 As Double
x5 = measureFaces1.Area
x6 = measureFaces1.Perimeter
lw.WriteLine("Flächengröße: " & x5)
lw.WriteLine("äußerer Umfang der Extrusion: " & x6)
Else
lw.WriteLine("No target extruded face found.")
End If
Next
re: measure face code
For Each tempFace As Face In arrayExtrudedBodyFaces
If allExtrudedFaces.Count > 0 Then
'Messe die tangente Flächengröße der Extrusion / measure the tagent face of the extrusion
measureFaces3 = workPart.MeasureManager.NewFaceProperties(areaUnit, lengthUnit, 0.999, arrayExtrudedBodyFaces)
Dim x5, x6 As Double
x5 = measureFaces1.Area
x6 = measureFaces1.Perimeter
lw.WriteLine("Flächengröße: " & x5)
lw.WriteLine("äußerer Umfang der Extrusion: " & x6)
Else
lw.WriteLine("No target extruded face found.")
End If
Next
In this section of code, you have created "measureFaces3" to measure the face, but "x5" and "x6" reference "measureFaces1". I suspect that "measureFaces1" was created earlier in the code to measure the original face. If this is the case, you are displaying values for the wrong face in this loop.
Re: measure face code
Hello NXJournaling,
Thanks for the hint! I feel as if I made a stupid mistake in the final exam XD
The area is reported correctly and I can concentrate on the thickness issue now :D
Best regards,
Ray