pulling out a mass of a specific part from an assembly?

pulling out a mass of a specific part from an assembly?

chris
Advisor Advisor
892 Views
15 Replies
Message 1 of 16

pulling out a mass of a specific part from an assembly?

chris
Advisor
Advisor

UPDATE: I figured it out.

SOLUTION: WIP_SP1 = Round(iProperties.Mass("Part1:1")) + Round(iProperties.Mass("Part2:1")) + Round(iProperties.Mass("Part3:1"))

 

It would be nice if there was just a way to pick the parts you wanted instead of having to type them.

 

 

currently, to get the assembly mass I run this code:          WIP = Round(iProperties.Mass, 2)

but I'd like to have this same thing set up for just pulling out the weight of pre-selected parts, for example: (assume the "P" numbers are the browser part numbers

 

chris_0-1723038102595.png

 

what would be the best way to write for a combined mass of just the selected "P" numbers, with the name of that mass group called "WIP_SP1"?

 

0 Likes
Accepted solutions (1)
893 Views
15 Replies
Replies (15)
Message 2 of 16

chris
Advisor
Advisor

 a side note, how can I write a line of iLogic that allows me to write vertically instead of it being super long horizontally? is there a "bread command?

0 Likes
Message 3 of 16

WCrihfield
Mentor
Mentor

Hi @chris.  It looks like you figured most of this out, but are still inquiring about how to spread a line of code out into more lines of code.  In those cases, we can usually leave one space at the end of a line of code, followed by a single underscore character ( _), then continue any further code that would have normally been in that same line of code on the next line.  Finding a proper 'breaking point' to inject that space and underscore is the fun part, but it is usually not that complicated.

And by the way, instead of rounding the Mass of each individual component, before adding their rounded masses together, you could just round the overall sum of all their unrounded masses at one time (use a single Round method).  Less processing that way.

https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/program-structure/how-to-bre... 

https://learn.microsoft.com/en-us/dotnet/visual-basic/misc/bc30999 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 4 of 16

chris
Advisor
Advisor

@WCrihfield I tried writing it without ht around on each component, but it kept giving me an error, here is what I currently have, if you don't mind showing my the simplified version

 

WIP_SP1 = Round(iProperties.Mass("1092648-OSBL-Flange-002:1")) _
+ Round(iProperties.Mass("1092648-OSBL-Pipe-002:1")) _
+ Round(iProperties.Mass("1092648-OSBL-Elbow-002:1")) _
+ Round(iProperties.Mass("1092648-OSBL-Reducer-001:1")) _
+ Round(iProperties.Mass("1092648-OSBL-Pipe-008:1")) _
+ Round(iProperties.Mass("1092648-OSBL-Flange-001:1")) _
+ Round(iProperties.Mass("TOL-.5X4-3000-FS:1"))

0 Likes
Message 5 of 16

WCrihfield
Mentor
Mentor
Accepted solution

Notice that I have eliminated the second ")" character at the end of each line, except the last line, and have removed the "Round(" from near the beginning of each line.  Now, it would do the inner 'Sum' of all Mass values, then do just the one overall Round method on that inner Sum value.

WIP_SP1 = Round(iProperties.Mass("1092648-OSBL-Flange-002:1") _
+ iProperties.Mass("1092648-OSBL-Pipe-002:1") _
+ iProperties.Mass("1092648-OSBL-Elbow-002:1") _
+ iProperties.Mass("1092648-OSBL-Reducer-001:1") _
+ iProperties.Mass("1092648-OSBL-Pipe-008:1") _
+ iProperties.Mass("1092648-OSBL-Flange-001:1") _
+ iProperties.Mass("TOL-.5X4-3000-FS:1"))

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 16

chris
Advisor
Advisor

@WCrihfield ah, I had left the "(" in front of iProperties, thank you for the assist

0 Likes
Message 7 of 16

chris
Advisor
Advisor

@WCrihfield  I've encountered a weird "error"? WIP_SP5 is not allowing me to finish the combined weights with the double parentheses.  The other SP#'s allow the doubles at the end, but when I add it to SP5 it errors me. But of course it runs with a single, but for some reason, SP5 is not formatting the mass the way I want, it's out to 10 decimals? 

