MeasureTools.GetMinimumDistance problem

MeasureTools.GetMinimumDistance problem

gerrardhickson
Collaborator Collaborator
644 Views
6 Replies
Message 1 of 7

MeasureTools.GetMinimumDistance problem

gerrardhickson
Collaborator
Collaborator

Hi All,

 

I have a many flexible sub-assemblies in a large organic main structure. In order to avoid sizing and placing each sub-assy, I'm using flexibility to place them and constrain them. I'm then writing code to go over those sub-assemblies, measure the distance between two points, save a copy of the sub-assembly and update it to suit the measured dimension.

 

The problem is that I can't get MeasureTools.GetMinimumDistance to work. The user selects a sub-assembly occurrence, then the code identifies the geometry to measure, but I get an error on the MeasureTools.GetMinimumDistance line. I suspect I'm defining my geometry (Plane1 and Axis1) wrong because manually picking the geometry works fine.

 

I tried various combination of selecting the occurrence (oOcc) and the work geometry (Plane1 and Axis1) using .definition and .contextdefinition. I found that if I selected the occurrence AND work geometry with .contextdefinition then the GetMinimumDistance returned 0 distance. 

 

How do I access the work geometry of an occurrence, while maintaining their context in the main assembly?

 

Code is below:

 

 

 

Sub SaveFlexibleAssyAsCopy()

Dim oA As AssemblyDocument
Dim oOcc As ComponentOccurrence
Dim oSS As SelectSet

Set oA = ThisApplication.ActiveDocument
Set oOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select first outrigger occurrence.")

Dim oPlate As ComponentOccurrence
Set oPlate = oOcc.ContextDefinition.Occurrences(3)
Dim Plane1 As WorkPlane
Set Plane1 = oPlate.Definition.WorkPlanes(2)
'Set Plane1 = ThisApplication.CommandManager.Pick(kWorkPlaneFilter, "Select outrigger workplane.")

Dim oBeam As ComponentOccurrence
Set oBeam = oOcc.ContextDefinition.Occurrences(1)
Dim Axis1 As WorkAxis
Set Axis1 = oBeam.Definition.WorkAxes(3)
'Set Axis1 = ThisApplication.CommandManager.Pick(kWorkAxisFilter, "Select outrigger axis.")

' Display the distance between the points using the current document units.
Dim uom As UnitsOfMeasure
Set uom = ThisApplication.ActiveDocument.UnitsOfMeasure

Dim oDist As Double

oDist = uom * ThisApplication.MeasureTools.GetMinimumDistance(Plane1, Axis1)


End Sub

 

 

 

Thanks in advance.

0 Likes
Accepted solutions (1)
645 Views
6 Replies
Replies (6)
Message 2 of 7

Michael.Navara
Advisor
Advisor

You need to use proxies of native geometries, when you want to measure distance in context of an assembly. Here i modified code

 

 

Sub SaveFlexibleAssyAsCopy()
    
    Dim oA As AssemblyDocument
    Dim oOcc As ComponentOccurrence
    Dim oSS As SelectSet
    
    Set oA = ThisApplication.ActiveDocument
    Set oOcc = ThisApplication.CommandManager.pick(kAssemblyOccurrenceFilter, "Select first outrigger occurrence.")
    
    Dim oPlate As ComponentOccurrence
    Set oPlate = oOcc.ContextDefinition.Occurrences(3)
    Dim Plane1 As WorkPlane
    Set Plane1 = oPlate.Definition.WorkPlanes(2)
    'Set Plane1 = ThisApplication.CommandManager.Pick(kWorkPlaneFilter, "Select outrigger workplane.")
    
    Dim oBeam As ComponentOccurrence
    Set oBeam = oOcc.ContextDefinition.Occurrences(1)
    Dim Axis1 As WorkAxis
    Set Axis1 = oBeam.Definition.WorkAxes(3)
    'Set Axis1 = ThisApplication.CommandManager.Pick(kWorkAxisFilter, "Select outrigger axis.")
    
    ' Display the distance between the points using the current document units.
    Dim uom As UnitsOfMeasure
    Set uom = ThisApplication.ActiveDocument.UnitsOfMeasure
    
    Dim oDist As Double
    
    'oDist = uom * ThisApplication.MeasureTools.GetMinimumDistance(Plane1, Axis1)
    
    Dim plane1Proxy As WorkPlaneProxy
    Call oPlate.CreateGeometryProxy(Plane1, plane1Proxy)
    
    Dim axis1Proxy As WorkAxisProxy
    Call oBeam.CreateGeometryProxy(Axis1, axis1Proxy)
    
    oDist = ThisApplication.MeasureTools.GetMinimumDistance(plane1Proxy, axis1Proxy)
    
    Debug.Print oDist

