So I found a while ago, on this forum, how to get the center of gravity values from iproperties and assign them to user parameters using iLogic:
"
cgx = iproperties.centerofgravity.x
cgy = iproperties.centerofgravity.y
cgz = iproperties.centerofgravity.z
ilogicvb.updatewhendone = true
"
I would like to have a work point follow my cg values in the model. The only way I can think that could do this is to by offsetting 3 work planes using the user parameters as offsets. This is so because the values retuned are sometimes negative. Therefore, I don't think (I'm about 99% certain) that I could not do this through sketches but I don't like to crowd my models with unneccessary user work planes. And even if I could do this with sketches, I don't know that I would want a bunch of sketches either.
So what I'm looking for is the cleanest way that I can create a work point in 3D space with the ability to travel in a negative direction given the x,y,z coordinates.
Any ideas guys?
EDIT: I'm considering this for both parts and assemblies, so if a 3d sketch would work for a part file, it can't be used for an assembly.
Thanks a ton.
Solved! Go to Solution.
Solved by cwhetten. Go to Solution.
Solved by cwhetten. Go to Solution.
Hi Will,
If you're using iLogic anyway, our approach might work for you. We use a rule that checks to see if a workpoint exists already (it checks by the name of the feature, which we have called "Shipping Center Of Gravity", defined on line 27 of the rule). If it exists, it updates its location to the CoG coordinates.
If the workpoint does not yet exist, it creates it. It is a fixed workpoint that doesn't rely on other work features for its location. It's location is solely controlled by the iLogic rule. Spoilered below is the rule:
Cameron Whetten
Inventor 2014
First off, thank you so much. That looks like a huge step in the right direction. I really wish I understoon iLogic/Inventor VBA better so that I could generate these things on my own. I do have a few questions pertaining to your rule though.
So this rule would be created as an external rule and run by the user when desired. What I would really like to do with this is pre-write it into our part and assembly templates. And what I'd really like for it to do is update as new parts are placed and moved/re-constrained rather than the options in the event triggers. For part files, the "Any Model Parameter Change" Event Trigger would probably suffice. The idea is to create as little interaction with iLogic as possible for the end user. Currently, I am the most familiar with iLogic at my place of work by a long shot. I mean... if my coworkers know the term "iLogic", they're in good shape. With that in mind, I want this to be as hands free as possible.
So, if I'm cleared to have a work point pre-existing in our templates named (in all likelihood) "Center of Gravity", then I will simply have it pre-existing for any new part or assemblies created moving forward. However, if that's not possible, then I would probably want to make a button for the ribbon that would create the work point. There's also the issue with user settings and making sure that my co-workers also have access to said button. I'm not certain if I'd have any complications with that cause I haven't tried it out yet.
Thanks again.
By the way, as far as I'm concerned, your solution does everything I need it to lol. I'm just trying to make it end user friendly.
Cameron,
Through trying out the external rule you provided, I've found that when it is placed in a part file, the point is placed and grounded, however when it is placed in an assembly, the point is placed and left capable of moving.
I'm looking through your code but I'm not familiar with how to make the same thing happen for an assembly.
Any thoughts?
Nevermind Cam,
I just added "oWorkPoint.Grounded = True" to the tail end of both the portion of the code that updates the workpoint as well as the portion that creates.
Hi Will, I am glad to help.
You say the point is left capable of moving. In my experience, it hasn't been a problem, but have you seen it move unexpectedly? I'm not sure how that would happen, but if it does, I would like to know how so I can prevent it from happening in my models.
As for getting the code to automatically run in an assembly when placing & constraining components, that's not so easy. We trigger it from our configuration rules, so it works for us. It is possible in Visual Basic to write code that watches for specific events and then runs other code accordingly, but I don't have the skills to do this.
You could set up a command button on the ribbon in a couple of ways. Firstly, you could place the code as a macro in Inventor's VBA project file (default.ivb). This would be instead of an external rule. It is possible to add VBA macros as buttons on the ribbon (through Tools > Customize > Ribbon tab). The code would need to be slightly rewritten, as there are a few syntax differences between VBA and iLogic (which is based on VB.NET).
Secondly, you could use Visual Basic Express (a free version of the VB.NET programming environment) to create a plugin version of this code. It is possible with plugins to add custom command buttons to the ribbon anywhere you like, and you can make a custom icon for your command button. This way, it integrates nicely and looks like it was always meant to be there. This method entails quite a bit more work, but when done properly it looks really nice and is easy to deploy to many workstations.
Cameron Whetten
Inventor 2014
Cam,
So after some more use, I'm finding that the macro I used to run the external rule is causing inventor to crash upon execution. I'm not too sure what is causing the problem. Originally I copied the macro from an old post in the Inventor Customization Forum. The code is as below:
Public Sub CenterofGravity() RuniLogic "CenterOfGravity" End Sub Public Sub RuniLogic(ByVal RuleName As String) Dim iLogicAuto As Object Dim oDoc As Document Set oDoc = ThisApplication.ActiveDocument If oDoc Is Nothing Then MsgBox "Missing Inventor Document" Exit Sub End If Set iLogicAuto = GetiLogicAddin(ThisApplication) If (iLogicAuto Is Nothing) Then Exit Sub iLogicAuto.RunExternalRule oDoc, RuleName End Sub Function GetiLogicAddin(oApplication As Inventor.Application) As Object Set addIns = oApplication.ApplicationAddIns 'Find the add-in you are looking for Dim addIn As ApplicationAddIn On Error GoTo NotFound Set addIn = oApplication.ApplicationAddIns.ItemById("{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}") If (addIn Is Nothing) Then Exit Function addIn.Activate Set GetiLogicAddin = addIn.Automation Exit Function NotFound: End Function
I'm primarily confused because it worked initially, and with no apparent changes, is now crashing inventor.
You mentioned that the code would need to be altered in order to make the macro handle everything without the external rule, not to ask too much of you, but how would that work? The external rule, as I currently have it, looks like this:
Option Explicit On ' Check to make sure a part or assembly document is active. Dim doc as Document = ThisDoc.Document If doc.DocumentType <> DocumentTypeEnum.kPartDocumentObject AndAlso doc.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then MessageBox.Show(" This rule can only be run in a part or assembly.", "WorkPoint At Mass Center") Exit Sub End If Dim massProps As MassProperties Dim workPoints As WorkPoints If (doc.DocumentType = DocumentTypeEnum.kPartDocumentObject) Then Dim partDoc as PartDocument = doc massProps = partDoc.ComponentDefinition.MassProperties workPoints = partDoc.ComponentDefinition.WorkPoints Else Dim assemDoc as AssemblyDocument = doc massProps = assemDoc.ComponentDefinition.MassProperties workPoints = assemDoc.ComponentDefinition.WorkPoints End If ' Get the Center of Mass. Dim oCenterOfMass As Point = massProps.CenterOfMass ' Check to see if a work point for center of mass already exists. ' This uses the name of the work feature to identify it. Const workPointName As String = "Center Of Gravity" Dim oWorkPoint As WorkPoint Try oWorkPoint = workPoints.Item(workPointName) Catch oWorkPoint = Nothing End Try If (oWorkPoint IsNot Nothing) Then If (doc.DocumentType = DocumentTypeEnum.kPartDocumentObject) Then Dim oFixedDef As FixedWorkPointDef = oWorkPoint.Definition oFixedDef.Point = oCenterOfMass Else Dim oFixedDef As AssemblyWorkPointDef = oWorkPoint.Definition oFixedDef.Point = oCenterOfMass End If doc.Update oWorkPoint.Grounded = True Else ' Create a new workpoint at the location of the center of mass. oWorkPoint = workPoints.AddFixed(oCenterOfMass) ' Rename the work point. oWorkPoint.Name = workPointName oWorkPoint.Grounded = True End If
Hi Will.
The VBA version is spoilered below (also attached as a TXT file).
The differences between the VBA and iLogic versions are mostly in the use of Set and Let statements. Also, the Try-catch statement that I was using to test if the workpoint already exists had to be removed. Try-catch statements are a VB.NET thing and don't work in VBA. So I replaced it with a for each loop to test if any existing workpoints had the same name. There were a few other syntactic changes, but you can compare the two versions to find them all (fun game and free to play!).
As for the crashing, I don't know why it would start doing that. But, if you use the VBA version of the rule, you won't need the crashy macro that runs the iLogic rule anymore.
Cameron Whetten
Inventor 2014
Cameron,
I'm getting an error on line 4 when I try to run the macro.
Whatcha think?
Thanks again for all of your help,
Did you add the macro to your default.ivb? I forgot that I suggested to do that.
Try replacing the line that says
Set doc = ThisDocument
with this:
Set doc = ThisApplication.ActiveDocument
lol so I did.
That seems to have done the trick. No lie - I thought about that. I've seen that line of text a few times before but, again, I don't know enough about it to know that ThisApplication.ActiveDocument was actually what I needed.
Thanks again Cameron.
ThisDocument accesses the document object that contains the VBA code. In the file I was using to test the code, I had just added it to an assembly VBA project, so it would get the assembly document and it worked just fine.
However, when the code is contained in the application project (default.ivb), then ThisDocument returns nothing (the code isn't contained in a document so there is no document to return). That's why we have to get the document another way. The easiest way to do that is with ThisApplication.ActiveDocument.
However, I have learned that ThisApplication.ActiveDocument is not always the best way. Sometimes you want to run a routine on another document besides the active one, so using ThisApplication.ActiveDocument will return the wrong document object. Hopefully that made some sense...
Cameron Whetten
Inventor 2014
Can't find what you're looking for? Ask the community or share your knowledge.