二.搭建一个Taskpane的SolidWorks插件

二.搭建一个Taskpane的SolidWorks插件

SolidWorks插件-将SolidWorks文件转换为gltf格式
  • 一.SolidWorks文件转换为glTF格式
  • 二.搭建一个Taskpane的SolidWorks插件
  • 三.获取SolidWorks文件中的网格信息
  • 四.获取SolidWorks中的材质信息
  • 五.转换为glTF格式
  • 六.装配体和多实体格式的转换
  • 去Github查看代码或下载插件安装包
  • 虽然可以在另存为选项中扩展gltf功能,但为了在SolidWorks界面上显而易见,我选择了添加一个TaskPane界面。

    2.新建一个带TaskPane的SolidWork插件

    使用SolidWors自带SwCSharpAddin模板建立一个SolidWorks插件,关于如何找到这个模板可以在看我的另一篇文章。

    2.1 新建一个名未DuSwToglTF的插件
    2.2 去掉和按钮有关的代码
    2.3 添加一个名为Convert.xaml的WPF用户控件.注意添加关于WPF的类库引用

    System.xaml;WindowsBase;WindowsFormsIntegration;PresentationCore;PresentionFramework;

  • 将UI Methods区域代码删除,并添加AddTaskPanel()方法
  •         #region UI Methods
            private void AddTaskPanel()
                    //DuSwToglTF.ConvertPanel.PreloadDlls();
                    ITaskpaneView pTaskPanView;
                    pTaskPanView = iSwApp.CreateTaskpaneView2((ConvertPanel.RootPath+"\\"+ "gltf.bmp"), "将Solidworks文件转换为glTF");
                    if (TaskPanelControl == null)
                        SwAddin.TaskPanelControl = new ConvertPanel(SwApp);
                        eleHost.Child = TaskPanelControl;
                    pTaskPanView.DisplayWindowFromHandlex64(eleHost.Handle.ToInt64());
                catch (Exception ex)
                    SwApp.SendMsgToUser(ex.ToString());
            #endregion
    

    这段代码首先定义了一个TaskpaneView对象,然后通过ISldworks创建了一个TaskpaneView对象。紧接着实例化了一个WPF的用户控件,
    此处使用的一个ElementHost来作为WPF界面的容器。此方面的介绍可以查看Winform与WPF的互操作性。最后调用DisplayWindowFromHandlex64方法显示了这个WPF控件,ToInt64()方法传递了一个指针给SolidWorks以便SolidWorks显示。

    2.4 在ConnectToSW方法中调用AddTaskPanel()
            public bool ConnectToSW(object ThisSW, int cookie)
                iSwApp = (ISldWorks)ThisSW;
                addinID = cookie;
                //Setup callbacks
                iSwApp.SetAddinCallbackInfo(0, this, addinID);
                #region 添加Taskpane
                AddTaskPanel();
                #endregion
                #region Setup the Event Handlers
                SwEventPtr = (SolidWorks.Interop.sldworks.SldWorks)iSwApp;
                openDocs = new Hashtable();
                AttachEventHandlers();
                #endregion
                return true;
    

    3.使用WPF做一个转换界面

    接下来我们需要设计一下UI来实现我们的功能

    3.1 安装必要nuget库
  • MVVMLight来实现MVVM模式
  • HandyControl 来美化UI
  • 使用HandyControl注意在xaml文件中引用命名空间

                 xmlns:hc="https://handyorg.github.io/handycontrol"
    

    并添加资源字典

    <UserControl.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
                    <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </UserControl.Resources>
    
    3.2 添加类 ConvertPanelViewModel.cs
    namespace DuSwToglTF
        public class ConvertPanelViewModel:GalaSoft.MvvmLight.ViewModelBase
    
    3.3 设计界面--完整的xaml文件如下
    <UserControl x:Class="DuSwToglTF.ConvertPanel"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:DuSwToglTF"
                 mc:Ignorable="d"              
                 xmlns:hc="https://handyorg.github.io/handycontrol"
                TextElement.FontWeight="Medium"
                TextElement.FontSize="10"
                FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"             
              d:DesignHeight="600" d:DesignWidth="300">
        <UserControl.Resources>
            <ResourceDictionary>
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
                    <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </UserControl.Resources>
        <TabControl>
            <TabItem>
                <TabItem.Header>
                    <Image Source="pack://application:,,,/DuSwToglTF;component/Resources/Main.png" Width="16" Height="16"></Image>
                </TabItem.Header>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="340"/>
                        <RowDefinition Height="16"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0,0,-0.4,0">
                        <StackPanel Grid.Row="0" Margin="0" Grid.RowSpan="2">
                            <GroupBox Margin="0,10"  ToolTip="Save Path">
                                <GroupBox.Header >
                                    <Label>保存路径</Label>
                                </GroupBox.Header>
                                <Grid  Margin="0,10">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="43*"/>
                                        <RowDefinition Height="50"/>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="79*"/>
                                        <ColumnDefinition Width="21*"/>
                                    </Grid.ColumnDefinitions>
                                    <TextBox Text="{Binding FileName}"></TextBox>
                                    <Label Grid.Row="0" Grid.Column="1" ToolTip="FileName">文件名</Label>
                                    <TextBox Text="{Binding FilePath}" Grid.Column="0" Margin="2,10"  Grid.Row="1"/>
                                    <Button Grid.Column="1" Command="{Binding ChoosePathCommand}" Content="..." Margin="0,10" Height="30" ToolTip="选择保存路径" Grid.Row="1"/>
                                </Grid>
                            </GroupBox>
                            <Button Margin="10,2" Command="{Binding SaveCommand}"   Click="Button_Click">
                               保存(Save)
                            </Button>
                            <!--<StackPanel Orientation="Horizontal">
                                <ProgressBar HorizontalAlignment="Stretch" Width="295"></ProgressBar>
                            </StackPanel>-->
                            <Grid  Margin="2">
                                <hc:Card Header="选项">
                                    <StackPanel>
                                        <StackPanel Margin="0,5" Orientation="Horizontal">
                                            <CheckBox HorizontalAlignment="Left" Margin="10,0"  IsChecked="{Binding IsOpenFile}"
                                      ToolTip="保存完成后打开文件(Open gltf file after saved)">
                                            保存完打开
                                            </CheckBox>
                                            <CheckBox HorizontalAlignment="Left" Margin="10,0"  IsChecked="{Binding IsOpenFolder}"
                                      ToolTip="保存完成后打开文件夹(Open folder after saved)">
                                                保存完成后打开文件夹
                                            </CheckBox>
                                        </StackPanel>
                                        <Slider Margin="0,10" VerticalAlignment="Center"
      Minimum="0"
      Maximum="100"
      ToolTip="网格精度(待实现)"
      Value="50"
                                    </StackPanel>
                                </hc:Card>
                            </Grid>
                            <GroupBox Header="批量转换" Visibility="Collapsed">
                            </GroupBox>
                        </StackPanel>
                    </ScrollViewer>
                    <GridSplitter Grid.Row="1" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Stretch" Margin="0,7,-0.4,7"  />
                    <Grid Grid.Row="2" Margin="0,0,-0.4,0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="14*"/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <!--<materialDesign:Card>
                            <GroupBox Header="批量转换(开发中)" Margin="5,10">
                                <StackPanel>
                                </StackPanel>
                            </GroupBox>
                        </materialDesign:Card>-->
                    </Grid>
                </Grid>
            </TabItem>
            <TabItem>
                <TabItem.Header>
                    <Image Source="pack://application:,,,/DuSwToglTF;component/Resources/About.png" Width="16" Height="16"></Image>
                </TabItem.Header>
                <StackPanel>
                    <Grid Margin="5">
                        <GroupBox >
                            <GroupBox.Header>
                                <Label ToolTip="Info">信息</Label>
                            </GroupBox.Header>
                            <StackPanel>
                                <TextBlock HorizontalAlignment="Center" FontSize="15" Margin="5">
                        DuSwToglTF V0.0.1 Preview
                                </TextBlock>
                                <TextBlock Margin="4">1.支持格式:sldprt,sldasm转换为glTF文件</TextBlock>
                                <TextBlock Margin="4" TextWrapping="Wrap">2.对多实体零件或者装配体的输出未进行测试,可能产生错误</TextBlock>
                                <TextBlock Margin="4">2.包含几何信息和颜色信息,单一面的颜色信息暂未考虑</TextBlock>
                                <TextBlock Margin="4">3.暂未支持光照度,场景,动画等功能</TextBlock>
                            </StackPanel>
                        </GroupBox>
                    </Grid>
                    <Grid Margin="5" >
                        <Expander Header="NuGet">
                            <!--<Expander.Header >
                                <Label  ToolTip="使用的库或框架">使用的库或框架
                                </Label>
                            </Expander.Header>-->
                            <StackPanel>
                                <Label>1.HandyControl</Label>
                                <Label>2.MVVM-MVVMLight</Label>
                                <Label>2.glTF-sharpglTF</Label>
                            </StackPanel>
                        </Expander>
                    </Grid>
                    <Grid Margin="5" >
                        <GroupBox Header="项目信息">
                            <StackPanel>
                                <TextBlock>
                                    <Hyperlink></Hyperlink>
                                </TextBlock>
                                <TextBlock Margin="5">Code by DuDuDu</TextBlock>
                                <TextBlock Margin="5">Contact me:1831197727@qq.com</TextBlock>
                                <StackPanel Orientation="Horizontal">
                                    <Label>Project:</Label>
                                    <TextBlock VerticalAlignment="Center">
                                    <Hyperlink>https://github.com/weianweigan/DuSwToglTF</Hyperlink>
                                    </TextBlock>
                                </StackPanel>
                            </StackPanel>
                        </GroupBox>
                    </Grid>
                </StackPanel>
            </TabItem>
        </TabControl>
    </UserControl>
    
    3.4将相应属性绑定到viewmodel上

    详细的代码可以去GitHub查看

    3.5 关于实时获取当前打开的文档,以便自动填写文件路径和名字。

    为了在打开零件或者装配体时自动填写文件名和当前打开的文件路径,我们需要监听切换文档的事件。

  • 在SwAddin.cs类的OnDocChange()方法中设置文档名字和路径
  •  public int OnDocChange()
                TaskPanelControl.viewmodel.SetModelDoc();
                return 0;
    
    3.6 实现ConvertPanelViewModel中的SaveClick()方法
      /// <summary>
            /// 保存按钮执行的动作
            /// </summary>
            private  void  SaveClick()
                List<string> files = null;
                Controller.Convertor.ErrorType errors = Controller.Convertor.ErrorType.NoErros;
                IsInProgress = true;
                if (!System.IO.Directory.Exists(FilePath))
                    swApp.SendMsgToUser("当前路径不存在:" + FilePath);
                    return;
                if (FilePath.Contains("-") || FileName.Contains("-"))
                    swApp.SendMsgToUser("-为非法字符,路径或者文件民包含-字符,请修改路径或者文件名后重新保存");
                    return;
                    //会堵塞UI;TODO:异步方式实现转换
                    var model =  Controller.Convertor.DuConvertor.ConvertToglTFModel(swModel, out errors);
                    if (model != null)
                        files =  Controller.Convertor.DuConvertor.SaveAs(model, FilePath, FileName);
                    swApp.SendMsgToUser("保存完成");
                    if (files != null && IsOpenFile && files.Count >= 3)
                        System.Diagnostics.Process.Start( files[2]);
                    if (IsOpenFolder)
                        System.Diagnostics.Process.Start("explorer.exe", FilePath);
                    IsInProgress = false;
                catch (Exception ex)
                    MessageBox.Show(ex.ToString());
                // System.Diagnostics.Process.Start("ExpLore", "C:\\window");
    

    *下面将介绍对SolidWorks模型处理和保存。

     var model =  Controller.Convertor.DuConvertor.ConvertToglTFModel(swModel, out errors);