I am trying to activate a DesignViewRepresentation in an iLogic rule in a drawing. The rule creates individual views per part for export to DXF. Here is the relevant code...
Dim oDrawDoc As DrawingDocument = ThisApplication.ActiveDocument
'Get the active sheet.
Dim oSheet As Sheet = oDrawDoc.ActiveSheet
'Get the views on the active sheet.
Dim oDwgView As DrawingView
Dim oDwgViews As DrawingViews = oSheet.DrawingViews
'Get the number of original views on the drawing for use later.
Dim oNoOGViews As Integer = oDwgViews.Count
Dim oDocDesc As DocumentDescriptor
'Cycle through all the drawings to check if each is of an assembly.
For Each oDwgView In oDwgViews
oDocDesc = oDwgView.ReferencedDocumentDescriptor
'Verify that the selected drawing view is of an assembly.
If oDocDesc.ReferencedDocumentType <> kAssemblyDocumentObject Then
MessageBox.Show("All views must be of an assembly.")
Exit Sub
End If
Next
'Get the component definition for the assembly.
Dim oAsmCompDef As AssemblyComponentDefinition = oDocDesc.ReferencedDocument.ComponentDefinition
Dim oAsm As AssemblyDocument = oAsmCompDef.Parent
'Gets the total number of occurrences in the assembly file.
Dim oOccurrences As ComponentOccurrences = oAsmCompDef.Occurrences
Dim oOcc As ComponentOccurrence
Dim oTotalOcc As Integer = oOccurrences.Count
Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
'Creates progress bar as a dialogue box.
Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oDwgViews.Count, "Color Conversion Process", False)
oProgressBar.UpdateProgress
'Cycle through all the drawings to create independent views with a single occurrence in each.
'This step gets the drawing style, drawing center position and view style from the originally placed view.
For Each oDwgView In oDwgViews
'Progress bar message and update.
oProgressBar.Message = "Step 1 of 2: Creating Separate Views For Each Component"
oProgressBar.UpdateProgress
'Checks is current view is a section or detail view. If view is a section or detail view, it will skip creating independent views for each component.
If oDwgView.Type = kSectionDrawingViewObject Or oDwgView.Type = kDetailDrawingViewObject Then
GoTo Line15
End If
Dim oDwgStyle As DrawingViewStyleEnum
Dim oDwgScale As Double
Dim oPosition As Point2d
Dim oOrientation As ViewOrientationTypeEnum
Dim oTangentEdges As Boolean
oDwgStyle = oDwgView.ViewStyle
If oDwgStyle = kFromBaseDrawingViewStyle Then
oDwgStyle = oDwgViews.Item(1).ViewStyle
End If
oDwgScale = oDwgView.Scale
oPosition = oTG.CreatePoint2d(oDwgView.Position.X, oDwgView.Position.Y)
oOrientation = kArbitraryViewOrientation
oTangentEdges = True
'Finds the current Design View Representation of the assembly and use it to place the new views.
Dim oDesRep As String
Dim oRep As DesignViewRepresentation
oDesRep = oDwgView.DesignViewRepresentation
If oDesRep = "" Then
oDesRep = "Master"
End If
oRep = oAsmCompDef.RepresentationsManager.DesignViewRepresentations.Item(oDesRep)
oRep.Activate
It fails on oRep.Activate with "Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))"
What makes this stranger is that it works on some machines and not others with exact same file. This worked in Inventor 2021 on all our machines. We upgraded to 2024.3 last week and are struggling with this iLogic.
Any suggestions or insights would be helpful. Thank you.
Solved! Go to Solution.
Solved by WCrihfield. Go to Solution.
Hi,
Try this code, hope it helps you!
Dim oDrawDoc As DrawingDocument = ThisApplication.ActiveDocument 'Get the active sheet. Dim oSheet As Sheet = oDrawDoc.ActiveSheet 'Get the views on the active sheet. Dim oDwgView As DrawingView Dim oDwgViews As DrawingViews = oSheet.DrawingViews 'Get the number of original views on the drawing for use later. Dim oNoOGViews As Integer = oDwgViews.Count Dim oDocDesc As DocumentDescriptor 'Cycle through all the drawings to check if each is of an assembly. For Each oDwgView In oDwgViews oDocDesc = oDwgView.ReferencedDocumentDescriptor 'Verify that the selected drawing view is of an assembly. If oDocDesc.ReferencedDocumentType <> kAssemblyDocumentObject Then MessageBox.Show("All views must be of an assembly.") Exit Sub End If Next 'Get the component definition for the assembly. Dim oAsmCompDef As AssemblyComponentDefinition = oDocDesc.ReferencedDocument.ComponentDefinition Dim oAsm As AssemblyDocument = oAsmCompDef.Parent 'Gets the total number of occurrences in the assembly file. Dim oOccurrences As ComponentOccurrences = oAsmCompDef.Occurrences Dim oOcc As ComponentOccurrence Dim oTotalOcc As Integer = oOccurrences.Count Dim oTG As TransientGeometry = ThisApplication.TransientGeometry 'Creates progress bar as a dialogue box. Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oDwgViews.Count, "Color Conversion Process", False) oProgressBar.UpdateProgress 'Cycle through all the drawings to create independent views with a single occurrence in each. 'This step gets the drawing style, drawing center position and view style from the originally placed view. For Each oDwgView In oDwgViews Dim ITest As Integer = 0 'Dim o2dTry As Boolean = False Try oDrawDoc.Activate oSheet.Activate Catch End Try 'Progress bar message and update. oProgressBar.Message = "Step 1 of 2: Creating Separate Views For Each Component" oProgressBar.UpdateProgress 'Checks is current view is a section or detail view. If view is a section or detail view, it will skip creating independent views for each component. If oDwgView.Type = kSectionDrawingViewObject Or oDwgView.Type = kDetailDrawingViewObject Then 'GoTo Line15 Continue For End If Dim oDwgStyle As DrawingViewStyleEnum Dim oDwgScale As Double Dim oPosition As Point2d Dim oOrientation As ViewOrientationTypeEnum Dim oTangentEdges As Boolean oDwgStyle = oDwgView.ViewStyle If oDwgStyle = kFromBaseDrawingViewStyle Then oDwgStyle = oDwgViews.Item(1).ViewStyle End If oDwgScale = oDwgView.Scale oPosition = oTG.CreatePoint2d(oDwgView.Position.X, oDwgView.Position.Y) oOrientation = kArbitraryViewOrientation oTangentEdges = True 'Finds the current Design View Representation of the assembly and use it to place the new views. Dim oDesRep As String Dim oRep As DesignViewRepresentation = Nothing oDesRep = oDwgView.DesignViewRepresentation If oDesRep = "" Then oDesRep = "Master" End If ONEMORE: Try oRep = oAsmCompDef.RepresentationsManager.DesignViewRepresentations.Item(oDesRep) Catch End Try If oRep Is Nothing Then MsgBox("Couldn't get the Rep. View: " & oDesRep) Continue For End If 'Maybe you need to have the Assembly document loaded or Activated to switch the views Try oRep.Activate Catch End Try If oAsmCompDef.RepresentationsManager.ActiveDesignViewRepresentation.Name <> oDesRep Then If ITest = 0 Then ITest = ITest + 1 oAsm = ThisApplication.Documents.Open(oAsm.FullDocumentName, True) 'Dim o2dTry As Boolean = True GoTo ONEMORE End If End If Next
This did not work. It caused a couple of issues. First it brings the assembly document to the "front" and causes the rule to stop with errors because the drawing is no longer the active document. It also causes an issue later in the script in a section of code that I did not provide that unsupresses views that have been created as the rule progresses.
Here is the full rule code as working in 2021.
Class ComponentViewColors
Public oTangentHiddenLinesBoolean As Boolean
Public oApp As Inventor.Application = ThisApplication
'This program is used on assembly drawings. For each view in the drawing, each model occurrence is placed in its own drawing view, in the same location
'relative to the other components in the base view. The color of the curves in the individual occurrence view will change to match that of the model
'color. Since the views of these occurrences will be independent of any other part in the assembly, the visible and invisible lines will react accordingly.
'Each visible line and hidden line for each color will be placed in its own layer and will be named according to the RGB color value. This
'drawing file can then be manually exported into a DXF file for further manipulation.
Public Sub Main()
'Version 1.14 08JUN20
'Call UserForm_Hidden_Tangent_Edges.Show
Dim question As DialogResult = MessageBox.Show("Do you want hidden tangent edges shown?", "Hidden Tangent Edges", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
If question = vbYes Then
oTangentHiddenLinesBoolean = True
ElseIf question = vbNo Then
oTangentHiddenLinesBoolean = False
Else
Exit Sub
End If
Dim oDrawDoc As DrawingDocument = ThisApplication.ActiveDocument
'Get the active sheet.
Dim oSheet As Sheet = oDrawDoc.ActiveSheet
'Get the views on the active sheet.
Dim oDwgView As DrawingView
Dim oDwgViews As DrawingViews = oSheet.DrawingViews
'Get the number of original views on the drawing for use later.
Dim oNoOGViews As Integer = oDwgViews.Count
Dim oDocDesc As DocumentDescriptor
'Cycle through all the drawings to check if each is of an assembly.
For Each oDwgView In oDwgViews
oDocDesc = oDwgView.ReferencedDocumentDescriptor
'Verify that the selected drawing view is of an assembly.
If oDocDesc.ReferencedDocumentType <> kAssemblyDocumentObject Then
MessageBox.Show("All views must be of an assembly.")
Exit Sub
End If
Next
'Get the component definition for the assembly.
Dim oAsmCompDef As AssemblyComponentDefinition = oDocDesc.ReferencedDocument.ComponentDefinition
Dim oAsm As AssemblyDocument = oAsmCompDef.Parent
'Gets the total number of occurrences in the assembly file.
Dim oOccurrences As ComponentOccurrences = oAsmCompDef.Occurrences
Dim oOcc As ComponentOccurrence
Dim oTotalOcc As Integer = oOccurrences.Count
Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
'Creates progress bar as a dialogue box.
Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oDwgViews.Count, "Color Conversion Process", False)
oProgressBar.UpdateProgress
'Cycle through all the drawings to create independent views with a single occurrence in each.
'This step gets the drawing style, drawing center position and view style from the originally placed view.
For Each oDwgView In oDwgViews
'Progress bar message and update.
oProgressBar.Message = "Step 1 of 2: Creating Separate Views For Each Component"
oProgressBar.UpdateProgress
'Checks is current view is a section or detail view. If view is a section or detail view, it will skip creating independent views for each component.
If oDwgView.Type = kSectionDrawingViewObject Or oDwgView.Type = kDetailDrawingViewObject Then
GoTo Line15
End If
Dim oDwgStyle As DrawingViewStyleEnum
Dim oDwgScale As Double
Dim oPosition As Point2d
Dim oOrientation As ViewOrientationTypeEnum
Dim oTangentEdges As Boolean
oDwgStyle = oDwgView.ViewStyle
If oDwgStyle = kFromBaseDrawingViewStyle Then
oDwgStyle = oDwgViews.Item(1).ViewStyle
End If
oDwgScale = oDwgView.Scale
oPosition = oTG.CreatePoint2d(oDwgView.Position.X, oDwgView.Position.Y)
oOrientation = kArbitraryViewOrientation 'oDwgView.Camera.ViewOrientationType
oTangentEdges = True 'Set to always show tangent edges in new view since they will be placed in their own layers. Option to match drawing sytle, use oDwgView.DisplayTangentEdges
'Finds the current Design View Representation of the assembly and use it to place the new views.
Dim oDesRep As String
Dim oRep As DesignViewRepresentation
oDesRep = oDwgView.ActiveDesignViewRepresentation
If oDesRep = "" Then
oDesRep = "Master"
End If
oRep = oAsmCompDef.RepresentationsManager.DesignViewRepresentations.Item(oDesRep)
oRep.Activate
'Finds the current Positional Representation of the assembly and use it to place the new views.
Dim oPosRep As String = oDwgView.ActivePositionalRepresentation
'Finds the current Level of Detail Representation of the assembly and use it to place the new views.
Dim oLODRep As String = oDwgView.ActiveLevelOfDetailRepresentation
Dim oNewView As DrawingView
Dim oBaseViewOptions As NameValueMap
'Cycles through each occurrence and places a new view with the settings retrieved from the main view.
'Initial check if occurrence is a sub-assembly in the main assembly. Also checks is the current component
'occurrence is not visible. If not visible, the step to create the independent component view is skipped.
For j = 1 To oTotalOcc
oOcc = oAsmCompDef.Occurrences.Item(j)
oVisible = oOcc.Visible
If oOcc.Suppressed = True Then
GoTo Line10
End If
If oVisible = False Then
GoTo Line10
End If
'If occurrence is a sub-assembly, this part will run to bring in the view of the sub-assembly component.
If oOcc.DefinitionDocumentType = kAssemblyDocumentObject Then
Dim oSubAsmCompDef As AssemblyComponentDefinition
Dim oSubAsm As AssemblyDocument
Dim oOccSub As ComponentOccurrence
Dim oOccurrencesSub As ComponentOccurrences
Dim oSubCount As Integer
'Sets sub-assembly as new assembly file.
oSubAsm = oOcc.Definition.Document
oSubAsmCompDef = oSubAsm.ComponentDefinition
oSubCount = oOcc.Definition.Occurrences.Count
Dim h As Integer
For h = 1 To oSubCount
oBaseViewOptions = ThisApplication.TransientObjects.CreateNameValueMap
Call oBaseViewOptions.Add("DesignViewAssociative", False)
Call oBaseViewOptions.Add("PositionalRepresentation", oPosRep)
Call oBaseViewOptions.Add("LevelofDetailRepresentation", oLODRep)
oNewView = oSheet.DrawingViews.AddBaseView(oAsm, oPosition, oDwgScale, oOrientation, oDwgStyle, oDesRep, oDwgView.Camera, oBaseViewOptions)
oNewView.DisplayTangentEdges = oTangentEdges
oNewView.ViewJustification = kFixedViewJustification
oNewView.Suppressed = True 'Suppress newly created view. To be unsuppresses and updated once all views are created. Used to speed up overall process.
'This sets the visibility of the all the model occurrences in the main assembly, except the active occurrence in the main assembly
'("j"), which will be the sub-assembly, to false or hidden and leaves only the active model in the view.
Dim n As Integer
For n = 1 To oTotalOcc
If n <> j Then
oOcc = oAsmCompDef.Occurrences.Item(n)
If oOcc.Suppressed = True Then
GoTo Line20
End If
oNewView.SetVisibility(oOcc, False)
End If
Line20:
Next n
'This sets the visibility of the all the model occurrences in the sub-assembly, except the active occurrence in the sub-assembly
'("h") to false or hidden and leaves only the active model in the view. Must create a ComponentOccurrence Proxy for the sub-assembly
'occurrence to bring it in the context of the main assembly. If assembly is a weldment, the weldbead feature of the weldment will
'skipped. If a weld is created in the assembly, it will show up in a component's individual view and can be deleted in AutoCAD.
'Created weldbead features will not take on the color of the model feature, but will be the default color.
Dim p As Integer
For p = 1 To oSubCount
If p <> h Then
Dim oOccSubProxy As ComponentOccurrenceProxy
oOccSub = oSubAsmCompDef.Occurrences.Item(p)
If oOccSub.Suppressed = True Or oOccSub.Name = "_Weldbead:1" Then
GoTo Line25
End If
If oAsmCompDef.Occurrences.Item(j).Suppressed = True Then
GoTo Line25
End If
Call oAsmCompDef.Occurrences.Item(j).CreateGeometryProxy(oOccSub, oOccSubProxy)
oNewView.SetVisibility(oOccSubProxy, False)
End If
Line25:
Next p
Next h
GoTo Line10 'Will contintue to the next "j", which will be the next occurrence in the main assembly.
End If
'Code to add view if occurrence is not an assembly.
'Dim oNewView As DrawingView
oBaseViewOptions = ThisApplication.TransientObjects.CreateNameValueMap
Call oBaseViewOptions.Add("DesignViewAssociative", False)
Call oBaseViewOptions.Add("PositionalRepresentation", oPosRep)
Call oBaseViewOptions.Add("LevelofDetailRepresentation", oLODRep)
oNewView = oSheet.DrawingViews.AddBaseView(oAsm, oPosition, oDwgScale, oOrientation, oDwgStyle, oDesRep, oDwgView.Camera, oBaseViewOptions)
oNewView.DisplayTangentEdges = oTangentEdges
oNewView.ViewJustification = kFixedViewJustification
oNewView.Suppressed = True 'Suppress newly created view. To be unsuppresses and updated once all views are created. Used to speed up overall process.
'This sets the visibility of the all the model occurrence, except the active occurrence ("j") to false or hidden and leaves only the active model in the view.
'Dim n As Integer
For n = 1 To oTotalOcc
If n <> j Then
oOcc = oAsmCompDef.Occurrences.Item(n)
If oOcc.Suppressed = False Then
oNewView.SetVisibility(oOcc, False)
End If
End If
Next n
Line10:
Next j
'Suppresses the original view as it is no longer needed.
oDwgView.Suppressed = True
Line15:
Next
'Unsuppress all created single component views. Force view updates of all views in the document prior to calling the color change command. This step is necessary as the program will not
'exeute the change color command if the views are not updated (in raster mode). To decrease time process runs creating and updating views on the fly.
'oApp.DoEvents
'Gets updated number of views on a sheet. Used with number of original views to only unsuppress newly created views.
Dim oNoViews As Integer
oNoViews = oDwgViews.Count
Dim v As Integer
For v = (oNoOGViews + 1) To oNoViews
oDwgView = oSheet.DrawingViews.Item(v)
oDwgView.Suppressed = False
Next v
oDrawDoc.Update
'oApp.DoEvents
'Close Progress Bar for Step 1.
oProgressBar.Close
Call Drawing_Colors
'Perform Save Copy As of the drawing and translates it to a DXF file.
Dim oAsmFullPath As String
Dim oAsmFullName As String
Dim oDXFFullPath As String
Dim oNewFileExtension As String
oAsmFullPath = oAsm.File.FullFileName
oAsmFullName = Left$(oAsmFullPath, InStrRev(oAsmFullPath, ".") - 1)
oNewFileExtension = ".dxf"
oDXFFullPath = oAsmFullName & oNewFileExtension
Call oDrawDoc.SaveAs(oDXFFullPath, True)
End Sub
'This subfunction is taken from the Drawing Colors programs and iterates through all views and changes all the curves of each model to match
'the color of the actual model.
Private Sub Drawing_Colors()
'Get the active drawing document.
Dim oDrawDoc As DrawingDocument = ThisApplication.ActiveDocument
'Get the active sheet.
Dim oSheet As Sheet = oDrawDoc.ActiveSheet
'Get the views on the active sheet.
Dim oDrawView As DrawingView
Dim oDrawViews As DrawingViews = oSheet.DrawingViews
oDrawDoc.MakeAllViewsPrecise
Dim oHiddenLineView As Boolean
For Each oDrawView In oDrawViews
If oDrawView.ViewStyle = kHiddenLineDrawingViewStyle Then
oHiddenLineView = True
GoTo Line10
End If
Next
Line10:
'Creates progress bar as a dialogue box.
Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oDrawViews.Count, "Color Conversion Process", False)
For Each oDrawView In oDrawViews
'Progress bar message and update.
oProgressBar.Message = "Step 2 of 2: Moving Components to Layers"
oProgressBar.UpdateProgress
'Get the component definition for the assembly.
Dim oDocDesc As DocumentDescriptor = oDrawView.ReferencedDocumentDescriptor
Dim oAsmDef As AssemblyComponentDefinition = oDocDesc.ReferencedDocument.ComponentDefinition
'Call the recursive function that does all the work.
Call ProcessAssemblyColor(oDrawView, oAsmDef.Occurrences)
Next
'Close Progress Bar for Step 2.
oProgressBar.Close
'Message box to confirm the color change has been completed. Also, allows for Inventor to populate layer selections with newly created layers.
Dim oSave As Integer
oSave = MsgBox("Color conversion complete. Press Yes to automatically export the drawing as a DXF file in the same directory as this drawing. Press No to end the program and manually export the drawing to another format.", vbYesNo, "Operation Complete")
If oSave = vbNo Then
Exit Sub
End If
End Sub
'Fucntion that creates the layers that correspond to the model color and the drawing has hidden lines on.
Private Sub ProcessAssemblyColor(oDrawView As DrawingView, oOccurrences As ComponentOccurrences)
'Iterate through the current collection of occurrences.
Dim oOcc As ComponentOccurrence
For Each oOcc In oOccurrences
If oOcc.Suppressed = True Then
GoTo Line30
End If
'Check to see if this occurrence is a part or assembly.
If oOcc.DefinitionDocumentType = kPartDocumentObject Then
'Get the TransientsObjects object to use later.
Dim oTransObjs As TransientObjects = ThisApplication.TransientObjects
'Verify that a layer exists for this color.
Dim oLayers As LayersEnumerator = oDrawView.Parent.Parent.StylesManager.Layers
Dim oDrawDoc As DrawingDocument = oDrawView.Parent.Parent
On Error Resume Next
'Get the diffuse color for the render style.
Dim Red As Byte
Dim Green As Byte
Dim Blue As Byte
'Gets the color of the first face of the occurrence and applies this to the line colors (and layer names).
Dim oPart As PartDocument = ThisApplication.Documents.Open(oOcc.Definition.Document.FullFileName, False)
Dim oPartDef As PartComponentDefinition = oPart.ComponentDefinition
Dim oFaces As Faces = oPartDef.SurfaceBodies.Item(1).Faces
Dim oFace As Face = oFaces.Item(1)
Dim ColorSource As StyleSourceTypeEnum
Dim oRenderStyle As RenderStyle = oFace.GetRenderStyle(ColorSource)
Call oRenderStyle.GetAmbientColor(Red, Green, Blue)
'Call oColor.GetAmbientColor(Red, Green, Blue) No longer vaild. This gets the RGB valve of the color name property.
'Get the base name of the file and use that for the layer names.
Dim value As String
Dim oDocFullPath As String
Dim Temp As String
oDocFullPath = oPart.FullFileName
Temp = Right$(oDocFullPath, Len(oDocFullPath) - InStrRev(oDocFullPath, "\")) 'File name with extension.
value = Left$(Temp, InStrRev(Temp, ".") - 1) 'Base name (file name w/o extension)
'Sets the name of the layers as RGB values that match the RGB values of the line color. Creates layers for visible, hidden, tangent and hidden tangent lines.
'Layer names will now reflect the file name, not color.
'If the set is empty, the layer will not be saved in the dxf file.
Dim oColorLayerSolid As Layer
Dim oColorLayerHidden As Layer
Dim oColorLayerTanSolid As Layer
Dim oColorLayerTanHidden As Layer
oColorLayerSolid = oLayers.Item(value & " Visible")
oColorLayerHidden = oLayers.Item(value & " Hidden")
oColorLayerTanSolid = oLayers.Item(value & " Tangent")
If oTangentHiddenLinesBoolean = True Then
oColorLayerTanHidden = oLayers.Item(value & " Hidden Tangent")
End If
'If layer name already exists, this skips to the section to get associated curves and places them in the correct layer instead of
'creating a layer with the same name.
If Err.Number <> 0 Then
On Error GoTo Line25
'Create a color object that is the diffuse color.
'Call oColor.GetDiffuseColor(Red, Green, Blue) No longer vaild. This gets the RGB valve of the color name property.
Call oRenderStyle.GetDiffuseColor(Red, Green, Blue)
Dim oNewColor As Color = oTransObjs.CreateColor(Red, Green, Blue)
'Copy an arbitrary layer giving it the name of the part (render style(RGB value)).
oColorLayerSolid = oLayers.Item(1).Copy(value & " Visible")
oColorLayerHidden = oLayers.Item(2).Copy(value & " Hidden")
oColorLayerTanSolid = oLayers.Item(3).Copy(value & " Tangent")
If oTangentHiddenLinesBoolean = True Then
oColorLayerTanHidden = oLayers.Item(4).Copy(value & " Hidden Tangent")
End If
'Get the attributes of the layer to use the color, have a solid or hidden line type, and a specific width.
oColorLayerSolid.Color = oNewColor
oColorLayerSolid.LineType = kContinuousLineType
oColorLayerSolid.LineWeight = 0.05
oColorLayerHidden.Color = oNewColor
oColorLayerHidden.LineType = kDashedHiddenLineType
oColorLayerHidden.LineWeight = 0.036
oColorLayerTanSolid.Color = oNewColor
oColorLayerTanSolid.LineType = kContinuousLineType
oColorLayerTanSolid.LineWeight = 0.05
If oTangentHiddenLinesBoolean = True Then
oColorLayerTanHidden.Color = oNewColor
oColorLayerTanHidden.LineType = kDashedHiddenLineType
oColorLayerTanHidden.LineWeight = 0.036
End If
End If
On Error GoTo 0
Line25:
'Get all of the curves associated with this occurrence.
On Error Resume Next
Dim oDrawCurves As DrawingCurvesEnumerator = oDrawView.DrawingCurves(oOcc)
If Err.Number = 0 Then
On Error GoTo 0
'Create an empty collection.
Dim oObjCollSolid As ObjectCollection
Dim oObjCollHidden As ObjectCollection
Dim oObjCollTanSolid As ObjectCollection
Dim oObjCollTanHidden As ObjectCollection
oObjCollSolid = oTransObjs.CreateObjectCollection()
oObjCollHidden = oTransObjs.CreateObjectCollection()
oObjCollTanSolid = oTransObjs.CreateObjectCollection()
If oTangentHiddenLinesBoolean = True Then
oObjCollTanHidden = oTransObjs.CreateObjectCollection()
End If
'Add the curve segments to the collection.
Dim oDrawCurve As DrawingCurve
For Each oDrawCurve In oDrawCurves
Dim oSegment As DrawingCurveSegment
If oTangentHiddenLinesBoolean = True Then
For Each oSegment In oDrawCurve.Segments
If oSegment.Layer.Name = "Visible Tangent Edges(ANSI)" Then
oObjCollTanSolid.Add(oSegment)
ElseIf oSegment.Layer.Name = "Hidden Tangent Edges(ANSI)" Then
oObjCollTanHidden.Add(oSegment)
ElseIf oSegment.HiddenLine = False Then
oObjCollSolid.Add(oSegment)
ElseIf oSegment.HiddenLine = True Then
oObjCollHidden.Add(oSegment)
End If
Next
Else
For Each oSegment In oDrawCurve.Segments
If oSegment.Layer.Name = "Visible Tangent Edges(ANSI)" Then
oObjCollTanSolid.Add(oSegment)
ElseIf oSegment.Layer.Name = "Hidden Tangent Edges(ANSI)" Then
'Makes Hidden Tangent Edges not visible so they will not get processed and not get added to an object collection and a layer.
oSegment.Visible = False
ElseIf oSegment.HiddenLine = False Then
oObjCollSolid.Add(oSegment)
ElseIf oSegment.HiddenLine = True Then
oObjCollHidden.Add(oSegment)
End If
Next
End If
Next
'Change the layer of all of the segments.
Call oDrawView.Parent.ChangeLayer(oObjCollSolid, oColorLayerSolid)
Call oDrawView.Parent.ChangeLayer(oObjCollHidden, oColorLayerHidden)
Call oDrawView.Parent.ChangeLayer(oObjCollTanSolid, oColorLayerTanSolid)
If oTangentHiddenLinesBoolean = True Then
Call oDrawView.Parent.ChangeLayer(oObjCollTanHidden, oColorLayerTanHidden)
End If
End If
On Error GoTo 0
Else
'It's an assembly so process its contents.
Call ProcessAssemblyColor(oDrawView, oOcc.SubOccurrences)
End If
Line30:
Next
End Sub
End Class
Good point about the DVR name.
There is also another area in the early portion of the code that seemed a little risky also.
In Lines 18 through Line 30...
You create a variable for the DocumentDescriptor before the loop of all views, and set its value once per view within that loop. If every view is not referencing the main assembly directly, then that could cause problems later in your code (starting at Lines 29 & 30, onwards). Maybe just set its value once, using the first view on the sheet, instead of for every view, but not sure about how you do your drawings. That variable will retain the last value assigned to it within that loop.
Then at Line 29, you should declare your Document variable first, then set that with DocumentDescriptor.ReferencedDocument. Then on Line 30, declare its ComponentDefinition, then set that with Document.ComponentDefinition. The ReferencedDocument property returns an Object, so it is always good to have an already declared Document type variable to capture its value, then go from there. Just good practice, and order of operations.
Wesley Crihfield
(Not an Autodesk Employee)
I have updated that section of code to this...
Dim oDocDesc As DocumentDescriptor = oDwgViews.Item(1).ReferencedDocumentDescriptor
'Cycle through all the drawing views to check if each is of an assembly.
For Each oDwgView In oDwgViews
'Verify that the selected drawing view is of an assembly.
If oDwgView.ReferencedDocumentDescriptor.ReferencedDocumentType <> kAssemblyDocumentObject Then
MessageBox.Show("All views must be of an assembly.")
Exit Sub
End If
'Verify that the selected drawing view is of an assembly.
If oDwgView.ReferencedDocumentDescriptor IsNot oDocDesc Then
MessageBox.Show("All views must be of the same assembly")
Exit Sub
End If
Next
'Get the component definition for the assembly.
Dim oAsmCompDef As AssemblyComponentDefinition = oDocDesc.ReferencedDocument.ComponentDefinition
Dim oAsm As AssemblyDocument = oAsmCompDef.Parent
Since the rest of the script acts on only one single Component Definition, I made sure that it is the definition of the first view, and that only that assembly is referenced in any view. I did also change the name assignment.
If oDesRep = "" Then
oDesRep = "[Primary]"
End If
I also noticed that the original code is looking for oDwgView.ActiveDesignViewRepresentation which does not appear to be a property of DrawingView (anymore?) so I changed that line to
oDesRep = oDwgView.DesignViewRepresentation
But I have the same issue.
In my code (extra comments everywhere) Line 130 is
oRep.Activate
I thought originally that this might be due to there being 2 DVRs (1 "hidden?" kTransientDesignViewType) that has the same name "[Primary]" and it having trouble assigning oRep with
oRep = oAsmCompDef.RepresentationsManager.DesignViewRepresentations.Item(oDesRep)
But I am no longer sure about that. There are no other DVRs present and even if I create am additional one, I have the same issue.
Activating an active view?
Check if View is active first. If not, activate it.
First I tried
if oAsmCompDef.RepresentationsManager.ActiveDesignViewRepresentation IsNot oRep Then oRep.Activate
When comparing the ActgiveDesignViewRepresentation with oRep, I learned that the oRep is the actual DVR and the ActiveDVR is the Transient one. They technically do not match as the type is different. I then compared them by name using
if not (oAsmCompDef.RepresentationsManager.ActiveDesignViewRepresentation.Name = oDesRep) Then oRep.Activate
This seems to have worked for the [Primary] DVR, but as soon as I add a new DVR in the assembly and create a view of that DVR, it fails again at the oRep.Activate on that line above.
Hi @tfrohe_LSI. Try capturing the DVR's collection to a variable. Then use that variable like...
oDVRs.Item("DVRName").Activate
...instead of...
oRep.Activate
...That way you are working with its name, instead of the object itself. Avoids the 'transient' thing that way.
Edit: You may also want to capture the RepresentationsManager object itself to a variable also, ahead of time, that way you can just use something like:
oRepsMgr.ActiveDesignViewRepresentation
(shorter line of code to get to / check that property later). Just suggestions.
Wesley Crihfield
(Not an Autodesk Employee)
I've updated the code to
'oRep = oAsmCompDef.RepresentationsManager.DesignViewRepresentations.Item(oDesRep)
Dim oReps As DesignViewRepresentations = oAsmCompDef.RepresentationsManager.DesignViewRepresentations
if not (oAsmCompDef.RepresentationsManager.ActiveDesignViewRepresentation.Name = oDesRep) Then oReps.Item(oDesRep).Activate
and get the same error
It does work if the view is DVR [Primary]. if the first view is anything else, it fails to activate the DVR. If a second view is of another DVR, it fails when it gets to that view.
Another interesting thing I am seeing. If I run the activate method from a macro in the assembly document, it works fine. for example.
Dim oApp As Application
Set oApp = ThisApplication
Dim oDoc As AssemblyDocument
Set oDoc = oApp.ActiveDocument
Dim oCompDef As ComponentDefinition
Set oCompDef = oDoc.ComponentDefinition
Call oCompDef.RepresentationsManager.DesignViewRepresentations.Item("No cap").Activate
Activates the view fine without error.
So it seems like this issue in the drawing is about activating the DVR from within the context of the drawing? Am I interpreting this correctly?
I am also thinking that maybe the activate itself is working but something that happens after activate but before my next line of code (behind the scenes, as it were) is causing the error. I suspect this because if I add
On Error Resume Next
the script runs and seems to output what we expect it to as all views are processed. I feel like this is a band-aid and have not yet done enough testing to confirm that it is actually working to the same output as it did in 2021.
I am thoroughly confused by this issue at this point. I have attached the current script version with the changes mentioned in this thread. Thoughts?
Hi @tfrohe_LSI. One possibly out there thought that comes to mind is that maybe your assembly, if it is a regular one (not an iAssembly), may have more than its one original/default ModelState in it (named "[Primary]"). If so, then it may be possible that at times you are encountering a ModelState member version of the assembly. If that is the case, then it would act like a ReadOnly document. You would be able to browse through it just fine, but when you try to change something in it, such as activating a different DVR, it will throw an error. If so, there are ways around this, but the code starts getting more complicated. When any model file (part or assembly) has 2 or more ModelStates in it, then there will be one 'factory' document, and at least one 'member' document. The factory is simply the document that is associated with whichever ModelState happens to be 'active' at that time. Then the member documents will be the ones associated with any other ModelStates that are not currently 'active'. The factory version will be fully Read/Write, while the member versions will act like ReadOnly. The exception to this behavior is when you have the 'member edit scope' set to factory scope or all members scope, instead of active member only scope. Or, when editing the ModelStateTable, which contains all of them in one table.
In situations where we are working on a document directly (it is the one actively visible on our screen), and we want our code to be acting upon that document (not some other document referenced within it), it can often be easy to automatically be working with the 'factory' version, but it is not guaranteed. We do have an iLogic snippet for making sure we start out working with the factory document (ThisDoc.FactoryDocument), which is OK for at the start of a rule, but is not always ideal to use down in the middle of a rule. In the middle of a rule that may be iterating through multiple ModelStates, or referenced documents, there are other ways to either get a reference to the factory version document, or force the member version you have a reference for to become the factory version, by activating the ModelState that it is associated with. Also sometimes when moving from one referenced document to another where multiple ModelStates may be involved, we sometimes need to update the referenced document before we can work with it, if we previously made changes to another ModelState version of that same file. I know, it can be a lot to learn and account for.
Wesley Crihfield
(Not an Autodesk Employee)
The particular document I am working with right now, and for the duration of this thread, does have 2 model states. "[Primary]" and "STRAIGHT". STRAIGHT has not been activated at all as far as i know and all of my DVRs were created while the [Primary] model state was active. The current edit scope of the assembly (not iAssembly) is currently editing [Primary].
So from the drawing, how do I know which document is active, Factory or Member? and how do we force it to one or the other?
Based on everything, at this point, i feel like the entire script needs to be rewritten due to the model state changes introduced in 2022. The fact that it works on some PC's with no changes from the original (which still has "Master") is still stuck in my mind here. I remember studying java and having junk data in declared, but not initialized, variables. this feels like that to me. It's the only thing I can relate it to from past experience.
I did not write the original version and there has been no updates to it since 2020. I am a hobbyist at best when it comes to programming but have been able to write some interesting scripts and an addon for my company. I feel like this is just above me and I can't quite grasp it. This has been a frustrating week for me.
Code it to check for "Master" and "[Primary]" if it need to work with different version IV.
In a drawing, only the drawing is "active document".
All other are referenced by the drawing.
You can get reference from View, BOM.
https://help.autodesk.com/view/INVNTOR/2023/ENU/?guid=GUID-D273D9C3-C24F-4CDD-B571-F2C0B5F7A5B3
To set DVR in drawing View, use: DrawingView.SetDesignViewRepresentation
https://help.autodesk.com/view/INVNTOR/2023/ENU/?guid=GUID-FD420D73-071E-4A94-B1CA-6C5514B9F457
Don't try to change DVR in assembly. Just get DVR names from the assembly and change DVR in each View.
Hi @tfrohe_LSI. What @Frederick_Law just mentioned is very true. If starting from a drawing, and you only need to change the drawing view(s) to show a different DVR version of the same assembly it is already referencing, then you can just change the view itself to a different DVR directly. Same goes for ModelStates...if the drawing view is set to one ModelState, but you want it to be set to a different ModelState, then there is a built-in method for that also.
DrawingView.ActiveModelState (ReadOnly String)
DrawingView.SetActiveModelState (Sub routine)
And if you need to change both the ModelState of the view, and the DVR of the view, then you should always change its ModelState first, then its DVR second.
However, when starting from the assembly itself (it is showing on your screen when you start the code), and that assembly has 2 or more ModelStates in it, and you want to make sure you are working with the factory version, then there are a few options. If in an iLogic rule, I would recommend using the 'ThisDoc.FactoryDocument' property to obtain your original reference to that assembly's factory document. If elsewhere (in VBA macro or an add-in), then the 'ThisDoc' term will not be recognized. So go ahead and use the 'ThisApplication.ActiveDocument' phrase, but then we will use additional lines of code to make sure we have the factory document. Within the AssemblyComponentDefinition we have a couple properties we can use for this.
AssemblyComponentDefinition.IsModelStateMember (ReadOnly Boolean)
AssemblyComponentDefinition.IsModelStateFactory (ReadOnly Boolean)
AssemblyComponentDefinition.FactoryDocument (ReadOnly, returns Document object, but might not return anything if there are not 2 or more ModelStates present.
We can use these like this:
If oADoc.ComponentDefinition.IsModelStateMember = True Then
oADoc = oADoc.ComponentDefinition.FactoryDocument
End If
...to reset the value of our initial AssemblyDocument variable to the new value, so that it will now represent the factory document. Or, you could declare a different variable before this block of code, like oFactoryDoc, then set its value within that block of code. If super curious, you can even compare the initial variable with the new variable afterwards, using 'Is' comparison (not =).
Another think to be aware of when ModelStates are involved is the Document.FullDocumentName property. Sometimes, when multiple ModelStates are involved, this property's value will start with the FullFileName value, but then immediately after the file extension will be something like "<ModelStateMemberName>", which tells us which version we are working with. The "ModelStateMemberName" portion will be the real name of the ModelState, not just that text shown here. There are also ways to separate the FullFileName portion from the ModelState member name portion, using FileManager.GetFullFileName method and FileManager.GetModelStateName method. Then there is this one: FileManager.GetLastActiveModelState. And when iterating through referenced documents, you can use the ThisApplication.Documents.Open() method, where you specify the FullDocumentName, and capture the Document object it returns to your variable, to use later, and it will ensure you are working with the factory document (if there is one). Just some additional tips for the road ahead.
Wesley Crihfield
(Not an Autodesk Employee)
@Frederick_Law @WCrihfield Thank you both for your replies. It was indeed model states that were causing my issues. I have updated the code to detect the appropriate model state.
Can't find what you're looking for? Ask the community or share your knowledge.