I am trying to make a function that delete all appearances from a display state. I have tryed many things and I am blocked at many places in the way.
From what I understand there are basically 2 possible ways to do it (see below code and explanations of everything I did for both ways). If anybody has experience with those functions, a piece of working code or tips for me, it would be greatly appreciated because I am really stucked right now. See also screenshots of one of the assemblies I am working with below.
First way : Using DeleteDisplayStateSpecificRenderMaterial
The first way is using the DeleteDisplayStateSpecificRenderMaterial function :
ModelDocExtension.DeleteDisplayStateSpecificRenderMaterial( ByVal PWMaterialId1 As System.Object, ByVal PWMaterialId2 As System.Object )
Using this way, I face 2 problems.
The first problem is to get the ids of the appearances (iRenderMaterial interface if I understand well). When I use the following code, I get very inconsistent results accessing the RenderMaterial objects. Meaning that I never get all the appearances contained in the assembly. In assemblies that contains many appearances for many components, sometimes I can not access any rendermaterial object, sometimes I can access a few, but I never get them all.
'ModelAsm is a valid ModelDoc2 object containing an assembly model
Dim swModelDocExt As ModelDocExtension
Dim displayStateNames(0) As String
Dim renderMaterials As Object
Dim nbRenderMaterials As Integer
swModelDocExt = ModelAsm.Extension
displayStateNames(0) = "Display State-1"
'using GetRenderMaterialsCount2 gives inconsistent results, for any of the 3 syntaxes below.
'In assemblies that contains many appearances, I sometimes get 0,
'sometimes another number, but never the appearance count that I can see under the appearance tab in SolidWorks
nbRenderMaterials = swModelDocExt.GetRenderMaterialsCount2(swDisplayStateOpts_e.swAllDisplayState, Nothing)
nbRenderMaterials = swModelDocExt.GetRenderMaterialsCount2(swDisplayStateOpts_e.swSpecifyDisplayState, displayStateNames)
nbRenderMaterials = swModelDocExt.GetRenderMaterialsCount2(swDisplayStateOpts_e.swThisDisplayState, Nothing)
'here I can access the the number of rendermaterial that was returned using the corresponding GetRenderMaterialsCount2 syntax above
renderMaterials = swModelDocExt.GetRenderMaterials2(swDisplayStateOpts_e.swAllDisplayState, Nothing)
renderMaterials = swModelDocExt.GetRenderMaterials2(swDisplayStateOpts_e.swSpecifyDisplayState, displayStateNames)
renderMaterials = swModelDocExt.GetRenderMaterials2(swDisplayStateOpts_e.swThisDisplayState, Nothing)
The second problem is using the DeleteDisplayStateSpecificRenderMaterial function. The function returns true (as if it was a success), but It does not appear in the assembly, even after a rebuild or saving, closing and re-opening the file. I tryed to use it in 2 ways.
First way (delete all render materials at once)
Dim tbool As Boolean
Dim iMat As RenderMaterial
Dim iMatID1 As Integer
Dim iMatID2 As Integer
Dim MatsIDs1(0 To nbRenderMaterials - 1) As Integer
Dim MatsIDs2(0 To nbRenderMaterials - 1) As Integer
For i = 0 To nbRenderMaterials - 1
iMat = renderMaterials(i)
iMat.GetMaterialIds(iMatID1, iMatID2)
MatsIDs1(i) = iMatID1
MatsIDs2(i) = iMatID2
Next
tbool = swModelDocExt.DeleteDisplayStateSpecificRenderMaterial(MatsIDs1, MatsIDs2)
'Here, tbool is true (as if it was a success), but the appearances are not deleted in SolidWorks
Second way, delete rendermaterials one by one
Dim tbool As Boolean
Dim iMat As RenderMaterial
Dim iMatID1 As Integer
Dim iMatID2 As Integer
Dim MatsIDs1(0) As Integer
Dim MatsIDs2(0) As Integer
For i = 0 To nbRenderMaterials - 1
iMat = renderMaterials(i)
iMat.GetMaterialIds(iMatID1, iMatID2)
MatsIDs1(0) = iMatID1
MatsIDs2(0) = iMatID2
tbool = swModelDocExt.DeleteDisplayStateSpecificRenderMaterial(MatsIDs1, MatsIDs2)
'Here, tbool is true (as if it was a success), but the appearances are not deleted in SolidWorks
Next
Second way : Looping trough components
Here the idea is to loop trough components and delete their applied appearances as answered by Alexandre Gragnano in this post : https://forum.solidworks.com/message/776101#comment-776101
Here is my adaptation in vb.net (and looping trough components). I also tried the original macro shown in the post, but without success (did not delete anything)
Sub DeleteAllColors2(ModelAsm As ModelDoc2, Optional DisplayStateName As String = "")
Dim vConfigName As Object = ModelAsm.GetConfigurationNames
Dim swConfMgr As ConfigurationManager = ModelAsm.ConfigurationManager
Dim swConf As Configuration = swConfMgr.ActiveConfiguration
Dim swRootComp As Component2 = swConf.GetRootComponent3(True)
Dim swModelDocExt As ModelDocExtension = ModelAsm.Extension
Dim tbool As Boolean
'recursive search returns all the component2 objects (all components and child components included in the assembly
Dim FrameList As List(Of Component2) = recursiveSearch(swRootComp, AddressOf isTrue)
For Each iFrame As Component2 In FrameList
'here, I tried both RemoveMaterialProperty2 and RemoveTextureByDisplayState functions.
'value returned by both functions is always false and nothing happen in SolidWorks
tbool = iFrame.RemoveMaterialProperty2(swInConfigurationOpts_e.swAllConfiguration, Nothing)
tbool = iFrame.RemoveTextureByDisplayState(DisplayStateName)
Next
ModelAsm.GraphicsRedraw2()
End Sub
Screenshots of the assembly