chris_0-1723087507236.pngchris_1-1723087548968.pngchris_2-1723087650027.png

 

 

WIP_SP1 = Round(iProperties.Mass("1092648-ISBL-Flange-002:1")*2 _
+ iProperties.Mass("1092648-ISBL-Pipe-009:1"))



WIP_SP2 = Round(iProperties.Mass("1092648-ISBL-Flange-002:1")*3 _
+ iProperties.Mass("1092648-ISBL-Tee-002:1") _
+ iProperties.Mass("1092648-ISBL-Pipe-008:1"))



WIP_SP3 = Round(iProperties.Mass("1092648-ISBL-Flange-002:1")*4 _
+ iProperties.Mass("1092648-ISBL-Pipe-010:1") _
+ iProperties.Mass("1092648-ISBL-Pipe-011:1") _
+ iProperties.Mass("1092648-ISBL-Tee-002:1")*2)



WIP_SP4 = Round(iProperties.Mass("1092648-ISBL-Flange-002:1")*3 _
+ iProperties.Mass("1092648-ISBL-Pipe-012:1"))



WIP_SP5 = Round(iProperties.Mass("1092648-ISBL-Flange-002:1")*3 _
+ iProperties.Mass("1092648-ISBL-Flange-001:1")*2 _
+ iProperties.Mass("1092648-ISBL-Pipe-003:1")*2 _
+ iProperties.Mass("1092648-ISBL-Pipe-004:1") _
+ iProperties.Mass("1092648-ISBL-Pipe-005:1") _
+ iProperties.Mass("1092648-ISBL-Pipe-006:1") _
+ iProperties.Mass("1092648-ISBL-Pipe-007:1") _
+ iProperties.Mass("1092648-ISBL-Reducer-001:1")*3 _
+ iProperties.Mass("TOL-2X6-3000-FS:3") _
+ iProperties.Mass("1092648-ISBL-Tee-001:1")*3) _
+ iProperties.Mass("1092648-ISBL-Elbow-001:1")



WIP_SP6 = Round(iProperties.Mass("1092648-ISBL-Flange-001:1")*2 _
+ iProperties.Mass("1092648-ISBL-Pipe-001:1") _
+ iProperties.Mass("TOL-.5X8-3000-FS:1"))
0 Likes
Message 8 of 16

chris
Advisor
Advisor

Here it is with the error

chris_4-1723087768720.png

 

 

0 Likes
Message 9 of 16

WCrihfield
Mentor
Mentor

Hi Chris.  I see where the issue is.  Its at the end of the next line above that position.  At the end of that previous line, after the "*3" you have the second ")" character there.  That needs to be moved to the end of the last line, where you are wanting to put it.  You may have added that last line after already having the rest of that block of code established, then forgot to move that one character.  Its amazing how much trouble/chaos a single misplaced or wrong character can cause in a code.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 16

_dscholtes_
Advocate
Advocate


Hmm, you could use a second (helper) rule which you run after you've made a selection in the modelling window that iterates through the selected items and outputs a text (in notepad?) based on a 'template' [EDIT] in a format [/EDIT] like below where you only need to add quantities and the # in the property name. You can then build your main rule using various of these exports.

 

 

WIP_SPX = Round(iProperties.Mass("<Name of component 1>") _
+ iProperties.Mass("<Name of component 2>") _
<repeat as much as necessary>
+ iProperties.Mass("<Name of component X>"))

 

 

 

0 Likes
Message 11 of 16

chris
Advisor
Advisor

@WCrihfield Always good to have a second set of eyes! again thanks!

 

@_dscholtes_ I'm not sure I understand, but I'll give it a try.

0 Likes
Message 12 of 16

WCrihfield
Mentor
Mentor

I'm guessing he means using a custom Function similar to this example below, but possibly with different types of inputs.  I'm using a NameValueMap here, because it is native to Inventor API, and is two-factor, so you can specify the component name, which is already a String anyways, then specify the quantity of that component as the second factor.  Then supply that NameValueMap to the Function, and it will iterate through the collection of name - value pairs, do the calculations, then return the total Mass value, that has been rounded.  The Sub Main section is just a brief example, for testing purposes.

 

