Assign surface body to layer

Assign surface body to layer

DewayneH
Advocate Advocate
548 Views
9 Replies
Message 1 of 10

Assign surface body to layer

DewayneH
Advocate
Advocate

I have a rule that assigns lines of surfaces to the phantom layer. It looks like it actually changes any curves that are not solid geometry.

We've been using it for several years and it works great except we've just discovered it produces an error on save if there is a section view.

I believe it has something to do with the sketch for the section. There is nothing in the code to handle the entity.

 

When the rule is ran explicitly nothing happens to the curves in the section view.

However, the rule is set to run before save and produces the error. Still the curves are not changed.

This is the error on save:

DewayneH_1-1714047928617.png

 

How could an exception be added to address the section sketch?

I'd welcome any improvements to fix the issue or future proof.

 

Here is the existing code:

Dim doc As DrawingDocument
doc = ThisDoc.Document

Dim oDC As DrawingCurve
Dim oDCS As DrawingCurveSegment

For Each oDC In doc.Sheets(1).DrawingViews(1).DrawingCurves
	For Each oDCS In oDC.Segments
		If Not oDCS.Parent.ModelGeometry.Parent.IsSolid Then
			oDCS.Layer = doc.StylesManager.Layers.Item(9)
		End If
	Next
Next

 

 

 

Dewayne
Inventor Pro 2023
Vault Pro 2023
0 Likes
549 Views
9 Replies
Replies (9)
Message 2 of 10

WCrihfield
Mentor
Mentor

Hi @DewayneH.  Looks like you may need to break this down into more lines of code, and check a few more things along the way.  The DrawingCurve.ModelGeometry property returns an 'Object' type for a good reason...because it may be Nothing, or it may be several other types of objects, in different situations.  Obviously in this situation it is finding a DrawingSketch as its value.  Below is a more detailed version of your code that you may like.  It still does not break down that one long line of code which gets the DrawingCurvesEnumerator into more lines of code, but I did add a bit of protection in there for that one too, just to help avoid some of the potential errors.  You may want to include some 'feedback' in there in a couple places, where it writes some stuff to the iLogic Log window when something unexpected happens (catches/handles an error), for more information though.

Dim doc As DrawingDocument = ThisDoc.Document

Dim oDCEnum As DrawingCurvesEnumerator = Nothing
Try : oDCEnum = doc.Sheets(1).DrawingViews(1).DrawingCurves : Catch : End Try
If oDCEnum Is Nothing OrElse oDCEnum.Count = 0 Then Return
Dim oLayer As Inventor.Layer = Nothing
Try : oLayer = doc.StylesManager.Layers.Item(9) : Catch : End Try
If oLayer Is Nothing Then Return
Dim oDC As DrawingCurve
Dim oDCSs As DrawingCurveSegments
Dim oDCS As DrawingCurveSegment
Dim oMGeom As Object
Dim oSBody As SurfaceBody

For Each oDC In oDCEnum
	oMGeom = Nothing : oMGeom = oDC.ModelGeometry
	If (oMGeom Is Nothing) OrElse _
		(TypeOf oMGeom Is SurfaceBody = False) Then
		Continue For
	End If
	oSBody = Nothing : oSBody = oMGeom
	If oSBody.IsSolid = False Then Continue For
	oDCSs = Nothing: oDCSs = oDC.Segments
	If oDCSs Is Nothing OrElse oDCSs.Count = 0 Then Continue For
	For Each oDCS In oDCSs
		oDCS.Layer = oLayer
	Next
Next

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 3 of 10

DewayneH
Advocate
Advocate

Thanks @WCrihfield for looking into it.

I tested the rule. The error is gone, but unfortunately the surface geometry in section view didn't update to the phantom layer.

 

I'm no expert so I'll have to look into adding the feedback you suggested.

Any further suggestions?

 

 

Dewayne
Inventor Pro 2023
Vault Pro 2023
0 Likes
Message 4 of 10

WCrihfield
Mentor
Mentor

Hi @DewayneH.  Sorry about that.  It looks like I got the 'IsSolid' check backwards on Line 22 while editing the code on my end.  Sometimes reading the 'Not' keyword at the beginning of a line is trickier to read than ' = Fasle' near the end.

 

