许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  SW二次开发一键清除装配体零件外观可靠实现

SW二次开发一键清除装配体零件外观可靠实现

阅读数 7
点赞 0
article_banner


适用版本:SOLIDWORKS 2018 及以上(VBA 宏)风险提示:本文涉及的操作会修改模型显示属性,建议操作前备份文件。


一、问题背景

在 SOLIDWORKS 日常建模与装配过程中,模型颜色混乱是一个高频痛点。颜色来源往往分散在多个层级,难以追溯:

  • 面级别(Face Appearance):直接赋色到某个面
  • 特征级别(Feature Appearance):赋色到拉伸、切除等特征
  • 实体级别(Body Appearance):赋色到某个实体(多实体零件)
  • 零件级别(Part Appearance):赋色到整个零件
  • 组件级别(Component Appearance):在装配体中对某个组件赋色(覆盖零件级颜色)
  • 显示状态(Display State):通过不同显示状态管理外观组合
  • 材质颜色(Material):由材质定义的基础颜色

最终结果是:同一个零件在不同装配层级、不同显示状态下呈现不同颜色,严重影响模型评审和出图效率。



二、外观层级的正确理解

SOLIDWORKS 的外观系统采用分层覆盖机制,优先级从高到低依次为:面(Face)→ 特征(Feature)→ 实体(Body)→ 零件(Part)→ 组件(Component)→ 材质(Material)

关键认知:

  1. Display State 不是覆盖层级,而是外观的"容器"。一个 Display State 可以包含上述所有层级的外观设置。删除 Display State 不等于删除外观,只是切换了外观组合。
  2. Component 外观存储在装配体文件中,而非零件文件。这意味着:即使清除了零件文件中的外观,装配体中的组件覆盖色仍然存在。
  3. Material 颜色是最底层 fallback,当所有上层外观都被移除后,模型会恢复为材质定义的颜色。


三、方案设计:为什么不能用 Select + Delete?

许多初学者会尝试用 SelectByID2 + EditDelete 来删除外观,但这种方式存在明显风险:

  • 可能误选并删除特征(Feature)或实体(Body)
  • 选择过滤器在不同 SOLIDWORKS 版本间行为不一致
  • 无法批量处理,效率低下

正确思路:通过官方 API 直接操作外观对象,避免任何选择-删除操作。



四、核心 API 说明

4.1 PartDoc.RemoveAllDisplayStates

这是零件文档的方法,官方描述为:

Removes all display states and appearances from this part document.

行为:删除零件中所有 Display State,并创建一个无外观的默认 Display State。这会同时清除面、特征、实体、零件级别的外观。

⚠️ 注意:

  • 这是一个破坏性操作——会删除用户自定义的所有 Display State(如爆炸视图对应的显示状态)。
  • 它不会清除装配体中对本零件的组件级外观覆盖。

4.2 装配体中的组件外观

装配体中组件的外观覆盖需要通过 Component2 或 AssemblyDoc 的相关 API 处理。由于组件外观存储在装配体文件内部,遍历组件时不能简单调用 comp.GetModelDoc2 后处理其 PartDoc——那样修改的是零件文件本身,而非装配体中的覆盖。



五、完整代码(修订版)

以下代码针对原文进行了以下修正:

  1. 补充了实体(Body)级别外观的清除
  2. 修正了装配体递归逻辑,区分"零件文件清理"与"装配体组件覆盖清理"
  3. 增加了 Lightweight 组件检测
  4. 增加了错误处理
  5. 代码块
  6. vba

  7.      自动换行
       

  8.      复制代码
       
  9. 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
Option Explicit

'========================
' 常量定义(确保低版本兼容)
'========================
Const swDocPART AsLong=1
Const swDocASSEMBLY AsLong=2

'========================
' 主入口
'========================
Sub ClearAllAppearances()

Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel IsNothingThen
        MsgBox "请先打开一个零件或装配体文件。", vbExclamation
ExitSub
EndIf

Dim docType AsLong
    docType = swModel.GetType

SelectCase docType

Case swDocPART
' 清理当前零件的所有外观
            ClearPartAllAppearances swModel

Case swDocASSEMBLY
' 清理装配体:包括组件覆盖 + 递归清理子零件/子装配
            ClearAssemblyAllAppearances swModel

CaseElse
            MsgBox "仅支持零件(.sldprt)和装配体(.sldasm)文件。", vbExclamation
ExitSub

EndSelect

    swModel.EditRebuild3
    swModel.GraphicsRedraw2

    MsgBox "外观清理完成。建议保存文件以保留更改。", vbInformation

EndSub

'========================
' 零件级:清除所有外观(面/特征/实体/零件/Display State)
'========================
Sub ClearPartAllAppearances(ByVal swModel As SldWorks.ModelDoc2)

If swModel IsNothingThenExitSub

Dim swPart As SldWorks.PartDoc
Set swPart = swModel

OnErrorResumeNext

' 方法1:RemoveAllDisplayStates — 清除零件内所有层级的外观
' 注意:这会删除所有自定义 Display State!
    swPart.RemoveAllDisplayStates

OnErrorGoTo0

' 方法2(备选):如果 RemoveAllDisplayStates 不满足需求,
' 可以遍历 Body 并调用 RemoveMaterialProperty 做更细粒度控制
' 以下代码演示如何单独清除 Body 级别外观:
'
' Dim vBodies As Variant
' Dim swBody As SldWorks.Body2
' Dim vConfigNames As Variant
' vConfigNames = swModel.GetConfigurationNames
'
' vBodies = swPart.GetBodies2(swSolidBody, True)
' If Not IsEmpty(vBodies) Then
'     Dim i As Long
'     For i = 0 To UBound(vBodies)
'         Set swBody = vBodies(i)
'         swBody.RemoveMaterialProperty swAllConfiguration, vConfigNames
'     Next i
' End If

