Find (create) both points where the axis intersects the body (convex)

Find (create) both points where the axis intersects the body (convex)

Maxim-CADman77
Advisor Advisor
860 Views
3 Replies
Message 1 of 4

Find (create) both points where the axis intersects the body (convex)

Maxim-CADman77
Advisor
Advisor

Nowadays I'm working on a project where apart from the rest tasks I need to find both points where the given axis intersects the given surface body (solid).

As a most close guide to follow I've found this article - projecting-points-onto-a-solid 

With some modification I managed to get a bit closer code. Here it is:

 

Dim oIPT = ThisDoc.Document
Dim oPCD = oIPT.ComponentDefinition

' Dim sk As PlanarSketch = oPCD.Sketches("The_Sketch")

' The body to project onto
Dim body As SurfaceBody = ThisApplication.CommandManager.Pick(kPartBodyFilter, "Select the body")

Dim oIL = oPCD.WorkAxes("oIL")
Dim skNormal As UnitVector = oIL.Line.Direction
' skNormal = sk.PlanarEntityGeometry.Normal

Dim skRootPoint As Point=oIL.Line.RootPoint ' ~ about Origin (wrong side to project with given Vector??)
' skRootPoint = sk.PlanarEntityGeometry.RootPoint

' oWWW=oPCD.Workpoints.AddFixed(skRootPoint) : oWWW.Name="skRootPoint"

Dim tg As TransientGeometry
tg = ThisApplication.TransientGeometry

' Construct a matrix where the X axis is along the sketch plane normal.
Dim xAxis As Vector
xAxis = skNormal.AsVector

Dim yAxis As Vector
yAxis = tg.CreateVector(xAxis.x + 1, xAxis.y + 1, xAxis.Z + 1)

Dim zAxis As Vector
zAxis = xAxis.CrossProduct(yAxis)

yAxis = zAxis.CrossProduct(xAxis)
xAxis.Normalize
yAxis.Normalize
zAxis.Normalize

Dim transform As Matrix
transform = tg.CreateMatrix
Call transform.SetCoordinateSystem(skRootPoint, xAxis, yAxis, zAxis)
transform.Invert

' offset = 0

Dim offsetVector As Vector
offsetVector = skNormal.AsVector
' Call offsetVector.ScaleBy(offset) ' ??

' *** Perform the intersection calculation of every center point in the sketch.

Dim resultPoints As ObjectCollection
resultPoints = ThisApplication.TransientObjects.CreateObjectCollection
Dim skPoint As SketchPoint

Dim pnt As Point = skRootPoint

' Move the point outside the solid.
Call pnt.TranslateBy(offsetVector)

' Intersect the point with the solid.
Dim foundEnts As ObjectsEnumerator
Dim locPoints As ObjectsEnumerator
Call body.FindUsingRay(pnt, skNormal, 0.00001, foundEnts, locPoints, True)

' If an intersection was found, add it to the list.
If locPoints.count > 0 Then
	 Call resultPoints.Add(locPoints(1))
End If

For i = 1 To resultPoints.count
	 Call oPCD.WorkPoints.AddFixed(resultPoints(i))
Next

 

For some bodies (I believe it depends on body location related to the model origin) it does build one of the required  points (try choose "Solid 1" in the sample IPT attached, 2021.3.1).

 

Unfortunately I stuck a bit and currently don't understand how to modify it further to get what I need thus ask for some help from community, please.

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Accepted solutions (1)
861 Views
3 Replies
Replies (3)
Message 2 of 4

JhoelForshav
Mentor
Mentor

Hi @Maxim-CADman77 

Maybe I don't understand what your goal is, but it seems to me that you're making this more complex than it really is.

My approach would be to just get the line from the axis. Find using ray in both directions along the axis from the rootpoint and just collect all the locationpoints i get back. Something like this:

 

Sub Main
	Dim oBod As SurfaceBody = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartBodyFilter, "Pick body.")
	Dim oAxis As WorkAxis = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kWorkAxisFilter, "Pick axis")


	For Each oPoint As Point In CreateIntersectionPoints(oBod, oAxis)
		ThisDoc.Document.ComponentDefinition.WorkPoints.AddFixed(oPoint)
	Next

