Reply
Solved! Go to solution

Face at bottom end of hole

[ Edited ]

Hello,

i'm working on a tool to convert an existing hole. I want to add new holes at the position of the existing hole. At the moment, i can place new holes at the same end as the existing hole and add a concentric relation ship to the existing hole.

My next step would be to add a hole at the bottom end of the existing hole. I want to find the face at the bottom of a hole. I tried many things, but had no success.

FacesFaces

 

I receive the top "face" from profile plane.

Dim profile As Profile
Dim pl As RefPlane

profile = DirectCast(_hole.Profile, Profile)
pl = DirectCast(profile.Plane, RefPlane)

If i get the face of the profile.plane, it could be possible to measure the "normaldistance" to the edges of the hole and get the bottom face.

How can i receive the face for this plane?

Is there an easy way to check if a face is on the profile.plane?

 

Greetings from Germany
Christian Kunkel
https://c-k-m.info
3 REPLIES

Re: Face at bottom end of hole

[ Edited ]

Hi Christian:

 

I too worked on a similar challenge recently but found no direct way of getting the bottom cap even when the hole was blind or finite depth.

I started with the hole face which would be the cylindrical face.

Get the edges of the hole - top and bottom. Figure out which one is the bottom edge, it would typically be at index 0 or 1.

From the bottom edge, again get the attached face using GetFaces. One of the faces would again be the cylindrical hole face and the other would be the required bottom face.

This would work for most simple holes where there is no chamfer or round on the bottom edge for some reason. It is pretty much kind of hard-coding or with several assumptions.

   

Sorry, can't post any code out here.

   

Best,

~Tushar Suradkar

 

fb.pngSolid Edge Users Facebook Group



Re: Face at bottom end of hole

Hello Tushar,

thanks for your reply. I think i have a solution which is working for 95% of all situations.

I have no code at the moment, but when it's working correctly i will post it here. The steps in words:

  • Get the faces of the hole
  • Get a List (Of Integer) from face.ID for the faces
  • Get all the edges of the hole
  • Get all the faces for each edge
  • If the face.ID is not in the List (Of Integer) Then add the face to a List (Of Face)

In 95% you will receive two faces, the top and the bottom face of the hole

  • Add a RefPlane ParallelByDinstance to the two faces
  • Get the normal vector of the faces
  • Compare the normal vectors to the normal vector of the profile plane
  • The plane with the normal vector in the opposite direction of the profile plane is the bottom face.

The code is not working, if the hole goes through a cutout or if the top or the bottom plane has a cut which goes through the hole. Then you receive more then two faces.

For this cases i could need your help! In the great TopoTools which i used very often the last time, you have a button which let's the user select a face. This is exactly what i need.

If the code doesen't return two faces i would like to let the user select the face.

Could you give me some hint's?

 

Greetings from Germany
Christian Kunkel
https://c-k-m.info
Solution
Solution
Accepted by topic author ckunkel72
‎06-22-2016 04:00 AM

Re: Face at bottom end of hole

Hello,

here is the code to locate the bottom face of an ordered hole. It is not working for all situations. If the hole runs through a cutout or if the face at the end of the hole is not parallel to the profile plane of the hole it fails at the moment.

For the Vectors i use a modificated System.Windows.Media.Media3d.Vector3d. For the Vector3d you have to add a reference to PresentationCore.dll from Framework 4.0.

Imports SolidEdgeFramework
Imports SolidEdgeGeometry
Imports SolidEdgePart
Imports System.Windows.Media
	
