Is there any way to use the Place At Component Origin command using VBA or even iLogic? I looked around in the object explorer but couldn't really find anything that seemed to hit the nail on the head.
Is it even part of the current capabilities, and if not, do you (Autodesk) ever plan on implementing this function into the API?
Solved! Go to Solution.
do you mean placing a component at the origin of an assembly? then look at http://www.mcadforums.com/forums/viewtopic.php?f=1
Though that code will allow me to place an object into the assembly, the actual in Inventor function Place at Component Origin, also automatically grounds the part to a selected origin (acting as a full constraint). PaCO is important as we slice up our parts here based on what we can physically cut.
I will continue to work with this script and see if anything pans out. If I could get it to just ‘stick’ to the parent part then it would essentially be the same as PaCO, but as of now it looks like I would just have to use constraints turning it into an odd variant of iMates.
Thank you for your reply!
I feel now that I had a misconception about how PaCO was behaving. It does make constraints (that show up as features), and for some reason I was failing to pay attention to that glaring fact!
Because of this, I might be able to implement the code from the link above, to behave in a very similar fashion.
Now I just have to figure out how to get those constraints to automatically happen, and actually work correctly.
Thank you for putting me down the correct path!
Well I managed to find my answer in a more obvious place.
Mod The Machine Blog had the lowdown on a nice little macro that essentially allows you to do what Place at Component Origin does, but only on a lot more parts!
The specific code below is the code that works like PaCO.
Public Sub AlignOccurrencesWithConstraints() Dim assemblydoc As AssemblyDocument Set assemblydoc = ThisApplication.ActiveDocument ' Get the occurrences in the select set. Dim occurrenceList As New Collection Dim entity As Object For Each entity In assemblydoc.SelectSet If TypeOf entity Is ComponentOccurrence Then occurrenceList.Add entity End If Next If occurrenceList.Count < 2 Then MsgBox "At least two occurrences must be selected." Exit Sub End If ' This assumes the first selected occurrence is the "base" ' and will constrain the base workplanes of all the other parts ' to the base workplanes of the first part. If there are ' constraints on the other they end up being over constrained. ' Get the planes from the base part and create proxies for them. Dim baseOccurrence As ComponentOccurrence Set baseOccurrence = occurrenceList.Item(1) Dim BaseXY As WorkPlane Dim BaseYZ As WorkPlane Dim BaseXZ As WorkPlane Call GetPlanes(baseOccurrence, BaseXY, BaseYZ, BaseXZ) Dim constraints As AssemblyConstraints Set constraints = assemblydoc.ComponentDefinition.constraints ' Iterate through the other occurrences Dim i As Integer For i = 2 To occurrenceList.Count Dim thisOcc As ComponentOccurrence Set thisOcc = occurrenceList.Item(i) ' Move it to the base occurrence so that if the base is ' not fully constrained it shouldn't move when the flush ' constraints are added. thisOcc.Transformation = baseOccurrence.Transformation ' Get the planes from the occurrence Dim occPlaneXY As WorkPlane Dim occPlaneYZ As WorkPlane Dim occPlaneXZ As WorkPlane Call GetPlanes(thisOcc, occPlaneXY, occPlaneYZ, occPlaneXZ) ' Add the flush constraints. Call constraints.AddFlushConstraint(BaseXY, occPlaneXY, 0) Call constraints.AddFlushConstraint(BaseYZ, occPlaneYZ, 0) Call constraints.AddFlushConstraint(BaseXZ, occPlaneXZ, 0) Next End Sub ' Utility function used by the AlignOccurrencesWithConstraints macro. ' Given an occurrence it returns the base work planes that are in ' the part or assembly the occurrence references. It gets the ' proxies for the planes since it needs the work planes in the ' context of the assembly and not in the part or assembly document ' where they actually exist. Private Sub GetPlanes(ByVal Occurrence As ComponentOccurrence, _ ByRef BaseXY As WorkPlane, _ ByRef BaseYZ As WorkPlane, _ ByRef BaseXZ As WorkPlane) ' Get the work planes from the definition of the occurrence. ' These will be in the context of the part or subassembly, not ' the top-level assembly, which is what we need to return. Set BaseXY = Occurrence.Definition.WorkPlanes.Item(3) Set BaseYZ = Occurrence.Definition.WorkPlanes.Item(1) Set BaseXZ = Occurrence.Definition.WorkPlanes.Item(2) ' Create proxies for these planes. This will act as the work ' plane in the context of the top-level assembly. Call Occurrence.CreateGeometryProxy(BaseXY, BaseXY) Call Occurrence.CreateGeometryProxy(BaseYZ, BaseYZ) Call Occurrence.CreateGeometryProxy(BaseXZ, BaseXZ) End Sub
Would anyone please be able explain how to rewrite this in ilogic? (if it's possible)
I am hoping to write a configurator that will constrain our product together, then move compents around accordingly. I feel muh more comfortable in the ilogic environemtn at present
At one point or another, I remade this code in iLogic to work with some automation stuffs that I wanted to test. I would create parts, place them into the assembly, and then constrain them using a few of the above methods. However I'm not 100% sure where that darn code ran off to
I don't mind looking into doing some re-writing, but I would first like to know how you plan on approaching this. If you have used the above VBA code, then you know that you need to select a master part first (as your item to constrain to) and any number of other parts (1-infinity) that get constrained to it. Did you want to keep this behavior, or were you looking to do what I was doing which is, cannibalize the above to get the basics of what’s happening but on different terms?
Well I was hoping to gain a better understanding of your code, then use it to do something a bit more advance.
Our product always contains a frame, we have three different height configurations. Some components I have modelled offset from origins so that they will be in the correct position as soon as they are contrained to the origin of the frame or the origin of the top-level-assembly. Some components move up and down depending on the height configuration, so I have created a plane within each frame variation that these parts can be constrained to to define their vertical position. Some parts/subassemblies haven't been modelled with position in mind so will need to be offset the the origin or constrained to other parts.
We have a gigantic amount of possible configuratins of our product and we have modelled everything up in iparts/iassemblies so that things can be easily swapped. I think the easiest way to create an assembly that can assemble itself is by creating a template assembly which will be controlled by a user form. There will always be special customer orders so I want to put this to one side for now as concentrate on automating constraints on an assembly that has been created from scratch. I have had a play around with iMates but I am not a fan of them.
A code what can contraint components to the origin of the frame or the origin of the top-level assembly would be a good start. Then I can look at constraining to YZ, XY and my plane which varies depending on height configuration.
To take things a step further, the program could examine a part, read what family of parts it belongs to (this could be done by looking at it's file location). The program could then use this information to make a decision as to how the component could be constrained.
So basically in the long run, I want a program that will assembly our product at the click of a button! But I want to take it one step at a time and improve my programming skills along the way. Any suggestions?
Well I did manage to find the code, but it is janky at best. It looks like I would pass in a base part occurrence name, and a child member that I wanted to constrain to it. I started hacking this together a long long time ago, and would probably go about it differently now. I just wanted to at least get something up on the board so that stuff could start moving again.
I don't know if you can use this, change it, or get a better idea of the direction to take some iLogic code, but if I am able to get the time, I'll look into re-writing it into something more appropriate. I have been wanting to do that any ways, as the code currently will not allow you to constrain parts that are inside of a sub-assembly (to another part that is in the same sub-assembly) if you are on the main level of your main assembly, and haven't opened the sub-assembly into its own environment.
My strange sub is as follows... :
Sub ConstrainNewParts (CurrentOccurrence As String, ParentOccurrence As String, PathToFile As String) Dim assemblyDoc As AssemblyDocument assemblyDoc = ThisApplication.ActiveDocument Dim occurrenceList As New Collection Dim compOcc As ComponentOccurrence compOcc = assemblyDoc.ComponentDefinition.Occurrences.ItemBy
Name(ParentOccurrence) occurrenceList.Add (compOcc) compOcc = assemblyDoc.ComponentDefinition.Occurrences.ItemBy Name(CurrentOccurrence) occurrenceList.Add (compOcc) If occurrenceList.Count < 2 Then MessageBox.Show( "At least two occurrences must be selected.", "Error") Exit Sub End If Dim baseOccurrence As ComponentOccurrence baseOccurrence = occurrenceList.Item(1) Dim BaseXY As WorkPlane Dim BaseYZ As WorkPlane Dim BaseXZ As WorkPlane Call GetPlanes(baseOccurrence, BaseXY, BaseYZ, BaseXZ) Dim constraints As AssemblyConstraints constraints = assemblyDoc.ComponentDefinition.constraints Dim i As Integer For i = 2 To occurrenceList.Count Dim thisOcc As ComponentOccurrence thisOcc = occurrenceList.Item(i) thisOcc.Transformation = baseOccurrence.Transformation Dim occPlaneXY As WorkPlane Dim occPlaneYZ As WorkPlane Dim occPlaneXZ As WorkPlane Call GetPlanes(thisOcc, occPlaneXY, occPlaneYZ, occPlaneXZ) Call constraints.AddFlushConstraint(BaseXY, occPlaneXY, 0) Call constraints.AddFlushConstraint(BaseYZ, occPlaneYZ, 0) Call constraints.AddFlushConstraint(BaseXZ, occPlaneXZ, 0) Next End Sub Private Sub GetPlanes(ByVal Occurrence As ComponentOccurrence, _ ByRef BaseXY As WorkPlane, _ ByRef BaseYZ As WorkPlane, _ ByRef BaseXZ As WorkPlane) BaseXY = Occurrence.Definition.WorkPlanes.Item(3) BaseYZ = Occurrence.Definition.WorkPlanes.Item(1) BaseXZ = Occurrence.Definition.WorkPlanes.Item(2) Call Occurrence.CreateGeometryProxy(BaseXY, BaseXY) Call Occurrence.CreateGeometryProxy(BaseYZ, BaseYZ) Call Occurrence.CreateGeometryProxy(BaseXZ, BaseXZ) End Sub
Thanks, the code doesn't run at present on my machine but I will have a play around with it.
After a bit more experimenting I think using imates may be the most effective method for my problem. I didn't think they were much use at first as I was having problems with getting them to function properly. Now I have an ilogic code that reads a list of componens from a spreadsheet, places them all into an assembly. The imates constrain everything to the frame. As all our models are imates/iassemblies, creating iMates is a relatively quick process.