I reworked the code with more feedback in it this time, and reversed the IsSolid check back to the way you had it.  Unfortunately, it is a lot more difficult setting all those drawing curves back to their default state after making these kinds of changes to them.  For that reason, I incorporated an extra tool in this new version to help some with that little detail (a Transaction).  The Transaction will bundle all those layer change actions into one item in the UNDO list.  That way, if it did not turn out correct, it can all be undone in one or two clicks.

I hope this version works better for you.  Make sure your iLogic Log window is visible before starting the code, otherwise it will not capture any of the feedback.  But those 'Logger' lines could be replaced by MsgBox or MessageBox.Show type lines also, but you may want to comment some of them out, if you go that route.

Dim doc As DrawingDocument = ThisDoc.Document
Dim oSheet As Inventor.Sheet = doc.Sheets.Item(1)
Dim oViews As DrawingViews = oSheet.DrawingViews
If oViews.Count = 0 Then
	Logger.Debug("No Views On First Sheet!")
	Return
End If
Dim oView As DrawingView = oView.Item(1)

Dim oDCEnum As DrawingCurvesEnumerator = Nothing
Try : oDCEnum = oView.DrawingCurves : Catch : End Try
If oDCEnum Is Nothing OrElse oDCEnum.Count = 0 Then
	Logger.Debug("No DrawingCurves retrieved from view!")
	Return
End If

Dim oLayers As Inventor.LayersEnumerator = doc.StylesManager.Layers
Dim oLayer As Inventor.Layer = Nothing
'you can specify it by its 'internal name', instead of by number here, if you want.
Try : oLayer = oLayers.Item(9) : Catch : End Try
If oLayer Is Nothing Then
	Logger.Info("Specified Layer Not Found!")
	Return
Else
	Logger.Info("Name of Layer obtained = " & oLayer.Name)
End If

'start a Transaction to bundle all following actions into one item in the UNDO list
Dim oTrans As Inventor.Transaction
oTrans = ThisApplication.TransactionManager.StartTransaction(doc, "Change Layer Of Surfaces - iLogic")

For Each oDC As DrawingCurve In oDCEnum
	Dim oMGeom As Object = oDC.ModelGeometry
	If oMGeom Is Nothing Then
		Logger.Debug("DrawingCurve.ModelGeometry Is Nothing")
		Continue For
	End If
	Logger.Info("DrawingCurve.ModelGeometry Type = " & TypeName(oMGeom))
	Dim oSBody As SurfaceBody = Nothing
	If (TypeOf oMGeom Is Edge)
		Dim oEdge As Inventor.Edge = oMGeom
		oSBody = oEdge.Parent
	ElseIf (TypeOf oMGeom Is Face) Then
		Dim oFace As Inventor.Face = oMGeom
		oSBody = oFace.Parent
	End If
	If oSBody Is Nothing Then
		Logger.Debug("SurfaceBody Is Nothing")
		Continue For
	End If
	If oSBody.IsSolid = False Then
		Dim oDCSs As DrawingCurveSegments = oDC.Segments
		For Each oDCS As DrawingCurveSegment In oDCSs
			oDCS.Layer = oLayer
		Next 'oDCS
	End If 'end of 'IsSolid' check
Next 'oDC
oTrans.End 'ends the Transaction

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 5 of 10

DewayneH
Advocate
Advocate

Well, I run the new rule and encountered a different error...

"Object variable or With block variable not set."

I couldn't figure that one out.

I bet you already have an idea.

 

Dewayne
Inventor Pro 2023
Vault Pro 2023
0 Likes
Message 6 of 10

WCrihfield
Mentor
Mentor

Did the error message mention what Line of code the error happened at?  Was there anything in the iLogic Log window afterwards?  Any small additional information may help in figuring the problem out.  The error indicates that somewhere the code is attempting to use a variable in some way, but that variable has not been assigned a value yet.  When I quickly reviewed the code, I did not see anything obvious jump out at me.  The only place that comes to mind is maybe at Line 2.  Because, if Line 1 did not get a DrawingDocument, but some other type of Document, then the 'doc' variable would not be usable, and therefore Line 2 could not its 'Sheets' property from it.  This is part of why I usually start my codes off with a more complex document type check.  Only the DrawingDocument has a property named Sheets.

 