End Sub

 

Also you CAN'T use uom in this way. You need to use uom to convert value to appropriate units but not only multiply value with uom.

 

Message 3 of 7

Cadkunde.nl
Collaborator
Collaborator

Hello,

 

I ran into this problem a few days ago.

You need to create a proxy of the axis to work in the top assembly before you can measure or constrain

 

oOcc.CreateGeometryProxy(oBeam.Definition.WorkAxes(3), Axis1)

You need to do the same for the workplane.

 

 

Message 4 of 7

gerrardhickson
Collaborator
Collaborator

Thanks for the advice - but I'm convinved that I'm also not declaring the Plane1 and Axis1 correctly.
I added in a highlightset so I could see which object I was selecting and with the following code, I end up selecting the main assembly XZ plane, instead of the XZ plane of the Plate part.

 

 

 

Dim oPlate As ComponentOccurrence
Dim Plane1 As WorkPlane
Set oPlate = oOcc.ContextDefinition.Occurrences(3)
Set Plane1 = oPlate.ContextDefinition.WorkPlanes(2)
'Set Plane1 = ThisApplication.CommandManager.Pick(kWorkPlaneFilter, "Select outrigger workplane.")
Call oHS.AddItem(Plane1)

 

 

Note that I'm using 'ContextDefinition' instead of 'Definition'. If I use 'Definition' then oHS.AddItem fails.

Similarly, the GetMinimumDistance method returns a very large number if I don't use 'ContextDefinition', and it returns 0 if I do.

 

 

0 Likes
Message 5 of 7

WCrihfield
Mentor
Mentor

Hi @gerrardhickson.  Interesting.  I had not messed around with ComponentOccurrence.ContextDefinition that much before, because I did not have much use for it.  It basically always refers to the main assembly's AssemblyComponentDefinition, which I already have a reference to.  So in your last code, 'oPlate' is being set to the third top level component in the main assembly.  Then your 'Plane1' is getting the second WorkPlane of the main assembly.  All because of that ContextDefinition use.  Then, since the WorkPlane you get using that route is already within the 'context' of the main assembly, your highlight thing works.  And when you get the real WorkPlane from the component, that WorkPlane is in the 'context' of that component, not the main assembly, therefore you can not add it directly to the highlight set of the main assembly.  Like the others have suggested, you need to get a reference to the 'copy' of that component's WorkPlane that is in the 'context' of the main assembly by using the oOcc.CreateGeometryProxy method.  You first create a WorkPlaneProxy type variable, set to Nothing as its value.  Then put the regular WorkPlane from the component into that method as the first input, then you put your WorkPlaneProxy type variable into that method as the second input.  Then that method sets the value of that WorkPlaneProxy variable to the instance/copy of that WorkPlane that is within the 3D model space of the 'parent' (one level up only) assembly.  Similarly, if you were to use the Pick method to manually select that component's WorkPlane, you would get its WorkPlaneProxy (the version of it that exists within the 3D space of the main assembly), not the native object in the context of that component.  If you were in Edit Mode of that component, then you would get the real one.

 

Edit:  Correction...The ContextDefinition returns the AssemblyComponentDefinition of the component's 'parent' assembly, not necessarily the 'top level' assembly.  I was testing on a part that was 3 levels down.  However, my first tests were was using 'Pick' method and 'kAssemblyLeafOccurrenceFilter', which will return a ComponentOccurrenceProxy of that component, instead of the actual ComponentOccurrence, which was throwing the results off.  In subsequent testing, I stepped down the proverbial component ladder to get the one I wanted to test on, which was a regular ComponentOccurrence.  In those tests, the ComponentOccurrence.ContextDefinition.Document.FullDocumentname returned the direct 'parent' assembly of the component.  Sorry for the confusion.  Still valid points above though.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 7

J-Camper
Advisor
Advisor

@gerrardhickson,

 

This is modified code based on @WCrihfield 's suggestion to edit-in-place the subassembly before selecting your the "outrigger occurrence":