Sub Main
	Dim oDataMap As NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
	oDataMap.Add("1092648-ISBL-Pipe-010:1", 1)
	oDataMap.Add("1092648-ISBL-Pipe-011:1", 1)
	oDataMap.Add("1092648-ISBL-Tee-002:1", 2)
	Dim dGroupMass As Double = GetRoundedMassTotals(oDataMap)
	Logger.Info(vbCrLf & "Group Mass = " & dGroupMass.ToString)
End Sub

Function GetRoundedMassTotals(NamesAndCounts As NameValueMap) As Double
	If NamesAndCounts Is Nothing OrElse NamesAndCounts.Count = 0 Then Return Nothing
	Dim dTotalMass As Double
	For i As Integer = 1 To NamesAndCounts.Count
		Dim sName As String = NamesAndCounts.Name(i)
		Dim iCount As Integer = CInt(NamesAndCounts.Value(sName))
		Dim dMass As Double
		Try
			dMass = iProperties.Mass(sName)
		Catch
			Continue For
		End Try
		dTotalMass += (dMass * iCount)
	Next
	If dTotalMass > 0 Then dTotalMass = Round(dTotalMass)
	Return dTotalMass
End Function

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 13 of 16

_dscholtes_
Advocate
Advocate

@WCrihfield, @chris 