If the iLogic rule was an 'internal' one (saved within an Inventor document) then the 'ThisDoc.Document' phrase will usually focus on that document that the rule is located within, by default.  If the iLogic rule was an 'external' one, then that phrase will focus on whichever document happened to be visibly active on your screen when the rule started, by default.  If the rule was triggered to run by the Event Triggers dialog setting, on the 'This Document' tab, then that phrase will usually focus on the document that caused that event to be triggered.  It is pretty dynamic.

Maybe try replacing this:

Dim doc As DrawingDocument = ThisDoc.Document

with this:

Dim doc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
If doc Is Nothing Then
	Logger.Debug("Rule named '" & iLogicVb.RuleName & "' could not obtain a DrawingDocument!")
	Return
End If

If that does not fix it, and the error message does not indicate which Line the error happened at, and there was not anything in the iLogic Log window that may help, we may just try do go about this task in a completely different way.  Maybe instead of trying to figure out what type of object each individual drawing curve represents, we could get a reference to the model document through the view, then if it is a Part, get its SurfaceBodies (and possibly its WorkSurfaces) collection, then iterate through those directly, checking if they have any drawing curved representing them in that view, and if so, deal with them from that angle.  But, I'm not even sure if that part of the code is causing any problems at this point.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 7 of 10

DewayneH
Advocate
Advocate

Sorry. Yes it did indicate the line.

It was line 8...

Dim oView As DrawingView = oView.Item(1)

I may have figured out the cause of the error. I changed the line to the following and the error no longer occurs. Unfortunately, the geometry doesn't change to the phantom layer.

Dim oView As DrawingView = oViews.Item(1)

 

Dewayne
Inventor Pro 2023
Vault Pro 2023
Message 8 of 10

WCrihfield
Mentor
Mentor

Hi @DewayneH.  Just double checking the design intent here, but I just want to confirm what you want this rule to do.  I think you want this rule to get the first view, on the first sheet, and if any geometry exists within that view that is from a SurfaceBody that 'is not solid', you want that geometry to be put on this other 'phantom' layer, correct?  And you said it started having problems when it encountered a section view, due to the DrawingSketch it encountered, but only when the rule was triggered to run by the Event Triggers 'Before Save' event, right?  Section views can be odd, because they have a 'parent' view that they refer to.

 

Did you review the contents of the iLogic Log window after running the rules above?  It was supposed to be reporting what types of objects it was finding as the type of the DrawingCurve.ModelGeometry property value.  It might help to know what all types it has been finding.  I also want to make sure what type of model document that view is referencing.  It it always a part, directly, or is it sometimes an assembly, or a view of an assembly component with other assembly components visibly turned off?  Knowing these details may help solve the mystery, and help solve the problems.  I have been expecting the view to always be of a Part directly, not an assembly.  If it is for an assembly, that is a whole extra headache, requiring even more code and complication.  Then it may be finding assembly component type objects, and different types of proxies, instead of real part bodies.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 9 of 10

WCrihfield
Mentor
Mentor

Here is a very different example iLogic rule you can try out.  This one does things from the other side, gets the bodies / surfaces first, then checks if there is any geometry in the view for them, and if so, tries to put all that geometry on that layer.  But again, this is designed for encountering a part, not an assembly.

