Ilogic performance inconsistency - with logs - need help.

Ilogic performance inconsistency - with logs - need help.

J_Pfeifer_
Advocate Advocate
358 Views
4 Replies
Message 1 of 5

Ilogic performance inconsistency - with logs - need help.

J_Pfeifer_
Advocate
Advocate

Good morning everyone, 


After a bunch of work to create primary templates and framework here at our company. I've run into something quite interesting. First off, the goal, I created configurators allowing fitting placement onto a dome top, and sidewall of our tanks. These were built to be fully parametric allowing direct editing without ever entering the model browser manually. Everything is creatable, and editable based on forms.

When I went to release these to the team, we were unhappy with the single placement runtime. I then refactored them to have as little objects as possible as few API calls required to finish off the fittings. I was able to bring it down to a manageable runtime, then released these templates to our team. 

That brings me to today, where I started on another type of tank top (flat top). Using the same frame work, with copied user parameters and rules. Only to find, for some reason unbeknownst to me, the program runs 8-10x faster overall. All the objects are the same, all the parametric expressions are applied nearly identically, and the feature / body naming is consistent. However, I cannot fathom why the first two templates take so much longer to calculate. 

 

During my optimization I created a timing program to show overall time, and section time. Allowing me to see where the slow downs were. However, I didn't find one section that stood out. The entire program as a whole simply ran slow. However, with a new template the entire program is now much faster. 

We plan to use the old templates, however, If I can get the runtime of these down to what I experience with this new one. That would be greatly beneficial. I feel that I'm missing something extremely critical. Any help would be appreciated. 

Below are the timing logs, and pictures of what's being created on each. To be clear, there are differences in how the fittings are placed, and some of the math / expressions used to apply the fittings. That is, the geometry to where they must start is different, but the creations themselves are identical. However, you will see from the logs, the time difference doesn't make sense (At least to me). Each fitting being applied is a standard 6" flanged nozzle with 4 plate gussets.  

Dome Fitting Placement timings:

INFO|Start current time: 00:00:00.0000011 Section time: 00:00:00.0000011
INFO|Bodies collected current time: 00:00:00.0062867 Section time: 00:00:00.0062856
INFO|Flange type selection finished current time: 00:00:00.0062890 Section time: 00:00:00.0000023
INFO|Calculations and strings created current time: 00:00:00.0063036 Section time: 00:00:00.0000146
INFO|expressions created current time: 00:00:00.2463493 Section time: 00:00:00.2400457
INFO|UCS creation current time: 00:00:00.9397604 Section time: 00:00:00.6934111
INFO|UCS Name and expressions current time: 00:00:00.9397621 Section time: 00:00:00.0000017
INFO|Flange sketch objects created current time: 00:00:02.4107226 Section time: 00:00:01.4709605
INFO|Flange sketch Expressions assigned current time: 00:00:03.2957951 Section time: 00:00:00.8850725
INFO|Downpipe block current time: 00:00:03.2957958 Section time: 00:00:00.0000007
INFO|GusBoltSketch projections complete current time: 00:00:03.8060827 Section time: 00:00:00.5102869
INFO|Gusset + bolt sketch created current time: 00:00:04.2123908 Section time: 00:00:00.4063081
INFO|Gusset expressions assigned current time: 00:00:04.5047325 Section time: 00:00:00.2923417
INFO|Flange revolve finished current time: 00:00:04.6569661 Section time: 00:00:00.1522336
INFO|Bolt hole created current time: 00:00:05.1423473 Section time: 00:00:00.4853812
INFO|Bolt and pattern created current time: 00:00:05.2934999 Section time: 00:00:00.1511526
INFO|Tank hole created - Last time measurement before gussets current time: 00:00:05.5953714 Section time: 00:00:00.3018715
INFO|Trim to tank combine created current time: 00:00:05.9051758 Section time: 00:00:00.3098044
INFO|agitator flange or solids created. current time: 00:00:05.9051764 Section time: 00:00:00.0000006
INFO|Feature naming done current time: 00:00:05.9613297 Section time: 00:00:00.0561533
INFO|Gusset block current time: 00:00:07.9276211 Section time: 00:00:01.9662914

 

INFO|End of program: 00:00:07.9276228

J_Pfeifer__0-1781701744188.png

 

 

Sidewall Placement timings:

 

INFO|Start current time: 00:00:00.0000007 Section time: 00:00:00.0000007
INFO|Bodies collected current time: 00:00:00.1209570 Section time: 00:00:00.1209563
INFO|tangent checks + parameter creation current time: 00:00:00.3945542 Section time: 00:00:00.2735972
INFO|UCS creation current time: 00:00:01.3236733 Section time: 00:00:00.9291191
INFO|UCS Name and expressions current time: 00:00:01.7522218 Section time: 00:00:00.4285485
INFO|Flange sketch objects created current time: 00:00:01.8119610 Section time: 00:00:00.0597392
INFO|Constraints applied current time: 00:00:02.7656996 Section time: 00:00:00.9537386
INFO|Flange assignements current time: 00:00:03.6177587 Section time: 00:00:00.8520591
INFO|Flange sketch parameters updated current time: 00:00:03.8485785 Section time: 00:00:00.2308198
INFO| Flange revolve finished current time: 00:00:04.1727124 Section time: 00:00:00.3241339
INFO|GusBoltSketch projections complete current time: 00:00:04.8507958 Section time: 00:00:00.6780834
INFO| Total bolt, gus, and cut sketch created current time: 00:00:05.6375365 Section time: 00:00:00.7867407
INFO|Bolt hole created current time: 00:00:06.2011502 Section time: 00:00:00.5636137
INFO| Bolt and pattern created current time: 00:00:06.4456078 Section time: 00:00:00.2444576
INFO| Tank hole created - Last time measurement before gussets current time: 00:00:06.9368458 Section time: 00:00:00.4912380
INFO|Trim completed current time: 00:00:07.2357228 Section time: 00:00:00.2988770
INFO| Renaming complete current time: 00:00:07.2628682 Section time: 00:00:00.0271454
INFO|Creating gussets current time: 00:00:07.5037503 Section time: 00:00:00.2408821
INFO|done creating starting blind current time: 00:00:10.2198876 Section time: 00:00:02.7161373
INFO|Current ending time current time: 00:00:10.2200407 Section time: 00:00:00.0001531

 

