Find dimension constraint specified by name in a sketch

Find dimension constraint specified by name in a sketch

FxRod
Enthusiast Enthusiast
615 Views
9 Replies
Message 1 of 10

Find dimension constraint specified by name in a sketch

FxRod
Enthusiast
Enthusiast

Hi again!

Another "share-your-knowledge"-post connected to the other one I just wrote. The next step in the workflow of finding a specified dimension after finding the sketch containing it, is often to highlight it in the sketch. I split the whole thing in two rules, because I do not always want to enter the sketch mode after finding a dimension. Of course it would be possible to connect both rules, entering the sketch mode immediately or after a user confirmation, and highlighting the constraint in the same rule.
Once again: Did I miss any easier solution shipped by Autodesk?

If TypeOf ThisApplication.ActiveEditObject Is Sketch Then
	Dim oDoc As PartDocument = ThisDoc.Document
	Dim oSketch As Sketch = ThisApplication.ActiveEditObject
	Dim name As String = InputBox("Enter the name of the dimension to find:", "Find dimension")
	If (name <> "") Then
		Dim waehl As SelectSet = oDoc.SelectSet
		waehl.Clear
		For Each oDimConst As DimensionConstraint In oSketch.DimensionConstraints
			If (oDimConst.Parameter.Name = name) Then
				Logger.Info(oDimConst.Parameter.Name)
				waehl.Select(oDimConst)
			End If
		Next
	End If
End If
0 Likes
Accepted solutions (1)
616 Views
9 Replies
Replies (9)
Message 2 of 10

JelteDeJong
Mentor
Mentor

I think you can improve the code a bit by removing the nested loop and if statements. I think that it makes the code more readable.

Did you know that there is a vb.net built-in function to check if a string is empty?  The function: "string.IsNullOrWhiteSpace(...)" will check for all kinds of invalid user input like spaes (or null characters)

Using the = operator to compare strings is not your best option. using the "string.Equals(...)" function is better. The most obvious reason is probably that it allows you to ignore case sensitivity. Wich is much nicer for the users.

If ThisApplication.ActiveEditObject.Type <> ObjectTypeEnum.kPlanarSketchObject Then Return

Dim name As String = InputBox("Enter the name of the dimension to find:", "Find dimension")
If (String.IsNullOrWhiteSpace(name)) Then Return

Dim oDoc As PartDocument = ThisDoc.Document
Dim oSketch As Sketch = ThisApplication.ActiveEditObject

Dim waehl As SelectSet = oDoc.SelectSet
waehl.Clear()

' use LINQ to find the constraints
Dim constraint As DimensionConstraint = oSketch.DimensionConstraints.Cast(Of DimensionConstraint).
	Where(Function(d) d.Parameter.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase)).
FirstOrDefault() ' Check if the constraint was found If (constraint Is Nothing) Then Return Logger.Info(constraint.Parameter.Name) waehl.Select(constraint)

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 3 of 10

FxRod
Enthusiast
Enthusiast

Hi Jelte,

 

thanks for the improvements, I don't know much about VB. I'm familiar with the concepts of the "where" and the string functions from other languages though, maybe was a bit lazy to not find out how they work here. Very nice that I know now. 😄

 

Is it old-fashioned that I don't like to have many returns in a script by the way?

0 Likes
Message 4 of 10

FxRod
Enthusiast
Enthusiast

By the way I like to use the nested loops for testing during development, as I can output everything the loop processes to the logger and see if that's what I expected it to iterate through, before I go on writing what to do with a specific element. Of course for the final version using "where" is way smoother.

0 Likes
Message 5 of 10

JelteDeJong
Mentor
Mentor
Accepted solution

I know that returning in the middle of a function is seen as bad practice by some people. But I prefer returns if it prevents nested functions. Maybe you could see it as satisfying the fail-fast rule?

 

I can imagen that you want to log things for debugging or any other reason. In that case, I would write it like this. No nesting but you can have the logging. Also if I would expect to find 0 or more items on my list then I would do this anyway. Another advantage is that you lose the null check here. (And the return halfway through the function.)

If ThisApplication.ActiveEditObject.Type <> ObjectTypeEnum.kPlanarSketchObject Then Return

Dim name As String = InputBox("Enter the name of the dimension to find:", "Find dimension")
If (String.IsNullOrWhiteSpace(name)) Then Return

Dim oDoc As PartDocument = ThisDoc.Document
Dim oSketch As Sketch = ThisApplication.ActiveEditObject

Dim waehl As SelectSet = oDoc.SelectSet
waehl.Clear()

' use LINQ to find the constraints
Dim constraints As List(Of DimensionConstraint) = oSketch.DimensionConstraints.Cast(Of DimensionConstraint).
    Where(Function(d) d.Parameter.Name.Equals(name, StringComparison.CurrentCultureIgnoreCase)).ToList()

' Loop over all the found constraints
For Each constraint As DimensionConstraint In constraints
    logger.Info(constraint.Parameter.Name)
    waehl.Select(constraint)
Next

 

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

0 Likes
Message 6 of 10

FxRod
Enthusiast
Enthusiast

Yeah sure that would output the items that are found, so for the finished script this is the way to go.

 

In the earlier state I mentioned, I like to first output all items that should then be compared to some criteria, to see if the input for the comparison is what I think it is. But that's also possible using the list, I could first initialize the list with the collection / list / whatever is the input, output that and then run the cast.where, either on the list or the source of the list. That would work about the same as my previous way.

0 Likes
Message 7 of 10

Zach.Stauffer
Advocate
Advocate

If I have a complicated rule that I'm trying to figure out, I like to use the Visual Studio debugger. Then you could set a breakpoint after retrieving your objects and make sure they are what you think they should be. For simple rules I just use the built in Logger though.

 

Mod the Machine - Debugging iLogic in Visual Studio 

0 Likes
Message 8 of 10

FxRod
Enthusiast
Enthusiast

I must admit that I do have VisualStudio installed, but mostly I come across ideas for scripts while designing something, so there is a big temptation to use the internal editor instead of starting a different program... but of course debugging would be much easier with that. Maybe I should train myself to start VS every time I start writing code. The possibility to watch objects and references dynamically would be a big advantage.

Message 9 of 10

JelteDeJong
Mentor
Mentor

If you have VS installed then you could clone my VS project from GitHub. That project allows you to write and debug rules in VS (This is another approach than only debugging in VS). And when your rule is ready for production then you can just copy and past the code to the iLogic editor. More info can be found in my blog post "Writing and debugging iLogic rules"

 

Jelte de Jong
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

EESignature


Blog: hjalte.nl - github.com

Message 10 of 10

FxRod
Enthusiast
Enthusiast

I actually installed VS after reading exactly this blogpost. Didn't clone the workspace though, because I didn't do much development back then. And then that task rotted on my todos. Now it got bumped up a bit. 🙂

0 Likes