Sub Main
	Dim oDDoc As DrawingDocument = TryCast(ThisDoc.Document, Inventor.DrawingDocument)
	If oDDoc Is Nothing Then
		Logger.Debug("Rule named '" & iLogicVb.RuleName & "' could not obtain a DrawingDocument!")
		Return
	End If
	Dim oSheet As Inventor.Sheet = oDDoc.Sheets.Item(1)
	If oSheet IsNot oDDoc.ActiveSheet Then oSheet.Activate
	Dim oViews As DrawingViews = oSheet.DrawingViews
	If oViews.Count = 0 Then
		Logger.Debug("No Views On First Sheet!")
		Return
	End If
	Dim oView As DrawingView = oViews.Item(1)
	
	'<<< find / get / create the Layer we want to use before we go further in the code >>>
	Dim oLayers As Inventor.LayersEnumerator = oDDoc.StylesManager.Layers
	Dim oLayer As Inventor.Layer = Nothing
	'you can specify it by its 'internal name', instead of by number here, if you want.
	Try : oLayer = oLayers.Item(9) : Catch : End Try
	If oLayer Is Nothing Then
		Logger.Info("Specified Layer Not Found!")
		Return
	Else
		Logger.Info("Name of Layer obtained = " & oLayer.Name)
	End If

	'make sure the drawing is updated
	oDDoc.Update2(True)
	'make sure the sheet is updated
	oSheet.Update

	'start a Transaction to bundle all following actions into one item in the UNDO list
	Dim oTrans As Inventor.Transaction
	oTrans = ThisApplication.TransactionManager.StartTransaction(oDDoc, "Change Layer Of Surfaces - iLogic")

	'<<< get the Document being referencd within the drawing view >>>
	Dim oViewDoc As Inventor.Document = oView.ReferencedDocumentDescriptor.ReferencedDocument
	'<<< if it is a Part, then we can access its SurfaceBodies & WorkSurfaces directly >>>
	'<<< assemblies do not have these directly in them >>>
	If TypeOf oViewDoc Is PartDocument Then
		Dim oPDoc As PartDocument = oViewDoc
		Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
		'<<< get the bodies, iterate through them, find ones where 'IsSolid = False'
		Dim oBodies As SurfaceBodies = oPDef.SurfaceBodies
		If oBodies.Count > 0 Then
			For Each oBody As SurfaceBody In oBodies
				If oBody.IsSolid = False Then
					Dim oDCurves As DrawingCurvesEnumerator = Nothing
					Try : oDCurves = oView.DrawingCurves(oBody) : Catch : End Try
					If oDCurves Is Nothing OrElse oDCurves.Count = 0 Then Continue For
					For Each oDCurve As DrawingCurve In oDCurves
						Dim oDCSs As DrawingCurveSegments = oDCurve.Segments
						For Each oDCS As DrawingCurveSegment In oDCSs
							oDCS.Layer = oLayer
						Next 'oDCS
					Next 'oDCurve
				End If 'end of 'IsSolid' check
			Next 'oBody
		End If 'end of bodies count check
		'<<< get the WorkSurfaces, iterate through them, find view geometry, if any >>>
		Dim oWSurfaces As WorkSurfaces = oPDef.WorkSurfaces
		If oWSurfaces.Count > 0 Then
			For Each oWSurface As WorkSurface In oWSurfaces
				Dim oDCurves As DrawingCurvesEnumerator = Nothing
				Try : oDCurves = oView.DrawingCurves(oWSurface) : Catch : End Try
				If oDCurves Is Nothing OrElse oDCurves.Count = 0 Then Continue For
				For Each oDCurve As DrawingCurve In oDCurves
					Dim oDCSs As DrawingCurveSegments = oDCurve.Segments
					For Each oDCS As DrawingCurveSegment In oDCSs
						oDCS.Layer = oLayer
					Next 'oDCS
				Next 'oDCurve
			Next 'oWSurface
		End If 'end of oWSurfaces count check
	Else 'what to do if the drawing's view is referencing an assembly, instead of a Part
		Logger.Info("The first view on the first sheet if referencing an Assembly, not a Part.")
		'if you need it to work here too, a much larger block of code would be needed
		'assemblies do not directly contain any SurfaceBody objects, or WorkSurfaces
		'you would have to iterate through every assembly component, possibly at every level
	End If 'end of view document type check
	oSheet.Update
	oDDoc.Update2(True)
	oTrans.End 'ends the Transaction
End Sub

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 10

DewayneH
Advocate
Advocate

The intent is to move surface body geometry to the phantom layer in all drawing views.

This is only used for parts. 

 

I checked the log window on the previous rules and it reports:

Name of Layer obtained = Phantom

DrawingCurve.ModelGeometry Type = Edge.

 

I ran the latest rule provided but again unfortunately, it changes the edges on all views except the section view. It remains unaffected.

 

The log reports:

Name of Layer obtained = Phantom

That's it.

 

Dewayne
Inventor Pro 2023
Vault Pro 2023
0 Likes