EndSub

'========================
' 装配体级:递归清理
'========================
Sub ClearAssemblyAllAppearances(ByVal swModel As SldWorks.ModelDoc2)

If swModel IsNothingThenExitSub

Dim swAssy As SldWorks.AssemblyDoc
Set swAssy = swModel

' 获取顶层组件(包含所有层级)
Dim vComps AsVariant
    vComps = swAssy.GetComponents(True)

If IsEmpty(vComps)ThenExitSub

Dim i AsLong
Dim swComp As SldWorks.Component2
Dim swCompModel As SldWorks.ModelDoc2

For i =0To UBound(vComps)

Set swComp = vComps(i)
If swComp IsNothingThenGoTo NextComponent

' 跳过被压缩的组件
If swComp.GetSuppression2 = swComponentSuppressed ThenGoTo NextComponent

' 跳过轻化模式组件(轻化模式下无法获取完整模型数据)
If swComp.GetSuppression2 = swComponentLightweight Then
            Debug.Print "跳过轻化组件: "& swComp.Name2
GoTo NextComponent
EndIf

Set swCompModel = swComp.GetModelDoc2
If swCompModel IsNothingThenGoTo NextComponent

' 根据组件类型分别处理
SelectCase swCompModel.GetType

Case swDocPART
' 对零件文件本身清理外观
                ClearPartAllAppearances swCompModel

Case swDocASSEMBLY
' 对子装配递归处理
                ClearAssemblyAllAppearances swCompModel

EndSelect

' ⚠️ 重要说明:
' 上述操作清理的是零件/子装配文件内部的外观。
' 如果装配体中对组件有 Component Appearance 覆盖,
' 需要额外通过 AssemblyDoc 或 Component2 的 API 清除。
' 目前 SOLIDWORKS API 中直接移除 Component Appearance 的方法有限,
' 常见做法是通过 DisplayManager 或 Selection + RemoveAppearance 处理。

NextComponent:
Next i

EndSub

      复制成功
     
     
     
     


六、技术要点与局限性

6.1 本文方案的覆盖范围

外观层级

是否可清除

说明

Face

✅

通过 RemoveAllDisplayStates 清除

Feature

✅

通过 RemoveAllDisplayStates 清除

Body

✅

通过 RemoveAllDisplayStates 清除(或单独遍历 Body)

Part

✅

通过 RemoveAllDisplayStates 清除

Component(装配体覆盖)

⚠️ 部分

RemoveAllDisplayStates 在装配体中仅清除组件级外观,但本文递归逻辑主要操作的是零件文件本身

Material

❌

材质颜色不会被移除,模型会恢复为材质默认色

6.2 已知局限

  1. Display State 丢失:RemoveAllDisplayStates 会删除所有自定义 Display State。如果项目中使用了多个 Display State(如爆炸视图、简化表示),请谨慎使用。
  2. 装配体组件覆盖:装配体中对组件单独赋色的 Component Appearance,其存储位置在装配体文件内部。本文代码通过递归清理零件文件,不会自动清除这些覆盖。如需完全清理,建议在装配体中手动使用"移除所有组件外观"功能。
  3. 轻化组件:轻化(Lightweight)模式下无法获取组件完整模型数据,代码会自动跳过。建议先将轻化组件还原为还原模式(Resolved)后再运行宏。
  4. 文件修改:递归处理会修改子零件/子装配的原始文件。如果文件受 PDM 管理,可能需要先检出(Check Out)。

6.3 为什么必须递归?

装配体结构是树状的:

顶层装配体

├── 子装配体 A │   ├── 零件 1 │   └── 零件 2 └── 子装配体 B     └── 零件 3

如果不递归处理,只能清理当前装配层级,子装配体及其内部零件的颜色完全不会变化。



七、适用场景

  • 导入外部模型后颜色混乱,需要统一归零
  • 多人协作导致外观不统一,需要批量重置
  • 装配体评审前统一视觉风格
  • PDM 模型整理,清除历史遗留外观
  • 出图前标准化处理,避免颜色干扰工程图表达


八、扩展方向

基于本文代码,可以进一步扩展为:

  • 标准化上色工具:按零件名称、BOM 层级或自定义属性自动分类赋色
  • PDM 批量清理:结合 SOLIDWORKS PDM API,实现文件夹级批量处理
  • 选择性清理:增加用户界面,允许选择清理哪些层级(仅 Face / 仅 Part / 全部)
  • 插件化:封装为 SOLIDWORKS 插件(Add-in),集成到工具栏或右键菜单


九、总结

SOLIDWORKS 外观问题的本质是多层级覆盖导致的显示状态不一致。解决思路应当遵循:

  1. 理解层级:明确 Face → Feature → Body → Part → Component → Material 的优先级关系
  2. 区分存储位置:零件级外观在 .sldprt 中,组件覆盖在 .sldasm 中
  3. 使用官方 API:避免 Select + Delete 的不稳定操作
  4. 谨慎使用 RemoveAllDisplayStates:意识到它会删除所有 Display State,属于破坏性操作

本文提供的代码是一个基础且可靠的起始版本,适用于大多数"一键归零"场景。如需更精细的控制(如保留某些 Display State、仅清除特定层级),建议在此基础上结合 RenderMaterial、DisplayStateSetting 等 API 进行二次开发。



免责声明:本文代码仅供学习和参考,运行前请备份原始文件。作者不对因使用本文代码导致的文件损坏或数据丢失承担责任。

免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空