Part Smarter, not harder.
One way to simplify the process of using parts in inventor is to make a master part file that's driven by parameters and then create a rule in ilogic to save all of your info for each configured variant of that part into the .ipt file, swapping them out when the params change.
I've been doing this with Json into a custom AttributeSet, and it seems to work pretty awesome.
I've got these .ipt's I call smartparts, and what I do is I make a class that holds a bunch of data to drive the parameters of the model file. i just serialize and deserialize from there.
So, for instance, for a pipe you could write this in a rule:
Sub main
Dim PipeList As List(Of Pipe) = New List(Of Pipe)
Dim SchList As List(Of ScheduleTableValues) = New List(Of ScheduleTableValues)
Dim JSeri As JavaScriptSerializer = New JavaScriptSerializer
AttName = "JSON"
Dim ThisPartDocument As PartDocument = ThisApplication.Documents.ItemByName(ThisDoc.Document.FullDocumentName)
Dim Attset As AttributeSet
Try'[
SchList = initScheduleList(SchList)
Catch
Logger.Error("{0} couldn't be made for some reason.. ", "SchList")
End Try']
Try'[
Logger.Info("creating the PipeList")
initializePipes(PipeList, SchList)
Logger.Info("The number of objects in the PipeList after creating it is: {0}.", PipeList.Count)
Catch Ex As Exception
Logger.Info("The number of objects in the PipeList after creating it is: {0}.", PipeList.Count)
' Logger.Info("something went wrong, the Code is in it's Cach block after trying to Populate the Teelist {0}.", TeeList.Count)
Logger.Info("Error {0}::{1}.", Ex.Message, Ex.HResult)
End Try']
SerializeToJSON(PipeList, AttName)
End Sub
<Serializable() >
Class Pipe
Public _nps As String = ""
Public _ptype As String = "PIPE"
Public _mat As String = ""
Public _sch As String = ""
Public _pol As String = "MILL"
Public _lcOrPed As String = ""
Public _ptNum As String = ""
Public _thickness As Double
Public _schTableValue As ScheduleTableValues
Public Sub New
End Sub
Public Sub New(Nps As String, Mat As String, Sch As String, Pol As String, LcOrPed As String, PtNum As String, Schlist As List(Of ScheduleTableValues))
Me._nps = Nps
Me._mat = Mat
Me._sch = Sch
Me._pol = Pol
Me._lcOrPed = LcOrPed
Me._ptNum = PtNum
Me._schTableValue = (From Entry In Schlist Where entry._nominalPipeSize = CDblAny(Me._nps)).FirstOrDefault
Select Case Me._sch
Case "SCH05"
Me._thickness = Me._schTableValue._sch05
Case "SCH10"
Me._thickness = Me._schTableValue._sch10
Case "SCH20"
Me._thickness = Me._schTableValue._sch20
Case "SCH40"
Me._thickness = Me._schTableValue._sch40
Case "SCH80"
Me._thickness = Me._schTableValue._sch80
Case "SCH160"
Me._thickness = Me._schTableValue._sch160
End Select
End Sub
End Class
<Serializable()>
Class ScheduleTableValues
Public _nominalPipeSize As Double
Public _od As Double
Public _sch05 As Double
Public _sch10 As Double
Public _sch20 As Double
Public _sch30 As Double
Public _sch40 As Double
Public _sch80 As Double
Public _sch120 As Double
Public _sch160 As Double
Public Sub New(NominalPipeSize As Double, Od As Double, SCH05 As Double, SCH10 As Double, SCH20 As Double, SCH30 As Double, SCH40 As Double, SCH80 As Double, SCH120 As Double, SCH160 As Double)
Me._nominalPipeSize = NominalPipeSize
Me._od = Od
Me._sch05 = SCH05
Me._sch10 = SCH10
Me._sch20 = SCH20
Me._sch30 = SCH30
Me._sch40 = SCH40
Me._sch80 = SCH80
Me._sch120 = SCH120
Me._sch160 = SCH160
End Sub
Public Overrides Function ToString() As String
Return String.Format("[NPS:{0}, OD:{1}]", Me._nominalPipeSize, Me._od)
End Function
Public Sub New
End Sub
End Class
Function initScheduleList(ByRef SchList As List(Of ScheduleTableValues))
SchList.Add(New ScheduleTableValues(0.125, 0.405, 0.035, 0.049, 0.049, 0.057, 0.068, 0.095, 0, 0))
SchList.Add(New ScheduleTableValues(0.25, 0.54, 0.049, 0.065, 0.065, 0.073, 0.088, 0.119, 0, 0))
SchList.Add(New ScheduleTableValues(0.375, 0.675, 0.049, 0.065, 0.065, 0.073, 0.091, 0.126, 0, 0))
SchList.Add(New ScheduleTableValues(0.5, 0.84, 0.065, 0.083, 0.083, 0.095, 0.109, 0.147, 0, 0.188))
SchList.Add(New ScheduleTableValues(0.75, 1.05, 0.065, 0.083, 0.083, 0.095, 0.113, 0.154, 0, 0.219))
SchList.Add(New ScheduleTableValues(1, 1.315, 0.065, 0.109, 0.109, 0.114, 0.133, 0.179, 0, 0.25))
SchList.Add(New ScheduleTableValues(1.25, 1.66, 0.065, 0.109, 0.109, 0.117, 0.14, 0.191, 0, 0.25))
SchList.Add(New ScheduleTableValues(1.5, 1.9, 0.065, 0.109, 0.109, 0.125, 0.145, 0.2, 0, 0.281))
SchList.Add(New ScheduleTableValues(2, 2.375, 0.065, 0.109, 0.109, 0.125, 0.154, 0.218, 0.25, 0.344))
SchList.Add(New ScheduleTableValues(2.5, 2.875, 0.083, 0.12, 0.12, 0.188, 0.203, 0.276, 0.3, 0.375))
SchList.Add(New ScheduleTableValues(3, 3.5, 0.083, 0.12, 0.12, 0.188, 0.216, 0.3, 0.35, 0.438))
SchList.Add(New ScheduleTableValues(3.5, 4, 0.083, 0.12, 0.12, 0.188, 0.226, 0.318, 0, 0))
SchList.Add(New ScheduleTableValues(4, 4.5, 0.083, 0.12, 0, 0.188, 0.237, 0.337, 0.437, 0.531))
SchList.Add(New ScheduleTableValues(4.5, 5, 0, 0, 0, 0, 0.247, 0.355, 0, 0))
SchList.Add(New ScheduleTableValues(5, 5.563, 0.109, 0.134, 0, 0, 0.258, 0.375, 0.5, 0.625))
SchList.Add(New ScheduleTableValues(6, 6.625, 0.109, 0.134, 0, 0, 0.28, 0.432, 0.562, 0.719))
SchList.Add(New ScheduleTableValues(7, 7.625, 0, 0, 0, 0, 0.301, 0.5, 0, 0))
SchList.Add(New ScheduleTableValues(8, 8.625, 0.109, 0.148, 0, 0.277, 0.322, 0.5, 0.719, 0.906))
SchList.Add(New ScheduleTableValues(9, 9.625, 0, 0, 0, 0, 0.342, 0.5, 0, 0))
SchList.Add(New ScheduleTableValues(10, 10.75, 0.134, 0.165, 0.25, 0.307, 0.365, 0, 0, 0))
SchList.Add(New ScheduleTableValues(12, 12.75, 0.156, 0.18, 0.25, 0.33, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(14, 14, 0.156, 0.25, 0.312, 0.375, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(16, 16, 0.165, 0.25, 0.312, 0.375, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(18, 18, 0.165, 0.25, 0.312, 0.437, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(20, 20, 0.188, 0.25, 0.375, 0.5, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(22, 22, 0.188, 0.25, 0.375, 0.5, 0.375, 0, 0, 0))
SchList.Add(New ScheduleTableValues(24, 24, 0.218, 0.25, 0.375, 0.562, 0.375, 0, 0, 0))
Return SchList
End Function
''' <summary>
''' This Serializes a variable passed in of basically anything that is serializable, then deposits it into
''' this part's attributes under the set called JSONSet, with the Attribute named by the passed in AttName
'''
''' provides minimal error checking to make sure the set exists and the AttName exists, and it creates them if not.
'''
''' this Depends upon "Imports System.Web.Script.Serialization" and "AddReference "System.Web.Extensions"" being in the header for JavaSciptSerializer
''' </summary>
''' <param name="X"></param>
''' <param name="AttName"></param>
Friend Sub SerializeToJSON(ByRef X, AttName)
Dim JSeri As New JavaScriptSerializer
Dim AttSet As AttributeSet
Dim SerialString = JSeri.Serialize(X)
Dim ThisPartDocument As PartDocument = ThisApplication.Documents.ItemByName(ThisDoc.Document.FullDocumentName)
Try
If ThisPartDocument.AttributeSets.NameIsUsed("JSONSet") Then
AttSet = ThisDoc.Document.AttributeSets.Item("JSONSet")
Else
AttSet = ThisDoc.Document.AttributeSets.Add("JSONSet")
End If
'EXTREMELY important to add Inventor to Atribute, otherwise it's thinking its a general system object attribute that we don't want.
Dim JSONATT As Inventor.Attribute
If AttSet.NameIsUsed(AttName) Then
JSONATT = AttSet.Item(AttName)
Else
JSONATT = AttSet.Add(AttName, ValueTypeEnum.kStringType, "ThisIsAPlaceHolder")
End If
JSONATT.Value = SerialString
Catch
End Try
End Sub
Sub initializePipes(ByRef PipeList As List(Of Pipe), ByRef SchList As List(Of ScheduleTableValues))
PipeList.Add(New Pipe("0.25", "304LSS", "SCH40", "MILL", "", "PipePartNumberFromErpSoftware", SchList))
'add all of your part information here.
End Sub
after this I have another rule that is aware of the properties changing, and as they do, load in the deserialized info that best fits from the json
Sub Main
Dim PipeList As List(Of Pipe) = New List(Of Pipe)
Dim PipesToUse As List(Of Pipe) = New List(Of Pipe)
PipeList = DeserializeJSON(PipeList)
Logger.Info(String.Format(" {0} Has {1} Objects after the Deserialization", "PipeList", PipeList.Count))
Dim NormalPipeList As List(Of Pipe) = (From This As Pipe In PipeList Where This._lcOrPed = "" Select this).ToList
Logger.Info(String.Format(" {0} Has {1} Objects after the Deserialization", "NormalPipeList", NormalPipeList.Count))
Dim LCPipeList As List(Of Pipe) = (From This As Pipe In PipeList Where This._lcOrPed = "LC" Select this).ToList
Logger.Info(String.Format(" {0} Has {1} Objects after the Deserialization", "LCPipeList", LCPipeList.Count))
Dim PEDPipeList As List(Of Pipe) = (From This As Pipe In PipeList Where This._lcOrPed = "PED" Select this).ToList
Logger.Info(String.Format(" {0} Has {1} Objects after the Deserialization", "PEDPipeList", PEDPipeList.Count))
If LotControl
pipesToUse = LCPipeList
End If
If PEDMaterial
PipesToUse = PEDPipeList
End If
If Not LotControl And Not PEDMaterial Then
PipesToUse = NormalPipeList
End If
SetLists(PipesToUse)
End Sub
Sub SetLists(ByRef PipesToUse As List(Of Pipe))
MultiValue.SetValueOptions(True)
MultiValue.UpdateAfterChange = True
Parameter.UpdateAfterChange = True
Dim NpsList = (From This As Pipe In PipesToUse Where This._ptype = "PIPE" Select this._nps Distinct ).ToList
MultiValue.List("NominalDia") = NpsList.ToArray
Select Case NominalDia
Case Else
Logger.Info(String.Format(" {0} Has {1} choices", "NominalDia", NpsList.Count))
RuleParametersOutput()
InventorVb.DocumentUpdate()
End Select
Dim MatList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") Select This._mat Distinct ).ToList
MultiValue.List("MaterialChoice") = MatList.ToArray
Select Case MaterialChoice
Case Else
Logger.Info(String.Format(" {0} Has {1} choices", "MaterialChoice", MatList.Count))
RuleParametersOutput()
InventorVb.DocumentUpdate
End Select
Try
Dim SchChoiceList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") And This._mat = Parameter("MaterialChoice") And This._pol = Parameter("PolishChoice")Select This._sch Distinct ).ToList
MultiValue.List("Schedule") = SchChoiceList.ToArray
Logger.Info(String.Format(" {0} Has {1} choices", "SchChoiceList", SchChoiceList.Count))
Catch
Dim SchChoiceList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") Select This._sch Distinct ).ToList
Logger.Info(String.Format(" {0} Has {1} choices", "SchChoiceList", SchChoiceList.Count))
MultiValue.List("Schedule") = SchChoiceList.ToArray
End Try
Select Case Schedule
Case Else
RuleParametersOutput()
InventorVb.DocumentUpdate
End Select
Dim PolishList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") Select This._pol Distinct ).ToList
MultiValue.List("PolishChoice") = PolishList.ToArray
Select Case PolishChoice
Case Else
Logger.Info(String.Format(" {0} Has {1} choices", "PolishList", PolishList.Count))
RuleParametersOutput()
InventorVb.DocumentUpdate
End Select
Try
Dim PartNumList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") And This._mat = Parameter("MaterialChoice") And This._pol = Parameter("PolishChoice") And This._sch = Parameter("Schedule") Select This._ptNum ).ToList
MultiValue.List("PartNumber") = PartNumList.ToArray
Logger.Info(String.Format(" {0} Has {1} choices", "PartNumList", PartNumList.Count))
Catch
Dim PartNumList As List(Of String) = (From This As Pipe In PipesToUse Where This._nps = Parameter("NominalDia") And This._mat = Parameter("MaterialChoice") And This._sch = Parameter("Schedule") Select This._ptNum ).ToList
MultiValue.List("PartNumber") = PartNumList.ToArray
Logger.Info(String.Format(" {0} Has {1} choices", "PartNumList", PartNumList.Count))
End Try
Select Case PartNumber
Case Else
RuleParametersOutput()
InventorVb.DocumentUpdate
End Select
Dim DescriptionString As String = String.Format("{0} {1} {2} {3} {4}", "PIPE", Parameter("NominalDia"), Parameter("MaterialChoice"), Parameter("Schedule"), Parameter("PolishChoice"))
Description = DescriptionString
Try
Thickness = (From This As Pipe In PipesToUse Where This._ptNum = Parameter("PartNumber") Select This._thickness ).FirstOrDefault
Catch
End Try
Try
OD = (From This As Pipe In PipesToUse Where This._ptNum = Parameter("PartNumber") Select This._schTableValue._od ).FirstOrDefault
Catch
End Try
End Sub
Function DeserializeJSON(ByRef PipeList As List(Of Pipe))
Dim Doc As PartDocument = ThisDoc.Document
Dim JSeri As JavaScriptSerializer = New JavaScriptSerializer
Dim AttName As String = "JSON"
Dim Attset As AttributeSet = Doc.AttributeSets.Item("JSONSet")
'EXTREMELY Important, add Inventor to the Attribute here, so it knows its not a general system attribute.
Dim JSONATT As Inventor.Attribute
Dim deSerialString As String
If Attset.NameIsUsed(AttName) Then
JSONATT = Attset.Item(AttName)
End If
Try
deSerialString = JSONATT.Value
PipeList = JSeri.Deserialize(Of List(Of Pipe))(deSerialString)
Catch ex As Exception
Logger.Info("Ran into trouble when trying to deserialize.{0}{1}", vbCrLf, ex.Message)
End Try
Return PipeList
End Function
Class Pipe
Public _nps As String = ""
Public _ptype As String = "PIPE"
Public _mat As String = ""
Public _sch As String = ""
Public _pol As String = "MILL"
Public _lcOrPed As String = ""
Public _ptNum As String = ""
Public _thickness As Double
Public _schTableValue As ScheduleTableValues
Public Sub New
End Sub
End Class
<Serializable() >
Class ScheduleTableValues
Public _nominalPipeSize As Double
Public _od As Double
Public _sch05 As Double
Public _sch10 As Double
Public _sch20 As Double
Public _sch30 As Double
Public _sch40 As Double
Public _sch80 As Double
Public _sch120 As Double
Public _sch160 As Double
Public Overrides Function ToString() As String
Return String.Format("[NPS:{0}, OD:{1}]", Me._nominalPipeSize, Me._od)
End Function
Public Sub New
End Sub
End Class
Mind you, this solution for things is a couple of years old, and Ive grown leaps and bounds past this since then, so there's a ton of things I'd do differently now, not the least of which is using an all purpose dll I write in a sane language like Fsharp as much as possible, and then calling out to it from ilogic where needed, if at all.
I'm doing a lot of redunant work, a lot of updating the document when I don't have to, and the ways I'm allocating and reallocating too much data with my lists is very noobish as well, I just didn't understand data as well as I do now.

Comments
Post a Comment