I was thinking of a separate rule that translates a selection made by a user into a piece of code (based on Chris' wish to select components instead of typing their names and the similarity of the code sections in his rule).

 

Something that enables this workflow:

  1. Chris selects some components in modelling window;
  2. The rule processes all components in the selection and outputs a code section like the code sections in Chris' rule [ WIP_SP# = ... )) ] with all the names and multipliers in it*.
  3. Chris copies this output manually to his 'mass update rule' and adds the correct index for 'WIP_SP#'
  4. Repeat for all groups of components.

* I referred to Notepad in my previous post as a way to output the code section such way it can be copy-pasted to somewhere else. You could also use the logger I guess.

0 Likes
Message 14 of 16

WCrihfield
Mentor
Mentor

Not a bad idea, but maybe not the most efficient.  Maybe a better system would be to somehow be able to identify which components belong to different 'groups', by using Custom iProperties (which may 'dirty' those referenced documents), or by using 'Instance Properties' which would only exist at the assembly level that they were created at.  This can be applied to the group of components after they are selected.  That way, the code can find that same group(s) of components, without needing to specify any specific component names.  This would allow for repeatability of getting the sums of their mass, without any specific component names being involved in the code.

 

The following example code would allow you to either manually pre-select all the components in a group, or manually select them using the 'Pick' method after starting the rule, capturing them into a collection, then iterate through the collection to get their total mass.  That whole upper portion of the code which deals with pre-selection and 'Picking' could be replaced with a routine that searches through all components, looking for specific properties, then all with the same property value get grouped together.  There could be a two-factor list that pairs a property value with a parameter name, so that the mass of all components in group A gets assigned to parameter A.

 

At the end of this simple example, it is just asking the user to manually enter the name of a parameter that it should store the group mass value to.  That could also be replaced by a few more lines of code that gets the list of all UserParemeters, and lets the user select one of them, then stores the group mass value to that selected parameter.

Just some additional directions/ideas this type of scenario could go.

 

Sub Main
	Dim oApp As Inventor.Application = ThisApplication
	Dim oDoc As Document = ThisDoc.Document
	Dim oSS As SelectSet = oDoc.SelectSet
	Dim oListOfOccs As New List(Of ComponentOccurrence)
	If oSS.Count > 0 Then
		For i As Integer = 1 To oSS.Count
			If TypeOf oSS.Item(i) Is ComponentOccurrence Then
				Dim oSSOcc As ComponentOccurrence = oSS.Item(i)
				oListOfOccs.Add(oSSOcc)
			End If
		Next i
	End If
	If oListOfOccs.Count = 0 Then
		Dim oCmdMgr As CommandManager = oApp.CommandManager
		PickAgain :
		Dim oPickedOcc As ComponentOccurrence = Nothing
		oPickedOcc = oCmdMgr.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select A Component.")
		If oPickedOcc Is Nothing Then
			GoTo AfterPicking
		Else
			oListOfOccs.Add(oPickedOcc)
			GoTo PickAgain
		End If
	End If
	AfterPicking :
	If oListOfOccs.Count = 0 Then Return
	Dim dGroupMass As Double = 0.0
	For Each oOcc In oListOfOccs
		dGroupMass += iProperties.Mass(oOcc.Name)
	Next oOcc
	Logger.Info(vbCrLf & "Group Mass = " & dGroupMass.ToString)
	Dim sParamName As String = InputBox("Enter Name of Param to store value in.", "Param Name", "")
	Parameter(sParamName) = dGroupMass	
End Sub

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 15 of 16

_dscholtes_
Advocate
Advocate

@WCrihfield wrote:

Not a bad idea, but maybe not the most efficient.  Maybe a better system would be to somehow be able to identify which components belong to different 'groups' ...


Yes, any type of 'structure' / distinction in the assembly would be handy to create a more efficient or automated script (I'd go for (phantom) sub assemblies). But as Chris didn't mention anything about this, maybe his hands are tied regarding the modelling, I'd just go with my first thought of how I could make his work easier.

0 Likes
Message 16 of 16

WCrihfield
Mentor
Mentor

OK.  Here is another example that attempts your idea of generating the block of code needed for the selection set of components.  I left both options (pre-select or Pick) in there for now, to keep it dynamic, and am still prompting for the name of the parameter / variable to put at the beginning of that block of code, but that prompt could be eliminated and replace with a generic variable name that would need to be replaced/renamed when pasting the code into the rule later.  Then, if there were some components in the selection, it attempts to create a multi-line String needed for the rule, then writes that to the iLogic Log window, simply because that is the simplest / easiest option available that leaves us with selectable / copyable text.  But the 'iLogic Log' tab must have already been showing (but not necessarily the active tab) in your iLogic DockableWindow area before starting the rule, or it will not capture those Log entries.

 

Sub Main
	Dim oApp As Inventor.Application = ThisApplication
	Dim oDoc As Document = ThisDoc.Document
	Dim oSS As SelectSet = oDoc.SelectSet
	Dim oListOfOccs As New List(Of ComponentOccurrence)
	If oSS.Count > 0 Then
		For i As Integer = 1 To oSS.Count
			If TypeOf oSS.Item(i) Is ComponentOccurrence Then
				Dim oSSOcc As ComponentOccurrence = oSS.Item(i)
				oListOfOccs.Add(oSSOcc)
			End If
		Next i
	End If
	If oListOfOccs.Count = 0 Then
		Dim oCmdMgr As CommandManager = oApp.CommandManager
		PickAgain :
		Dim oPickedOcc As ComponentOccurrence = Nothing
		oPickedOcc = oCmdMgr.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select A Component.")
		If oPickedOcc Is Nothing Then
			GoTo AfterPicking
		Else
			oListOfOccs.Add(oPickedOcc)
			GoTo PickAgain
		End If
	End If
	AfterPicking :
	If oListOfOccs.Count = 0 Then Return
	Dim sParamName As String = InputBox("Enter Name of Param to store Mass value in.", "Param Name", "")
	Dim sCodeText As String = ""
	If sParamName = "" Then
		sCodeText = "XXX_XXX = Round("
	Else
		sCodeText = sParamName & " = Round("
	End If
	
	If oListOfOccs.Count = 1 Then
		sCodeText &= "iProperties.Mass(" & Chr(34) & oListOfOccs.Item(0).Name & Chr(34) & "))"
	Else
		For Each oOcc As ComponentOccurrence In oListOfOccs
			Dim sCore As String = "iProperties.Mass(" & Chr(34) & oOcc.Name & Chr(34) & ")"
			If oOcc Is oListOfOccs.First Then
				sCodeText &= sCore & " _" & vbCrLf
			ElseIf oOcc Is oListOfOccs.Last Then
				sCodeText &= "+ " & sCore & ")" & vbCrLf
			Else
				sCodeText &= "+ " & sCore & " _" & vbCrLf
			End If
		Next oOcc
	End If
	Logger.Info(vbCrLf & sCodeText & vbCrLf)
End Sub

 

If this solved your problem, or answered your question, please click ACCEPT SOLUTION .
Or, if this helped you, please click (LIKE or KUDOS) 👍.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)