Sub SaveFlexibleAssyAsCopy()
    
    Dim oA As AssemblyDocument
    Dim oOcc As ComponentOccurrence
    Dim oSS As SelectSet
	'New:
		Dim oSubAssemblyOcc As ComponentOccurrence
    
    Set oA = ThisApplication.ActiveDocument
    'New:
		Set	oSubAssemblyOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select a subassembly to access.")
		If oSubAssemblyOcc.DefinitionDocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Logger.Debug("Sub Assembly not selected.") : Exit Sub
		'Edit in place
		Call oSubAssemblyOcc.Edit()
	Set oOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select first outrigger occurrence.")

    Dim oPlate As ComponentOccurrence
    Set oPlate = oSubAssemblyOcc.Definition.Occurrences(3) 'Edited: oOcc.ContextDefinition.Occurrences(3)

    Dim Plane1 As WorkPlane
    Set Plane1 = oPlate.Definition.WorkPlanes(2)
    'Set Plane1 = ThisApplication.CommandManager.Pick(kWorkPlaneFilter, "Select outrigger workplane.")
    
    Dim oBeam As ComponentOccurrence
    Set oBeam = oSubAssemblyOcc.Definition.Occurrences(1) 'Edited: oOcc.ContextDefinition.Occurrences(1)
    Dim Axis1 As WorkAxis
    Set Axis1 = oBeam.Definition.WorkAxes(3)
    'Set Axis1 = ThisApplication.CommandManager.Pick(kWorkAxisFilter, "Select outrigger axis.")
    
    ' Display the distance between the points using the current document units.
    Dim uom As UnitsOfMeasure
    Set uom = oA.UnitsOfMeasure 'Edited: ThisApplication.ActiveDocument.UnitsOfMeasure
    
    Dim oDist As Double
    
    'oDist = uom * ThisApplication.MeasureTools.GetMinimumDistance(Plane1, Axis1)

    Dim plane1Proxy As WorkPlaneProxy
    Call oPlate.CreateGeometryProxy(Plane1, plane1Proxy)
    
    Dim axis1Proxy As WorkAxisProxy
    Call oBeam.CreateGeometryProxy(Axis1, axis1Proxy)
    
    oDist = ThisApplication.MeasureTools.GetMinimumDistance(plane1Proxy, axis1Proxy)
    
    Debug.Print oDist

	'New:
		'Exit edit back to previous assembly, which should be main
		Call oSubAssemblyOcc.ExitEdit(ExitTypeEnum.kExitToPrevious)
	
End Sub

 

I work in vb.Net, so I translated back to VBA after testing.  Let me know if something isn't working or if you have any questions

0 Likes
Message 7 of 7

gerrardhickson
Collaborator
Collaborator
Accepted solution

Thanks for the help guys, I appreciate the effort. @J-Camper 's code helped, but it didn't work as expected. The 'Call oSubAssemblyOcc.Edit()' line opened the component for explicit editing, not in context editing as expected. I'm not sure why.

But the oDist result was the distance between the plane and axis in the original subassembly document, not in the context of the assembly (keeping in mind it's a flexible assembly).

 

I realised that my definition for the oPlate and oBeam occurrence definitions was wrong - they pointed to the SubAssembly definition, whereas I should have used oOcc.SubOccurrences instead.

 

So the revised code looks something like this:

 

Sub SaveFlexibleAssyAsCopy()

Dim oA As AssemblyDocument
Dim oOcc As ComponentOccurrence
Dim oSS As SelectSet
Dim oHS As HighlightSet

Set oA = ThisApplication.ActiveDocument
Set oOcc = ThisApplication.CommandManager.Pick(kAssemblyOccurrenceFilter, "Select first outrigger occurrence.")
Set oHS = oA.CreateHighlightSet

Dim oPlate As ComponentOccurrence
Dim Plane1 As WorkPlane
Set oPlate = oOcc.SubOccurrences(3)
Set Plane1 = oPlate.Definition.WorkPlanes(2)

Dim oBeam As ComponentOccurrence
Dim Axis1 As WorkAxis
Set oBeam = oOcc.SubOccurrences(1)
Set Axis1 = oBeam.Definition.WorkAxes(3)

' Display the distance between the points using the current document units.
Dim uom As UnitsOfMeasure
Set uom = oA.UnitsOfMeasure

Dim oDist As Double

Dim plane1Proxy As WorkPlaneProxy
Call oPlate.CreateGeometryProxy(Plane1, plane1Proxy)

Dim axis1Proxy As WorkAxisProxy
Call oBeam.CreateGeometryProxy(Axis1, axis1Proxy)
Call oHS.AddItem(plane1Proxy)
Call oHS.AddItem(axis1Proxy)
oDist = ThisApplication.MeasureTools.GetMinimumDistance(plane1Proxy, axis1Proxy) * 10

debug.print oDist

End Sub
0 Likes