INFO|End of program: 00:00:10.2200413

J_Pfeifer__1-1781701789096.png

 

 

Flat Top Placement timings:

 

INFO|Start current time: 00:00:00.0021513 Section time: 00:00:00.0021513
INFO|Bodies collected current time: 00:00:00.0054841 Section time: 00:00:00.0033328
INFO|Flange type selection finished current time: 00:00:00.0084894 Section time: 00:00:00.0030053
INFO|expressions created current time: 00:00:00.0810707 Section time: 00:00:00.0725813
INFO|UCS creation current time: 00:00:00.1832772 Section time: 00:00:00.1022065
INFO|UCS Name and expressions current time: 00:00:00.1854329 Section time: 00:00:00.0021557
INFO|Flange sketch objects created current time: 00:00:00.4202639 Section time: 00:00:00.2348310
INFO|Flange sketch Expressions assigned current time: 00:00:00.6249049 Section time: 00:00:00.2046410
INFO|Downpipe block current time: 00:00:00.6275123 Section time: 00:00:00.0026074
INFO|GusBoltSketch projections complete current time: 00:00:00.7000802 Section time: 00:00:00.0725679
INFO|Gusset + bolt sketch created current time: 00:00:00.7882997 Section time: 00:00:00.0882195
INFO|Gusset expressions assigned current time: 00:00:00.8565726 Section time: 00:00:00.0682729
INFO|Flange revolve finished current time: 00:00:00.8786062 Section time: 00:00:00.0220336
INFO|Bolt hole created current time: 00:00:00.9477425 Section time: 00:00:00.0691363
INFO|Bolt and pattern created current time: 00:00:00.9631923 Section time: 00:00:00.0154498
INFO|Tank hole created - Last time measurement before gussets current time: 00:00:00.9927119 Section time: 00:00:00.0295196
INFO|Trim to tank combine created current time: 00:00:01.0152568 Section time: 00:00:00.0225449
INFO|agitator flange or solids created. current time: 00:00:01.0193598 Section time: 00:00:00.0041030
INFO|Feature naming done current time: 00:00:01.0487372 Section time: 00:00:00.0293774
INFO|Gusset block current time: 00:00:01.3994151 Section time: 00:00:00.3506779

 

INFO|End of program: 00:00:01.4013818

J_Pfeifer__2-1781701833935.png


@Curtis_Waguespack 
@WCrihfield 
@JelteDeJong 

 



0 Likes
Accepted solutions (1)
359 Views
4 Replies
Replies (4)
Message 2 of 5

JhoelForshav
Mentor
Mentor
Accepted solution

Hi @J_Pfeifer_ 
Looking at your timing data, there's no single operation that sticks out. It's basically the same time loss factor everywhere, if you wanna call it that. I'd say the difference isn't in the code but the part itself. Every recompute in Inventor has to solve against the geometry you're working with, and a flat surface is simply way less complex to solve against than your curved surfaces in the dome/side wall. Without seeing your code it's difficult to say where you can save time, but basically generating geometry slows things down. So if you can deffer updates, turn of screen updating, avoid unnecessary document updates etc you could possibly gain some speed. However, given that you're working against a flat surface, which is a way simpler geometry, the flat top will always be faster.

Message 3 of 5

J_Pfeifer_
Advocate
Advocate

See this is the conclusion I came to back when I first encountered this problem. The company had hired a third party to create templates before my exploration. These ran significantly faster, however they were not parametric or dynamic to the model. They also didn't bother fully constraining the sketches involved. This led me to thinking I was doing something wrong causing the slow down. One could argue that generating this geometry is the incorrect path in general. Something like derived parts or i parts would likely be quicker. 

Basically it boils down to the recalculations being done by the inventor engine. Due to the curved surfaces, and base model geometry, there is a minimum speed that can be achieved? That is, I'm sure there are still places I could optimized, but due to the model's needs the time cost will likely remain no matter my efforts?

 

I have the main sketch creation deferred already, I found marginal gains there. However, screen updating seemed to have little to no effect and introduce lock up risk to the programs. I played around moving the parametric assignments. Trying to get them all to process at the same time. Is there a way to defer the entire document until the end? Or control the document updating more consistently?

I was just flabbergasted to how much faster this was when I got it converted this morning.

People don't like to hit a button to do something and wait. This is also why I made this post. If they have one template that runs in 2 seconds, and others that run in 10 seconds. They're going to ask why, and I need a way to explain that properly to them. 

