I recently received a question that I thought there might be some general interest in the answer. Here’s the problem. I have the assembly shown below. It’s free to move in the ways you would expect; it can pivot about the base and the arm can extend. Everything is fine so far.
Next I insert the arm assembly shown above into a new assembly. Then I insert the yellow block part into the assembly and constrain it to the tip of the arm, as shown below.
First, the arm assembly is rigid if I try to move any of its parts. That’s the behavior I would expect because, by default, subassemblies are rigid within an assembly. However, you can set the subassembly occurrence to be “flexible” so that it will behave the same as it does when the subassembly is active. That is, the arms can be dragged and the positions of all of the connected parts will update. I can also drag the yellow block and that will cause the arms to reposition to follow the block.
The question posed was how to move the block using the API and still get the arms to follow. The expectation, which I shared, is that setting the transformation for the yellow block to reposition it should automatically reposition everything else that’s connected to it. This is probably how it should behave but it’s not. When setting the position of the yellow block nothing happens. The yellow block doesn’t move and the arm subassembly doesn’t move.
I played around with a couple of ideas and one of them does work. It’s simple to implement so should be an acceptable workaround. It temporarily grounds the part that’s being moved. The API to move a part will move a grounded part and when the assembly computes, the grounded part has a higher priority in the solver than the flexible assembly so the flexible assembly adjusts to the change.
Here’s the code I used to test this.
Public Sub MovePart()
' Have the occurrence that will be moved selected.
Dim occ As ComponentOccurrence
Set occ = ThisApplication.CommandManager.Pick( _
"Select an occurrence.")
' Get the current grounded state of the selected occurrence.
Dim groundState As Boolean
groundState = occ.Grounded
' Ground the occurrence.
occ.Grounded = True
' Change the position of the occurrence. This repositions it
' in a series of steps to create a short animation. It moves
' it 0.5 cm in the Y direction for each step.
Dim i As Integer
For i = 1 To 10
Dim trans As Matrix
Set trans = occ.Transformation
trans.Cell(2, 4) = trans.Cell(2, 4) + .5
occ.Transformation = trans
' Reset the grounded state of the occurrence back to
' its original state.
occ.Grounded = groundState