Friend Module HelperModul
	
	Public Function BottomPlane(h As Hole) As RefPlane

		Dim profile As Profile
		Dim edgs As Edges
		Dim nrmTopPlane As Vector3D
		Dim lstHFID As List(Of Integer)
		Dim lstNonHoleFace As List(Of Face)
		Dim lstBottomFace As List(Of Face)
		Dim mdl As Model
		Dim par As PartDocument
		Dim refPlns As RefPlanes
		Dim topPl As RefPlane
		Dim btmPl As RefPlane

		'Get RefPLane of hole
		profile = DirectCast(h.Profile, Profile)
		topPl = DirectCast(profile.Plane, RefPlane)

		'Get List of the Face.ID for the hole
		lstHFID = New List(Of Integer)
		lstHFID = HoleFaceIDs(h)

		'Get List of all faces connected to edges of the hole which are no faces of the hole
		lstNonHoleFace = New List(Of Face)
		edgs = CType(h.Edges(FeatureTopologyQueryTypeConstants.igQueryAll), Edges)
		For Each ed As Edge In edgs
			Dim num As Integer
			Dim arrFc As Array
			arrFc = Array.CreateInstance(GetType(Face), 4)
			ed.GetFaces(num, arrFc)
			'More the 4 faces on one edge is a complex part.
			If num > 4 Then Throw New ArgumentOutOfRangeException
			For i = 0 To num - 1
				'Check if the face.id is in the list of the hole Face.ID, of not add to new list 
				If Not lstHFID.Contains(CType(arrFc.GetValue(i), Face).ID) Then lstNonHoleFace.Add(CType(arrFc.GetValue(i), Face))
			Next
		Next

		'Get the normal vector of the profile plane
		nrmTopPlane = New Vector3D
		topPl.GetNormal(nrmTopPlane.Vector)

		'Check the normal vector of the faces found earlier
		mdl = CType(h.Parent, Model)
		par = CType(mdl.Document, PartDocument)
		refPlns = par.RefPlanes
		lstBottomFace = New List(Of Face)
		For Each f As Face In lstNonHoleFace
			Dim tmpPln As RefPlane
			Dim tmpNrm As Vector3D
			tmpPln = refPlns.AddParallelByDistance(f, 0.0, ReferenceElementConstants.igNormalSide)
			tmpNrm = New Vector3D
			tmpPln.GetNormal(tmpNrm.Vector)
			'if the angle between the vectors is 180° this could be the bottom face
			If Media3D.Vector3D.AngleBetween(nrmTopPlane.Media3D, tmpNrm.Media3D) > 179.9 Then
				lstBottomFace.Add(f)
			End If
			tmpPln = Nothing
			tmpNrm = Nothing
		Next

		'The list should only contain face which could be the bottom face
		Select Case lstBottomFace.Count
			Case 0
				MessageBox.Show("Es wurde keine geeignete Fläche gefunden")
				'TODO: Let the user select a face and check it is at 180°
				Throw New NotImplementedException
			Case 1
				'hard work
				btmPl = refPlns.AddParallelByDistance(lstBottomFace.Item(0), 0.0, ReferenceElementConstants.igNormalSide)
			Case Else
				MessageBox.Show("Es wurde zuviele geeignete Fläche gefunden")
				'TODO: Let the user select a face and check it is at 180°
				Throw New NotImplementedException
		End Select

		Return btmPl

	End Function
	
	Private Function HoleFaceIDs(h As Hole) As List(Of Integer)

		Dim fcs As Faces
		Dim fID As New List(Of Integer)

		fcs = CType(h.Faces(FeatureTopologyQueryTypeConstants.igQueryAll), Faces)
		For Each f As Face In fcs
			fID.Add(f.ID)
		Next
		fcs = Nothing

		Return fID

	End Function
	
End Module

Class for the Vector3D

Imports System.Windows.Media

Friend Class Vector3D
	Private _vector As Media3D.Vector3D
	Public Property Vector As Array
		Get
			Dim ar As Array = Array.CreateInstance(GetType(Double), 3)
			ar.SetValue(X, 0)
			ar.SetValue(Y, 1)
			ar.SetValue(Z, 2)
			Return ar
		End Get
		Set(value As Array)
			If Not value.Length = 3 Then
				Throw New IndexOutOfRangeException
			End If
			_vector.X = CDbl(value.GetValue(0))
			_vector.Y = CDbl(value.GetValue(1))
			_vector.Z = CDbl(value.GetValue(2))
		End Set
	End Property

	Public Property Media3D As Media3D.Vector3D
		Get
			Return _vector
		End Get
		Set(value As Media3D.Vector3D)
			_vector = value
		End Set
	End Property

	Public Property X As Double
		Get
			Return _vector.X
		End Get
		Set(value As Double)
			_vector.X = value
		End Set
	End Property
	Public Property Y As Double
		Get
			Return _vector.Y
		End Get
		Set(value As Double)
			_vector.Y = value
		End Set
	End Property
	Public Property Z As Double
		Get
			Return _vector.Z
		End Get
		Set(value As Double)
			_vector.Z = value
		End Set
	End Property

	Public ReadOnly Property Length As Double
		Get
			Return _vector.Length
		End Get
	End Property

	Public ReadOnly Property LengthSquared As Double
		Get
			Return _vector.LengthSquared
		End Get
	End Property

	Public Sub Normalize()
		_vector.Normalize()
	End Sub

	Public Sub Negate()
		_vector.Negate()
	End Sub

	Public Overrides Function ToString() As String
		Return "{" & X & ";" & Y & ";" & Z & "}"
	End Function

End Class
Greetings from Germany
Christian Kunkel
https://c-k-m.info