Measuring Angles/Distances in active Sketch

Measuring Angles/Distances in active Sketch

llorden4
Collaborator Collaborator
1,892 Views
7 Replies
Message 1 of 8

Measuring Angles/Distances in active Sketch

llorden4
Collaborator
Collaborator

A series of obstacles within iLogic is forcing me to figure this feature out and I just can't get this figured.  Using iLogic to develop a sketch, there are angles and distances that I need to derive in order to complete my task.  I can place dimensional constraints as driven and read their values, but the Reference Parameter created is creating errors for my iLogic when attempting to delete it and recreate anew.  So if you have a solution for that, great, but I still need to know how to use this measure feature.

This link seems pretty straight forward and intuitive, but....

It's wanting the name of the Entity as an object, which I can't figure out the correct call/format in order to get these within the sketch.

llorden4_0-1625001934740.png

So if I have a Sketchline set to variable oSketchLine1 and another as oSketchLine2, I need to be able to measure the distance or angle between the two sketchlines, a sketchline and a start/end sketchpoint of that sketch feature, etc.

 

How do I call the command to return a value, or am I just using the wrong command for the task needed?

 

These samples didn't work:

Dist = Measure.GetMinimumDistance("SketchLine1", "SketchLine2.EndSketchPoint")

Dist = Measure.GetMinimumDistance(SketchLine1.Entity.OwnedBy, SketchLine2.Entity.OwnedBy)

Autodesk Inventor Certified Professional
0 Likes
Accepted solutions (1)
1,893 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor

Sometimes the built-in tools for measuring in iLogic do seem a bit inadequate, and they aren't always a good fit for some of the stuff we try to use them for.  It can take a bit of time to set-up, but it may pay off in the long run to create a set of custom reference Subs &/or Functions for measuring/comparing different specific types of geometry for these occasions.

 

In this case (which is likely simplified for testing purposes), it seems like you are comparing two regular 2d lines in a PlanarSketch.  In this situation, we have several other built-in tools for comparing/measuring them, that you just have to dig a little deeper for.  I created an example part file, and manually created a sketch on a plane and put two non-parallel lines on it that don't touch each other.  Then I created this iLogic rule to compare the two lines.  In this rule I isolated all the comparison work in a custom Function, and to keep it as useful as possible, I'm having that function return a NameValueMap (native to Inventor - could use a Dictionary or other collection type that uses Key/Value pairs).  Then I use a simple multi-line MsgBox to display the results to the user.  The resulting NameValueMap includes 4 name/value pairs (Parallel (Boolean), Perpendicular (Boolean), Angle (Double), and Distance (Double)).

Here's the iLogic rule code that I've got right now:

 

Sub Main
	Dim oPDoc As PartDocument = ThisApplication.ActiveDocument
	Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
	Dim oSketch As PlanarSketch = oPDef.Sketches.Item("Measure Test Sketch")
	Dim oSketchLine1 As SketchLine = oSketch.SketchLines.Item(1)
	Dim oSketchLine2 As SketchLine = oSketch.SketchLines.Item(2)
	Dim oResult As NameValueMap = Line2dCompare(oSketchLine1, oSketchLine2)
	MsgBox(oResult.Name(1) & " = " & oResult.Value(oResult.Name(1)) & vbCrLf & _
	oResult.Name(2) & " = " & oResult.Value(oResult.Name(2)) & vbCrLf & _
	oResult.Name(3) & " = " & oResult.Value(oResult.Name(3)) & vbCrLf & _
	oResult.Name(4) & " = " & oResult.Value(oResult.Name(4)),,"RESULTS")
End Sub