End Sub
Function CreateIntersectionPoints(sb As SurfaceBody, ax As WorkAxis) As ObjectCollection
	Dim oLine As Line = ax.Line
	Dim oVector As UnitVector = oLine.Direction
	Dim oPoint As Point = oLine.RootPoint
	Dim oPoints As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oLocPoints As ObjectsEnumerator
	sb.FindUsingRay(oPoint, oVector, 0, Nothing, oLocPoints)
	For Each lPoint As Point In oLocPoints
		oPoints.Add(lPoint)
	Next
	Dim invertVector As Vector = oVector.AsVector
	invertVector.ScaleBy(-1)
	sb.FindUsingRay(oPoint, invertVector.AsUnitVector, 0, Nothing, oLocPoints)
	For Each lPoint As Point In oLocPoints
		oPoints.Add(lPoint)
	Next
	Return oPoints
End Function

 

0 Likes
Message 3 of 4

Maxim-CADman77
Advisor
Advisor

@JhoelForshav 

FindUsingRay method works ok for cases when Axis intersects each entity just once but it does not return the second (I believe the far one) point for multiple intersections with non-flat entity, ex cylindrical face (see the Inventor 2022 sample IPT attached) which corresponds to the description of the "LocationPoints" argument (Output ObjectsEnumerator that returns a set of Point objects. One Point object is returned for each entity ...).

Do you have any further ideas on how to overcome this?

 

BTW, How do you paste colored iLogic-code?
(I see neither "iLogic" nor "VB.Net" within 12 entries of drop-down list of "Insert/edit code sample" forum message editor control, and none of the 12 color it the same way it is colored in your message).

Please vote for Inventor-Idea Text Search within Option Names

0 Likes
Message 4 of 4

JhoelForshav
Mentor
Mentor
Accepted solution

Hi @Maxim-CADman77 

Let's use FindUsingVector instead then 🙂

This code should work on your sample part.

Sub Main
	Dim oBod As SurfaceBody = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartBodyFilter, "Pick body.")
	Dim oAxis As WorkAxis = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kWorkAxisFilter, "Pick axis")


	For Each oPoint As Point In CreateIntersectionPoints(oBod, oAxis)
		ThisDoc.Document.ComponentDefinition.WorkPoints.AddFixed(oPoint)
	Next

End Sub
Function CreateIntersectionPoints(sb As SurfaceBody, ax As WorkAxis) As ObjectCollection
	Dim oDef As PartComponentDefinition = sb.Parent

	Dim oLine As Line = ax.Line
	Dim oVector As UnitVector = oLine.Direction
	Dim oPoint As Point = oLine.RootPoint
	Dim oPoints As ObjectCollection = ThisApplication.TransientObjects.CreateObjectCollection
	Dim oSelFilters(0) As SelectionFilterEnum
	oSelFilters(0) = SelectionFilterEnum.kPartFaceFilter
	Dim oFaces1 As ObjectsEnumerator = oDef.FindUsingVector(oPoint, oVector, oSelFilters)
	Dim invertVector As Vector = oVector.AsVector
	invertVector.ScaleBy(-1)
	Dim oFaces2 As ObjectsEnumerator = oDef.FindUsingVector(oPoint, invertVector.AsUnitVector, oSelFilters)
	
	Dim oFaces As New List(Of Face)
	For Each oFace In oFaces1
		If oFace.SurfaceBody Is sb AndAlso oFaces.Contains(oFace) = False Then oFaces.Add(oFace)
	Next
	For Each oFace In oFaces2
		If oFace.SurfaceBody Is sb AndAlso oFaces.Contains(oFace) = False Then oFaces.Add(oFace)
	Next
	For Each oFace In oFaces
		Dim foundPoints As ObjectsEnumerator = ThisApplication.TransientGeometry.CurveSurfaceIntersection(oLine, oFace.Geometry)
		For Each oPoint In foundPoints
			If TypeOf(oPoint) Is Point Then oPoints.Add(oPoint)
		Next
	Next
	Return oPoints
End Function

 

When it comes to colored iLogic code, that doesn't seem to work anymore. Before you could just copy the code from iLogic and it would keep its formatting and colors here on the forum.