For fun, below is the main of this application. (Yes, it's likely a mess to most)

Sub main
	 
	Dim App As Inventor.Application = ThisApplication
	Dim oDoc As PartDocument = App.ActiveDocument 
	Dim oCompDef As PartComponentDefinition = oDoc.ComponentDefinition
	Dim oTO As TransientObjects = App.TransientObjects
	Dim oTG As TransientGeometry = App.TransientGeometry
	Dim UParams As UserParameters = oCompDef.Parameters.UserParameters
	Dim Trnsmgr As TransactionManager = App.TransactionManager

	iLogicVb.UpdateWhenDone = True
	
Dim FittingTransaction As Transaction 

If Transaction_Flip = False Then 
  FittingTransaction = Trnsmgr.StartTransaction(oDoc, "Standard fitting creation")
End If 

	Dim	Flange_Face_OD As Double, Flange_Head_Thickness As Double, Flange_Thickness As Double, Bolt_Circle As Double, Bolt_Dia As Double
	Dim Num_of_Bolts As Integer, GussetProgAngle As Integer = 360
	Dim GussetBool As Boolean = False
	
Dim FittingNameInput As String 

If Devoloper_Flip = False Then 
	
'	If Rule_Launched = False Then 	
		FittingNameInput = InputBox("Please enter the F# value to name the fitting.", "Name Fitting")
'	Else If Rule_Launched = True Then ' This boolean checks if a rule launched this program. If so it will assume its to recreate an edit.  
	'	FittingNameInput = CType(Edit_Fitting_List, String)
		
	'	Flange_Size = Edit_Flange_Size
	'	Fitting_Height = Edit_Flange_Height
	'	Fitting_Angle = Edit_Flange_Angle
	'	Fitting_Offset_Dir = Edit_Fitting_Offset_Dir
	'	Fitting_Offset = Edit_Fitting_Offset
'	End If
	
Else If Devoloper_Flip = True Then 
	FittingNameInput = "F" & Fitting_Number
End If 

		Dim iWatch As Stopwatch = Stopwatch.StartNew 
		Dim PreviousTime As TimeSpan = Nothing
	
		DisplayTimer(iWatch, "Start", PreviousTime)

	Dim StringPattern As String = "^[F]\d{1,3}$"	

	If Regex.IsMatch(FittingNameInput, StringPattern) Then 
		
	Else
		MessageBox.Show("Incorrect Input, please run program again with different name. F### accepted (CAPS ONLY)")
		FittingTransaction.Abort()
		
		Exit Sub
	End If
	
	Dim InsideBodyCol As ObjectCollection = oTO.CreateObjectCollection 'These collections are used for the combine features
	Dim OutsideBodyCol As ObjectCollection = oTO.CreateObjectCollection
		CollectSolids(InsideBodyCol, OutsideBodyCol)
		
	Dim TankBodyCol As ObjectCollection = oTO.CreateObjectCollection 'This is the primary collection used for the tank hole cut. 
		TankBodyCol.Add(oCompDef.SurfaceBodies(1))
	
	DisplayTimer(iWatch, "Bodies collected", PreviousTime)	
	
	Dim FlangeType As String 
	Dim UpperDpFlg As Boolean
	Dim LowerDpFlg As Boolean
	
'Try	
	
	If SharedVariable.Exists("TypeTransfer") = False Then 'This checks if there is a type transfer, if so it uses that value from the other creation. Otherwise it then checks if there are downpipes or not involved. Setting the flange type to required input.
		If Downpipe_Trigger = False Then 
			FlangeType = "Standard"
		Else If Downpipe_Trigger = True Then 
			If Downpipe_Type = "P.V.C."
				FlangeType = "PVC Downpipe"
				UpperDpFlg = False
				LowerDpFlg = True
			Else If Downpipe_Type = "F.R.P."
				FlangeType = "FRP Downpipe"
				UpperDpFlg = False
				LowerDpFlg = True
			Else If Downpipe_Type = "P.V.C. Removable"
				FlangeType = "PVC Removable Downpipe"
				UpperDpFlg = True
				LowerDpFlg = False
			Else If Downpipe_Type = "F.R.P. Removable"
				FlangeType = "FRP Removable Downpipe"
				UpperDpFlg = True	
				LowerDpFlg = False
			End If 
		End If 
	Else 
		FlangeType = SharedVariable("TypeTransfer") 
	End If 
		
		DisplayTimer(iWatch, "Flange type selection finished", PreviousTime)
	'Logger.Info("FittingType: " & FlangeType & " Upper flag: " & UpperDpFlg.ToString & " Lower Flag: " & LowerDpFlg.ToString)	
		
	If Downpipe_Trigger = True Or FlangeType = "Anti-Foam" Then  'Set the values required when inserting the standard fitting. 
		Trim_Fitting_Tube = False
	End If 
	
	If Agitator_Flange = True Then 'Sets the value of the plate gusset to none in order to create the agitator flange solid and items.
		Gusset_Type = "None"
	End If 
		
	SharedVariable.RemoveAll() 'Used to remove all non needed shared variables from the program when called. 
	
	SharedVariable.Value("FittingName") = FittingNameInput
	
	If Cartesian_Input = True Then 'converts the cartesian input method into a polar input system allowing for correct placement metrics. 
			
			Dim iTuple As Tuple(Of Double, Double) = CartesianToPolar()
				
			Dim RadiusCalc As Double = iTuple.Item1
			Dim AngleCalc As Double = iTuple.Item2 * (180 / Math.PI)
			
				Fitting_Placement = RadiusCalc
				Angle_from_Start = AngleCalc
				Plate_Gus_Angle = AngleCalc
				
		Else 
				Plate_Gus_Angle = 0
	End If 
	
		SelectFittingOptions(Flange_Face_OD, Flange_Head_Thickness, Flange_Thickness, Bolt_Circle, Bolt_Dia, Num_of_Bolts) 'This finds the required values for the flanges being applied. 
		
		'Setup required parameters 
		UParams.AddByValue(FittingNameInput & "_Flange_Size", Flange_Size * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Flange_Face_OD", Flange_Face_OD * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Flange_Head_Thickness", Flange_Head_Thickness * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Flange_Thickness", Flange_Thickness * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Flange_Type", FlangeType, Inventor.UnitsTypeEnum.kTextUnits)
		UParams.AddByValue(FittingNameInput & "_Bolt_Circle", Bolt_Circle * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Bolt_Dia", Bolt_Dia * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Num_Of_Bolts", Num_of_Bolts, Inventor.UnitsTypeEnum.kUnitlessUnits)
		UParams.AddByValue(FittingNameInput & "_Bolt_Angle", FindBoltAngle(Num_of_Bolts), Inventor.UnitsTypeEnum.kDegreeAngleUnits)
		UParams.AddByValue(FittingNameInput & "_Gusset_Type", Gusset_Type, Inventor.UnitsTypeEnum.kTextUnits)
		UParams.AddByValue(FittingNameInput & "_Num_Of_Gus", Num_Of_Gus, Inventor.UnitsTypeEnum.kUnitlessUnits)
		UParams.AddByValue(FittingNameInput & "_Plate_Gus_Angle", Plate_Gus_Angle * (Math.PI / 180), Inventor.UnitsTypeEnum.kDegreeAngleUnits)
		UParams.AddByValue(FittingNameInput & "_Fitting_Proj", 12 * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Fitting_Trim", Trim_Fitting_Tube, Inventor.UnitsTypeEnum.kBooleanUnits)
		UParams.AddByValue(FittingNameInput & "_Fitting_Placement", Fitting_Placement * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		UParams.AddByValue(FittingNameInput & "_Fitting_Angle", Angle_from_Start * (Math.PI / 180), Inventor.UnitsTypeEnum.kDegreeAngleUnits)
		UParams.AddByValue(FittingNameInput & "_Blind", Blind_Flange, Inventor.UnitsTypeEnum.kBooleanUnits)
		UParams.AddByValue(FittingNameInput & "_Fitting_Height", 6 * 2.54, Inventor.UnitsTypeEnum.kInchLengthUnits)
		
		'Setup dynamic and special variables 	
			'UParams.AddByExpression(FittingNameInput & "_Chord_Length", ChordStr, Inventor.UnitsTypeEnum.kInchLengthUnits) 
			'UParams.AddByExpression(FittingNameInput & "_Cir_Seg_h", CirSegStr, Inventor.UnitsTypeEnum.kInchLengthUnits)
				
		DisplayTimer(iWatch, "expressions created", PreviousTime)	
		
'Catch Err As Exception 
'		Call ReportError("Problem establishing parameters", Err, FittingTransaction)		
'End Try
			
	'This the actual start of the flange creation. Everything before this is establishing varaibles and saving data internally. 
	Dim oUCSDef As UserCoordinateSystemDefinition
	Dim oUCS As UserCoordinateSystem
	
'Try	
		oUCSDef = oCompDef.UserCoordinateSystems.CreateDefinition() 
	
		oUCS = oCompDef.UserCoordinateSystems.Add(oUCSDef) 
			oUCS.Visible = False
		
		DisplayTimer(iWatch, "UCS creation", PreviousTime)
		
		SharedVariable.Value("FittingUCS") = oUCS
		
'Catch Err As Exception 
'		Call ReportError("Problem Establishing the UCS object or direction starting points", Err, FittingTransaction)		
'End Try

		DisplayTimer(iWatch, "UCS Name and expressions", PreviousTime)
	
	Dim FlangeSketch As PlanarSketch
	
	Dim CenterLine As SketchLine, CenterPoint As SketchPoint
	
	Dim TopUCSLine As SketchLine, BotUCSLine As SketchLine
	
	Dim FlgRect As SketchEntitiesEnumerator, TBRect As SketchEntitiesEnumerator
	
	Dim FlangeIDDim As DimensionConstraint, FlangeFaceODDim As DimensionConstraint, FlangeHeadThickDim As DimensionConstraint, FlangeThickDim As DimensionConstraint, FlangePlaceDim As DimensionConstraint, FittingDisDim As DimensionConstraint
	Dim FittingPlacementDim As DimensionConstraint, FittingHeightDim As DimensionConstraint
	
	Dim CenterFittingAxis As WorkAxis
	
'Try		

		FlangeSketch = oCompDef.Sketches.Add(oUCS.YZPlane)
			
			FlangeSketch.DeferUpdates = True
	
		CenterPoint = FlangeSketch.SketchPoints.Add(oTG.CreatePoint2d(0, 0))
			FlangeSketch.GeometricConstraints.AddGround(CenterPoint)
		
	Dim CenterStartPoint As Point2d = oTG.CreatePoint2d(CenterPoint.Geometry.X, CenterPoint.Geometry.Y + Fitting_Placement * 2.54) 'This creates the horizontal placement Point
	
	Dim CenterEndPoint As Point2d = oTG.CreatePoint2d(CenterStartPoint.X + 6 * 2.54, CenterStartPoint.Y) 'This creates the vertical placement point

		CenterLine = FlangeSketch.SketchLines.AddByTwoPoints(CenterStartPoint, CenterEndPoint)
			CenterLine.Construction = True
			
			Dim AttrLineSetName As String = FittingNameInput & "LineSet"
			
			CenterLine.AttributeSets.Add(AttrLineSetName)
			
		SharedVariable.Value("CenterLine") = CenterLine	
			
	CenterFittingAxis = oCompDef.WorkAxes.AddByLine(CenterLine)	
		CenterFittingAxis.Visible = False
		
		SharedVariable.Value("CenterAxis") = CenterFittingAxis

			FlangeSketch.GeometricConstraints.AddVerticalAlign(CenterPoint, CenterLine.StartSketchPoint)
			FlangeSketch.GeometricConstraints.AddHorizontal(CenterLine)
			
				FittingPlacementDim = FlangeSketch.DimensionConstraints.AddTwoPointDistance(CenterPoint, CenterLine.StartSketchPoint, DimensionOrientationEnum.kVerticalDim, oTG.CreatePoint2d(5, 5))
					FittingPlacementDim.Parameter.Value = Fitting_Placement * 2.54
					
				FittingHeightDim = FlangeSketch.DimensionConstraints.AddTwoPointDistance(CenterLine.StartSketchPoint, CenterLine.EndSketchPoint, DimensionOrientationEnum.kHorizontalDim, oTG.CreatePoint2d(10, -10))
			
			FlangeSketch.Solve()
			
		Dim SFPoint As Point2d = oTG.CreatePoint2d(CenterLine.EndSketchPoint.Geometry.X, CenterLine.EndSketchPoint.Geometry.Y + (Flange_Size / 2) * 2.54) 'X is up and down, Y is left and right. 
			
		Dim SFPoint2 As Point2d = oTG.CreatePoint2d(SFPoint.X - Flange_Head_Thickness * 2.54, SFPoint.Y + (Flange_Face_OD - Flange_Size) / 2 * 2.54)
		
		Dim TBPoint As Point2d = oTG.CreatePoint2d(SFPoint.X - 12 * 2.54, SFPoint.Y + (Flange_Thickness / 2) * 2.54) 'This input distance will need to be changed when a downpipe is created.
		
			FlgRect = FlangeSketch.SketchLines.AddAsTwoPointRectangle(SFPoint, SFPoint2)
			
			TBRect = FlangeSketch.SketchLines.AddAsTwoPointRectangle(SFPoint, TBPoint)
			
		FlangeIDDim = FlangeSketch.DimensionConstraints.AddOffset(FlgRect(1), CenterLine, oTG.CreatePoint2d(FlgRect(1).StartSketchPoint.Geometry.X + 2, FlgRect(1).StartSketchPoint.Geometry.Y  + Flange_Size / 2 * 2.54), True) 
		
		FlangeFaceODDim = FlangeSketch.DimensionConstraints.AddOffset(FlgRect(3), CenterLine, oTG.CreatePoint2d(FlgRect(3).EndSketchPoint.Geometry.x + 4, FlgRect(3).EndSketchPoint.Geometry.Y + Flange_Face_OD / 2 * 2.54), True)
		
		FlangeHeadThickDim = FlangeSketch.DimensionConstraints.AddTwoPointDistance(FlgRect(3).StartSketchPoint, FlgRect(3).EndSketchPoint, Inventor.DimensionOrientationEnum.kHorizontalDim, oTG.CreatePoint2d(FlgRect(3).StartSketchPoint.Geometry.X + Flange__Head_Thickness / 2, FlgRect(3).StartSketchPoint.Geometry.Y - 2))
		
		FlangeThickDim = FlangeSketch.DimensionConstraints.AddTwoPointDistance(TbRect(2).StartSketchPoint, TbRect(2).EndSketchPoint, Inventor.DimensionOrientationEnum.kVerticalDim, oTG.CreatePoint2d(TBrect(2).EndSketchPoint.Geometry.X - Flange_Thickness / 4, TBRect(2).EndSketchPoint.Geometry.Y - 2))
		
			FlangeSketch.GeometricConstraints.AddCoincident(FlgRect(1).StartSketchPoint, TBRect(4))
			FlangeSketch.GeometricConstraints.AddCoincident(FlgRect(1).StartSketchPoint, TBRect(1))
			FlangeSketch.GeometricConstraints.AddVerticalAlign(FlgRect(1).StartSketchPoint, CenterLine.EndSketchPoint)
		
		FittingDisDim = FlangeSketch.DimensionConstraints.AddTwoPointDistance(TBRect(1).StartSketchPoint, TBRect(1).EndSketchPoint, Inventor.DimensionOrientationEnum.kHorizontalDim, oTG.CreatePoint2d(TBRect(1).EndSketchPoint.Geometry.X + 6, TBRect(1).EndSketchPoint.Geometry.Y + 2))
			FittingDisDim.Parameter.Expression = FittingNameInput & "_Fitting_Proj"
			
		FlangeSketch.DeferUpdates = False	
		
		DisplayTimer(iWatch, "Flange sketch objects created", PreviousTime) 
		
						'Apply expressions to the flange revolve creation
						FittingPlacementDim.Parameter.Expression = FittingNameInput & "_Fitting_Placement"
						FittingHeightDim.Parameter.Expression = FittingNameInput & "_Fitting_Height"
						FlangeIDDim.Parameter.Expression = FittingNameInput & "_Flange_Size"
						FlangeFaceODDim.Parameter.Expression = FittingNameInput & "_Flange_Face_OD"
						FlangeHeadThickDim.Parameter.Expression = FittingNameInput & "_Flange_Head_Thickness"
						FlangeThickDim.Parameter.Expression = FittingNameInput & "_Flange_Thickness / 2"
			
			
		DisplayTimer(iWatch, "Flange sketch Expressions assigned", PreviousTime) 
		
			If UpperDpFlg = True Or LowerDpFlg = True Then 
				
					'Create the UCS lines that represent the UCS placement for downpipes
					TopUCSLine = FlangeSketch.SketchLines.AddByTwoPoints(CenterLine.EndSketchPoint, oTG.CreatePoint2d(CenterLine.EndSketchPoint.Geometry.X, CenterLine.EndSketchPoint.Geometry.Y + 2.54))	
						TopUCSLine.Construction = True
					
						FlangeSketch.GeometricConstraints.AddVertical(TopUCSLine)
						
					Dim MiddleBotPoint As Point2d = oTG.CreatePoint2d(CenterLine.EndSketchPoint.Geometry.X - 12 * 2.54, CenterLine.EndSketchPoint.Geometry.Y)	
					
					BotUCSLine = FlangeSketch.SketchLines.AddByTwoPoints(MiddleBotPoint, oTG.CreatePoint2d(CenterLine.StartSketchPoint.Geometry.X, CenterLine.StartSketchPoint.Geometry.Y + 2.54))
						BotUCSLine.Construction = True
						
						FlangeSketch.GeometricConstraints.AddCoincident(BotUCSLine.StartSketchPoint, CenterLine)
						FlangeSketch.GeometricConstraints.AddVertical(BotUCSLine)
						FlangeSketch.GeometricConstraints.AddVerticalAlign(BotUCSLine.StartSketchPoint, TbRect(2).StartSketchPoint)
						FlangeSketch.GeometricConstraints.AddHorizontalAlign(TopUCSLine.EndSketchPoint, BotUCSLine.EndSketchPoint)
						
					Dim TopSketchPoint As SketchPoint = FlangeSketch.SketchPoints.Add(oTG.CreatePoint2d(CenterLine.EndSketchPoint.Geometry.X + 2.54, CenterLine.EndSketchPoint.Geometry.Y))	
							
						FlangeSketch.GeometricConstraints.AddHorizontalAlign(TopSketchPoint, CenterLine.EndSketchPoint)	
						
					CreateDpUCS(UpperDpFlg, LowerDpFlg, TopUCSLine, BotUCSLine, TopSketchPoint, FlangeType, oCompDef, FittingNameInput)	
						
			End If		
				
	DisplayTimer(iWatch, "Downpipe block", PreviousTime)	
	
'Catch Err As Exception 
'	Call ReportError("Encountered problem creating horizontal placement sketch", Err, FittingTransaction)	
'End Try		
	
	Dim BackFace As Face, TopFace As Face 

	Dim GussetBoltPlane As WorkPlane, GusBoltSketch As PlanarSketch
	
	Dim CenterAxisLine As SketchLine, InnerCircle As SketchCircle, OuterCircle As SketchCircle, BoltCircle As SketchCircle, BoltAngleLine As SketchLine, StartPlateLine As SketchLine, EndPlateLine As SketchLine
	
	Dim EndPlateEnum As SketchEntitiesEnumerator 
	
	Dim BoltCirDim As DimensionConstraint, BoltAngleDim As DimensionConstraint, PlateOffsetDim As DimensionConstraint, InnerCirDim As DimensionConstraint, OutCirDim As DimensionConstraint, OffsetTest As DimensionConstraint, OffsetTest2 As DimensionConstraint
	Dim GusAngleDim As DimensionConstraint 
	
'	Try
					Dim TopPlane As WorkPlane = oCompDef.WorkPlanes.AddByPlaneAndPoint(oUCS.XZPlane, CenterLine.EndSketchPoint)
						TopPlane.Visible = False
						TopPlane.Name = FittingNameInput & " Top Plane"
						SharedVariable.Value("TopPlane") = TopPlane
						
						GussetPlane = oCompDef.WorkPlanes.AddByPlaneAndOffset(TopPlane, -2 * 2.54)
							GussetPlane.Visible = False
							
						GusBoltSketch = oCompDef.Sketches.Add(GussetPlane)
							GusBoltSketch.DeferUpdates = True
						
						CenterAxisLine = GusBoltSketch.AddByProjectingEntity(oUCS.YZPlane)
							CenterAxisLine.Construction = True
						
							Dim GusBoltCenterStart As SketchPoint = GusBoltSketch.AddByProjectingEntity(CenterFittingAxis)
							
								Dim GUSCENX As Double = GusBoltCenterStart.Geometry.X 'These two double values are to pull the direct point locations from the center. 
								Dim GYSCENY As Double = GusBoltCenterStart.Geometry.Y
							
							InnerCircle = GusBoltSketch.SketchCircles.AddByCenterRadius(GusBoltCenterStart, (Flange_Size + Flange_Thickness) / 2 * 2.54)
				
							InnerCirDim = GusBoltSketch.DimensionConstraints.AddDiameter(InnerCircle, oTG.CreatePoint2d(5, 5))
					
							BoltCircle = GusBoltSketch.SketchCircles.AddByCenterRadius(GusBoltCenterStart, Bolt_Circle / 2 * 2.54)
								BoltCircle.Construction = True
								
								GusBoltSketch.GeometricConstraints.AddConcentric(BoltCircle, InnerCircle)
								GusBoltSketch.GeometricConstraints.AddCoincident(InnerCircle.CenterSketchPoint, GusBoltCenterStart)
				
					DisplayTimer(iWatch, "GusBoltSketch projections complete", PreviousTime)		
							
								BoltCirDim = GusBoltSketch.DimensionConstraints.AddDiameter(BoltCircle, oTG.CreatePoint2d(GUSCENX - 6, GYSCENY - 6))
								
							BoltAngleLine = GusBoltSketch.SketchLines.AddByTwoPoints(GusBoltCenterStart, oTG.CreatePoint2d(GUSCENX - 5, GYSCENY - 5))	
								BoltAngleLine.Construction = True
							
								GusBoltSketch.GeometricConstraints.AddCoincident(BoltAngleLine.EndSketchPoint, BoltCircle)
								
								SharedVariable.Value("BoltPoint") = BoltAngleLine.EndSketchPoint 
								
								Dim AttrPointSetName As String = FittingNameInput & "boltset"
								
								BoltAngleLine.EndSketchPoint.AttributeSets.Add(AttrPointSetName)
								
							'	For Each oSet As AttributeSet In BoltAngleLine.EndSketchPoint.AttributeSets 'This point gets an attribute in order to confirm the bolt hole location as requried. 
							'	    Logger.Info("Set name: " & oSet.Name)
							'	Next
								
							BoltAngleDim = GusBoltSketch.DimensionConstraints.AddTwoLineAngle(CenterAxisLine, BoltAngleLine, oTG.CreatePoint2d(GusBoltCenterStart.Geometry.X -3, GusBoltCenterStart.Geometry.Y -25))'oTG.CreatePoint2d(StartPlateLine.StartSketchPoint.Geometry.X - 3, StartPlateLine.StartSketchPoint.Geometry.Y - 25))
								BoltAngleDim.Parameter.Expression = FittingNameInput & "_Bolt_Angle -" & FittingNameInput & "_Plate_Gus_Angle"
								
					GusBoltSketch.DeferUpdates = False
						
					DisplayTimer(iWatch, "Gusset + bolt sketch created", PreviousTime) 
				
									InnerCirDim.Parameter.Expression = FittingNameInput & "_Flange_Size + " & FittingNameInput & "_Flange_Thickness"
							
									BoltCirDim.Parameter.Expression = FittingNameInput & "_Bolt_Circle"
					
			DisplayTimer(iWatch, "Gusset expressions assigned", PreviousTime)	
							
'	Catch Err As Exception 
'		Call ReportError("Issue creating bolt / gusset sketch", Err, FittingTransaction)			
'	End Try			

	Dim FlangeCol As ObjectCollection = oTO.CreateObjectCollection
	Dim FittingProfile As Profile
	Dim FlangeRevolve As RevolveFeature
		
'	Try
			FittingProfile = FlangeSketch.Profiles.AddForSolid
			
			FlangeRevolve = oCompDef.Features.RevolveFeatures.AddFull(FittingProfile, CenterLine, Inventor.PartFeatureOperationEnum.kNewBodyOperation)
		
		DisplayTimer(iWatch, "Flange revolve finished", PreviousTime)		
		
'	Catch Err As Exception 
'		Call ReportError("Encountered problem creating horizontal placement sketch", Err, FittingTransaction)			
'	End Try	
	
	oUCS.YAngle.Expression = "180 +" & FittingNameInput & "_Fitting_Angle" 'Rotate the UCS to the correct orientation before setting the trim, or holes
	
	Dim BoltHoleCol As ObjectCollection = oTO.CreateObjectCollection
	Dim BoltPointCol As ObjectCollection = oTO.CreateObjectCollection 'This object collection holds the primary sketch object we create the hole from. 
		BoltPointCol.Add(BoltAngleLine.EndSketchPoint)	
			
	Dim BoltHoleDef As HolePlacementDefinition, BoltHole As HoleFeature 'The objects that make up the defintion and application of the bolt hole on the object
	Dim BoltCirPatDef As CircularPatternFeatureDefinition, BoltCirPat As CircularPatternFeature
							
'	Try						
				
					BoltHoleDef = oCompDef.Features.HoleFeatures.CreateSketchPlacementDefinition(BoltPointCol)
					
					BoltHole = oCompDef.Features.HoleFeatures.AddDrilledByThroughAllExtent(BoltHoleDef, FittingNameInput & "_Bolt_Dia", Inventor.PartFeatureExtentDirectionEnum.kSymmetricExtentDirection)	'AddDrilledByDistanceExtent2(BoltHoleDef, Bolt_Dia * 2.54, "6 in", Inventor.PartFeatureExtentDirectionEnum.kNegativeExtentDirection)			'AddDrilledByToFaceExtent2(BoltHoleDef, FittingNameInput & "_Bolt_Dia", FlangeRevolve.Faces.Item(4), True)
					
						FlangeCol.Add(FlangeRevolve.SurfaceBodies.Item(1))					
					
						BoltHole.SetAffectedBodies(FlangeCol)
						
						BoltHoleCol.Add(BoltHole)
						
				DisplayTimer(iWatch, "Bolt hole created", PreviousTime)		
						
					BoltCirPatDef = oCompDef.Features.CircularPatternFeatures.CreateDefinition(BoltHoleCol, CenterFittingAxis, True, FittingNameInput & "_Num_Of_Bolts", "360")
						BoltCirPatDef.ComputeType = Inventor.PatternComputeTypeEnum.kOptimizedCompute
					
					BoltCirPat = oCompDef.Features.CircularPatternFeatures.AddByDefinition(BoltCirPatDef)

				DisplayTimer(iWatch, "Bolt and pattern created", PreviousTime)	 
									
'	Catch Err As Exception 
'		Call ReportError("Unable to create bolt hole or bolt pattern", Err, FittingTransaction)			
'	End Try									
			
	'Start the creation of the tank hole. 
	Dim TankCutExtDef As ExtrudeDefinition, TankCutExt As ExtrudeFeature
	
	Dim InnerCirCol As ObjectCollection = oTO.CreateObjectCollection	
	
'					Try									
										
							InnerCirCol.Add(InnerCircle) 'Add the circle cut sketch object to be used.
								
							Dim TankHoleProfile As Profile = GusBoltSketch.Profiles.AddForSolid(False, InnerCirCol)
							
							TankCutExtDef = oCompDef.Features.ExtrudeFeatures.CreateExtrudeDefinition(TankHoleProfile, Inventor.PartFeatureOperationEnum.kCutOperation)
								TankCutExtDef.SetDistanceExtent(24 * 2.54 , Inventor.PartFeatureExtentDirectionEnum.kNegativeExtentDirection)
						
							TankCutExt = oCompDef.Features.ExtrudeFeatures.Add(TankCutExtDef)
						
								TankCutExt.SetAffectedBodies(TankBodyCol)
										
							DisplayTimer(iWatch, "Tank hole created - Last time measurement before gussets", PreviousTime)	
							
'					Catch Err As Exception 
'						Call ReportError("Unable to cut tank hole", Err, FittingTransaction)			
'					End Try		
					
		Dim TankTrim As CombineFeature	
	
'		Try
			TankTrim = oCompDef.Features.CombineFeatures.Add(FlangeRevolve.SurfaceBodies.Item(1), InsideBodyCol, Inventor.PartFeatureOperationEnum.kCutOperation, True)
'		Catch Err As Exception 
'			Call ReportError("Failed to apply tank trim", Err, FittingTransaction)			
'		End Try	
		
			If Trim_Fitting_Tube = False Then 'Suppress trim if required.
				TankTrim.Suppressed = True
			End If 
			
			DisplayTimer(iWatch, "Trim to tank combine created", PreviousTime) 
	
	If Agitator_Flange = True Then 	'Create agitator flange if requested
		CreateAgiFlange(FittingNameInput, CenterFittingAxis, oUCS, CenterLine.EndSketchPoint, OutsideBodyCol)
	End If 		
	
			DisplayTimer(iWatch, "agitator flange or solids created.", PreviousTime)
			
	'Fitting item renames:
	FlangeSketch.Name = FittingNameInput & " Flange revolve sketch"
	CenterFittingAxis.Name = FittingNameInput & " Center axis"
	FlangeRevolve.Name = FittingNameInput & " Flange + tube revolve"
	FlangeRevolve.SurfaceBodies.Item(1).Name = FittingNameInput & " Fitting body"
	GussetPlane.Name = FittingNameInput & " Conical Gusset & bolt sketch plane (Do not edit)"	
	GusBoltSketch.Name = FittingNameInput & " Conical Gusset, tank hole, & bolthole sketch"
	TankCutExt.Name = FittingNameInput & " Tank hole - cut" 
	BoltHole.Name = FittingNameInput & " Bolt hole"
	BoltCirPat.Name = FittingNameInput & " Bolt circular pattern"
	
	TankTrim.Name = FittingNameInput & " Trim to tank (Suppress/Un-suppress)"
	oUCS.Name = FittingNameInput & " " & FlangeType & " UCS: " & FittingNameInput
	
DisplayTimer(iWatch, "Feature naming done", PreviousTime)	'The display timer that shows where we're going on the display stuff entirely.

	If Gusset_Type = "Conical" Or Gusset_Type = "Plate" Then 
		iLogicVb.RunRule("CREATE GUSSETS")
	End If 

	DisplayTimer(iWatch, "Gusset block", PreviousTime) 

		If Blind_Flange = True Then 
			iLogicVb.RunRule("CREATE BLIND")
		End If
			
	If FittingTransaction IsNot Nothing Then  
		FittingTransaction.End() 
	End If 		

	If Num_Of_Gus <> 4 Then 'Set the default number of gussets back to 4. 
		Num_Of_Gus = 4
	End If 

	Logger.Info("End of program: " & iWatch.Elapsed.ToString)

End Sub   

 

0 Likes
Message 4 of 5

JhoelForshav
Mentor
Mentor

@J_Pfeifer_ 
I don't know if there's that much you can do. The geometry generation takes time with complex geometric references.

One thing I noticed in your code is that you crate a UCS, attach geometry to it and then you re-orient it. That causes an extra regeneration that could be very heavy depending on how complex the geometry that reference it is. If you could have it correctly oriented before "building on it" it that would save some time. Other things like projections, if you dont actually need the projected geometry but only the positions, it could be optimized to instead just calculate the positions (Less geometry to re-evaluate/solve).

Also, calling external rules from within a rule, with SharedVariable etc is something that in my experience slow things down a bit. It spins up an extra rule context and I  believe it causes updates both on calling the rule and returning (But don't quote me on that, this is just a guess based on experience).

All and all I personally don't think a 10 second delay is terrible for generating geometry of this complexity. I'd assume you still save a lot of time compared to doing it manually 😉 But these are the things I noticed that you could look over in order to shave some time off if you feel like it's worth your time.

Message 5 of 5

WCrihfield
Mentor
Mentor

I tend to agree with most of that too.  There are still many opportunities within the last code example you posted to reduce API calls, and a few minor code layout/formatting things that could be changed a bit, but not sure if they would make a significant difference in processing time overall.  Any time you are stepping through Object.Property.Object.Property the same way on multiple lines, getting the lowest level common object or property value to a variable, then using that multiple times will cause less API calls, and therefore a little less processing.  But whether there are enough of those places in this code, where if they were updated, would make any noticeable difference, I'm not sure.  There may also be a few other settings that may make a difference in processing time.  For example, in the Document Settings of a Part file, on the Modeling tab, there are a couple settings which you may want to toggle on/off before &/or after your code routine (Link).  Those can also be reached by code, for convenience (ModelingSettings).  Then there are some settings at the Application Options level, such as the ones related to 'Physical Properties' on the 'General' tab (likely only relevant if saving), and certain other settings that update things visually, like the option on the Part tab for displaying extended information after feature node name in browser, and some of the stuff on the Display tab.  But if screen updating is turned off, that may negate most of that stuff.

I have also noticed minor differences in processing time when using alternate comparison techniques (like using the TypeOf operator) instead of using some of the built-in Enums.  One example is the DocumentTypeEnum.  I have found it is faster to use TypeOf comparison vs DocumentTypeEnum for determining document type.  I'm sure there are other similar minor interactions like that with similar results.  It all requires testing & review to determine which ones may be 'worth it' though.  Sometimes we may sacrifice processing speed for 'readability', where appropriate, depending on the need/situation.

 

Minor layout/formatting tweaks like changing this (and similar):

Dim FlangeIDDim As DimensionConstraint, FlangeFaceODDim As DimensionConstraint, FlangeHeadThickDim As DimensionConstraint, FlangeThickDim As DimensionConstraint, FlangePlaceDim As DimensionConstraint, FittingDisDim As DimensionConstraint

 to this:

Dim FlangeIDDim, FlangeFaceODDim, FlangeHeadThickDim, FlangeThickDim, FlangePlaceDim, FittingDisDim As DimensionConstraint

...but doing so likely has little or no noticeable performance difference.  Declaring multiple variables in one line like this does not necessarily 'reset' their values, if used in a 'loop' scenario, where declaring them on separate lines and setting their values to Nothing would reset them, if needed, at the cost of a longer code.  Usually not an issue at all if variables are declared in their proper context (only within the inner-most block of code they are being used within).

Wesley Crihfield

EESignature

(Not an Autodesk Employee)