Function Line2dCompare(oLin1 As SketchLine, oLin2 As SketchLine) As NameValueMap
	Dim oResults As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	Dim oParallel, oPerpendicular As Boolean 'both False by default
	Dim oAngle As Double
	Dim oDist As Double
	
	Dim oDir1 As UnitVector2d = oLin1.Geometry.Direction
	Dim oDir2 As UnitVector2d = oLin1.Geometry.Direction
	oAngle = oDir1.AngleTo(oDir2)

	If oDir1.IsParallelTo(oDir2, .001) Then
		oParallel = True
		'or measure the distance between them and return that Double
		oDist = oLin1.Geometry.DistanceTo(oLin2.Geometry.StartPoint)
	ElseIf oDir1.IsPerpendicularTo(oDir2, .001) Then
		oPerpendicular = True
		If oLin1.Geometry.IntersectWithCurve(oLin2.Geometry).Count > 0 Then
			'they intersect, so set oDist to zero
			oDist = 0
		Else
			'you could attempt to measure the minimum distance between the two
			Dim oD1 As Double = oLin1.Geometry.DistanceTo(oLin2.Geometry.StartPoint)
			Dim oD2 As Double = oLin1.Geometry.DistanceTo(oLin2.Geometry.EndPoint)
			oDist = Min(oD1, oD2)
		End If
	End If
	
	If oParallel = False And oPerpendicular = False Then
		'now attempt to get the 'minimum' distance between the two non parralel line segments
		'since these are staight lines, this distance will be between start/end points, so compare them for minimum
		Dim oL1Sp, oL1Ep, oL2Sp, oL2Ep As Point2d
		oL1Sp = oLin1.StartSketchPoint.Geometry
		oL1Ep = oLin1.EndSketchPoint.Geometry
		oL2Sp = oLin2.StartSketchPoint.Geometry
		oL2Ep = oLin2.EndSketchPoint.Geometry
		Dim oSpDist As Double = oL1Sp.DistanceTo(oL2Sp) 'start point to start point (-)
		Dim oEpDist As Double = oL1Ep.DistanceTo(oL2Ep) 'end point to end point (-)
		Dim oSEDist As Double = oL1Sp.DistanceTo(oL2Ep) 'start point to end point (x)
		oDist = MinOfMany(oSpDist, oEpDist, oSEDist)
	End If
	
	oResults.Add("Parallel", oParallel)
	oResults.Add("Perpendicular", oPerpendicular)
	oResults.Add("Angle", oAngle)
	oResults.Add("Distance", oDist)
	Return oResults
End Function

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION.
Or, if this helped you, please click (LIKE or KUDOS) 👍.

If you want and have time, I would appreciate your Vote(s) for My IDEAS 💡or you can Explore My CONTRIBUTIONS

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 8

llorden4
Collaborator
Collaborator

Thanks for the sample code, but the answer to my root question is that there doesn't appear to be any pre-made tools in iLogic while in a sketch environment and thus I need to keep developing my own routines (as you've done here) to continue to develop our own tools to determine values.

Autodesk Inventor Certified Professional
0 Likes
Message 4 of 8

J-Camper
Advisor
Advisor
Accepted solution

That method is not looking for names of entities, it is looking for the objects themselves.  This should work:

Dim pDef As PartComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition

Dim mySketch As PlanarSketch = pDef.Sketches.Item(1)

Dim Dist As Double = ThisApplication.MeasureTools.GetAngle(mySketch.SketchLines.Item(1), mySketch.SketchLines.Item(2)) / (Math.PI / 180)

MessageBox.Show(Dist, "Angle")

ExampleExample

Figuring out which sketchlines you need to get angles from you require you to keep track of the sketchlines you are making.

 

Let me know if you have any questions, or if this is not working as intended

Message 5 of 8

WCrihfield
Mentor
Mentor

After revisiting and reviewing my old code a little closer, I noticed that not only did some stuff not copy over correctly (did it in chunks from larger code then manually edited it together on post), but it really needed to be updated for efficiency. 🤔  I also added in a note about possibly using a Dictionary as an alternative to using the NameValueMap.

So here is a slightly updated version of it, just for the records. 😉

Sub Main
	Dim oPDoc As PartDocument = ThisApplication.ActiveDocument
	Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
	Dim oSketch As PlanarSketch = oPDef.Sketches.Item("Measure Test Sketch")
	'specify which 2 sketch lines to compare (one way or another)
	Dim oSketchLine1 As SketchLine = oSketch.SketchLines.Item(1)
	Dim oSketchLine2 As SketchLine = oSketch.SketchLines.Item(2)
	'call reference Function here which compares the 2 lines
	Dim oResult As NameValueMap = Line2dCompare(oSketchLine1, oSketchLine2)
	'use the results here - MsgBox user feedback in this case

	'MsgBox(oResult.Name(1) & " = " & oResult.Value(oResult.Name(1)) & vbCrLf & _
	'oResult.Name(2) & " = " & oResult.Value(oResult.Name(2)) & vbCrLf & _
	'oResult.Name(3) & " = " & oResult.Value(oResult.Name(3)) & vbCrLf & _
	'oResult.Name(4) & " = " & oResult.Value(oResult.Name(4)), , "RESULTS")
	'or
	Dim oParallel As Boolean = oResult.Value("Parallel")
	Dim oPerpendicular As Boolean = oResult.Value("Perpendicular")
	Dim oAngle As Double = oResult.Value("Angle")
	Dim oDistance As Double = oResult.Value("Distance")
	MsgBox("Parralel = " & oParallel & vbCrLf & _
	"Perpendicular = " & oPerpendicular & vbCrLf & _
	"Angle = " & oAngle & vbCrLf & _
	"Distance = " & oDistance, , "RESULTS")
