Measure - NameValueMap

Measure - NameValueMap

miha_bokan
Enthusiast Enthusiast
607 Views
5 Replies
Message 1 of 6

Measure - NameValueMap

miha_bokan
Enthusiast
Enthusiast

Hello dear friends,

 

I am trying to find out the orientation (top, front, right), where the width x height is at their max. So with the help of Forum I wrote this function:

Sub findOrient()	
        MaxX = Round(Measure.ExtentsLength, 0) 'X
	MaxY = Round (Measure.ExtentsWidth,0) 'Y
	MaxZ = Round(Measure.ExtentsHeight, 0) 'Z
	
	If MaxOfMany(MaxX, MaxY, MaxZ) = MaxX Then
		If MaxY > MaxZ Then
			oOrient = kFrontViewOrientation
		Else
			oOrient = kTopViewOrientation
		End If
         elseif
            .... pattern
         end if
end sub

 oOrient is global function.

 

On assembly level and part level, this function does, what it should, but when I loop through part on assembly level, I cann't make it work. I tried to open referenced document, and use the function:

 

For Each oRefDoc As Document In oDoc.AllReferencedDocuments
    oControlDoc = ThisApplication.Documents.Open(oRefDoc.FullFileName, True)
    oControlDoc.Activate
    Call oOrient()
Next

 

Externalrule on the other hand, gives satisfying results, but sadly I don't know how to access that Info.

There is probably a way using Namevaluemap objects, and sending value back to main program, but after few attempts, I gave up.

Could someone help me?

0 Likes
Accepted solutions (1)
608 Views
5 Replies
Replies (5)
Message 2 of 6

Michael.Navara
Advisor
Advisor
Accepted solution

This question can be added to context. But you can avoid to use Measure.Extents... methods and use RangeBox instead. This is what this method uses in background. In this case you can easily iterate over all documents and get requested orientation.

 

The second thing is tu use iLogic function MinOfMany instead MaxOfMany which simplifies the code.

 

 

Sub Main()

    For Each refDoc As Document In ThisDoc.Document.AllReferencedDocuments
        Dim oOrient = FindOrient(refDoc.ComponentDefinition)

        Logger.Debug("{0} - {1}", refDoc.DisplayName, oOrient)
    Next
End Sub


Function FindOrient(compDef As ComponentDefinition) As ViewOrientationTypeEnum


    'This is what Measure.Extents... does
    Dim minPoint As Point = compDef.RangeBox.MinPoint
    Dim maxPoint As Point = compDef.RangeBox.MaxPoint

    Dim sizeX = maxPoint.X - minPoint.X
    Dim sizeY = maxPoint.Y - minPoint.Y
    Dim sizeZ = maxPoint.Z - minPoint.Z

    'Selection can be simplified
    If MinOfMany(sizeX, sizeY, sizeZ) = sizeX Then Return ViewOrientationTypeEnum.kRightViewOrientation
    If MinOfMany(sizeX, sizeY, sizeZ) = sizeY Then Return ViewOrientationTypeEnum.kTopViewOrientation
    If MinOfMany(sizeX, sizeY, sizeZ) = sizeZ Then Return ViewOrientationTypeEnum.kFrontViewOrientation

    'Without iLogic function MinOfMany
    'If sizeX <= sizeY And sizeX <= sizeZ Then Return ViewOrientationTypeEnum.kRightViewOrientation
    'If sizeY <= sizeX And sizeY <= sizeZ Then Return ViewOrientationTypeEnum.kTopViewOrientation
    'If sizeZ <= sizeX And sizeZ <= sizeY Then Return ViewOrientationTypeEnum.kFrontViewOrientation

    'Default
    Return ViewOrientationTypeEnum.kRightViewOrientation

End Function

 

 

How to pass arguments from local rule to external rule and back is little bit complicated but it is possible.

Local and external rules sample

 

'Local rule
Sub main

	Dim args As New ArgumentsClass()
	args.Number = 1
	args.Text = "One"

	Logger.Debug("Before call")
	Logger.Debug("{0}, {1}", args.Number, args.Text)

	Dim map As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
	map.Add("Args", args)
	iLogicVb.RunExternalRule("ExternalRuleName", map)



	Logger.Debug("After call")
	Logger.Debug("{0}, {1}", args.Number, args.Text)

End Sub

'Can be declared in separate file
Class ArgumentsClass
	Property Number As Double
	Property Text As String
End Class

 

 

 

'External Rule
Dim args = RuleArguments("Args")
args.Number = 2
args.Text = "Two"

 

 

Expected result in logger window (enable Debug logging level)

DEBUG|Before call
DEBUG|1, One
DEBUG|After call
DEBUG|2, Two
Message 3 of 6

WCrihfield
Mentor
Mentor

Tip:  Another utility I like to use in those situations, instead of MaxOfMany or MinOfMany or a series of comparison operators is to add the three sizes to a New List(Of Double), then use List.Sort method on it, then the first entry in the List (Item zero) will be the smallest value, and the last entry in it will be the largest value.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 4 of 6

miha_bokan
Enthusiast
Enthusiast

Hello guys!

sorry for the late answer. I tried out the suggested rangebox function and it worked! But! Interesting, FindOrient with rangebox function that @Michael.Navara wrote only worked in for loop. When I used FindOrient on assembly level document it didn't work. So I left both functions active in my code (range box for for each document, measure.extents for assembly). I am happy with the result, but not the best praxis 🙂

Also tnx for the MaxOfMany, MinofMany and List.Sort functions, method, didn't know them. 

 

I didn't try the external rule yet, will try after vacation!

0 Likes
Message 5 of 6

_dscholtes_
Advocate
Advocate

@miha_bokan wrote:

When I used FindOrient on assembly level document it didn't work.


That's because the rule only loops through the referenced documents in the assembly. The assembly itself is not processed.

0 Likes
Message 6 of 6

miha_bokan
Enthusiast
Enthusiast

@_dscholtes_ :
What I tried was FindOrient outside of foreach loop. But! The error was somewhere else not in FindOrient function (my old function also defined the sides of max range box). So confirmed, this code works everywhere !

0 Likes