End Sub

Function Line2dCompare(oLin1 As SketchLine, oLin2 As SketchLine) As NameValueMap
	Dim oResults As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	'or to use a Dictionary instead of NameValueMap
	'Dim oResults As Dictionary = New Dictionary(Of String, Object)
	'oResults.Add("Angle", oAngle) '-just an example entry
	Dim oParallel, oPerpendicular As Boolean 'both False by default
	Dim oAngle As Double
	Dim oDist As Double
	
	Dim oDir1 As UnitVector2d = oLin1.Geometry.Direction
	Dim oDir2 As UnitVector2d = oLin2.Geometry.Direction
	oAngle = oDir1.AngleTo(oDir2)

	If oDir1.IsParallelTo(oDir2, .001) Then
		oParallel = True
		'measure the distance between them - 'it's parallel so it doesn't matter which end you measure to
		oDist = oLin1.Geometry.DistanceTo(oLin2.Geometry.StartPoint)
		GoTo Output
	End If
	If oDir1.IsPerpendicularTo(oDir2, .001) Then
		oPerpendicular = True
		If oLin1.Geometry.IntersectWithCurve(oLin2.Geometry).Count > 0 Then
			'they intersect, so set oDist to zero
			oDist = 0
			GoTo Output
		End If
	End If
	
	'if reads this part, the 2 lines are not parallel and don't intersect
	'now attempt to get the 'minimum' distance between them
	Dim oD1 As Double = oLin1.Geometry.DistanceTo(oLin2.Geometry.StartPoint)
	Dim oD2 As Double = oLin1.Geometry.DistanceTo(oLin2.Geometry.EndPoint)
	Dim oD3 As Double = oLin2.Geometry.DistanceTo(oLin1.Geometry.StartPoint)
	Dim oD4 As Double = oLin2.Geometry.DistanceTo(oLin1.Geometry.EndPoint)
	oDist = MinOfMany(oD1, oD2, oD3, oD4)
	
	Output :
	oUOM = ThisApplication.UnitsOfMeasure
	'convert default database Angle units (Radians) to Degrees
	oAngle = oUOM.ConvertUnits(oAngle, UnitsTypeEnum.kDatabaseAngleUnits, UnitsTypeEnum.kDegreeAngleUnits)
	'convert default database Length units (Centimeters) to Inches
	oDist = oUOM.ConvertUnits(oDist, UnitsTypeEnum.kDatabaseLengthUnits, UnitsTypeEnum.kInchLengthUnits)
	
	oResults.Add("Parallel", oParallel)
	oResults.Add("Perpendicular", oPerpendicular)
	oResults.Add("Angle", oAngle)
	oResults.Add("Distance", oDist)
	Return oResults
End Function

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 8

llorden4
Collaborator
Collaborator

Yes, this is exactly what I'm hoping for, but you hit the nail on the head, I have to track which sketch item is what myself, but I get what you're saying and the needed format.  Maybe I can find a way to search through all those items and find a matching header of some kind to match a property against the current sketchline.item(#)  being compared....

Autodesk Inventor Certified Professional
0 Likes
Message 7 of 8

J-Camper
Advisor
Advisor

It is nearly impossible for me to help figure out a plan for tracking the sketchlines without knowing the end goal and the creation process you are currently implementing.  If you are willing to post some of the code you are working on, I could try to help further; otherwise, good luck with your endeavor.

0 Likes
Message 8 of 8

llorden4
Collaborator
Collaborator

Oh I agree, I am asking a general question for broad application; not looking for a Huckleberry to do my homework.  You gave me exactly what I needed, thanks!

Autodesk Inventor Certified Professional
0 Likes