Selected component exported to STL
Selected component exported to STL

This macro demonstrates how to export selected component to STL format. This macro is not using the default exporter and overcomes the limitation when the model needs to be loaded in its own window. Macro will create stl from the tesselation triangles of the model.

Macro will also work with the components loaded lightweight.

  • Open assembly (can be opened lightweight)
  • Select part component
  • Browse the location of the output STL file
  • File is exported
using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using System.Runtime.InteropServices;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace CodeStack
{
    public partial class SolidWorksMacro
    {
        public void Main()
        {
            IModelDoc2 model = swApp.IActiveDoc2;

            if (model != null)
            {
                IComponent2 comp = model.ISelectionManager.GetSelectedObjectsComponent3(1, -1) as IComponent2;

                if (comp != null)
                {
                    float[] tessTriangs;
                    float[] tessNorms;

                    GetTesselationData(comp, out tessTriangs, out tessNorms);

                    string filePath = BrowseFile(Path.GetFileNameWithoutExtension(comp.GetPathName()));

                    if (!string.IsNullOrEmpty(filePath))
                    {
                        ExportToStl(filePath, tessTriangs, tessNorms);
                    }
                }
                else
                {
                    swApp.SendMsgToUser("Please select component");
                }
            }
            else
            {
                swApp.SendMsgToUser("Please open assembly");
            }
        }

        private void GetTesselationData(IComponent2 comp, out float[] tessTriangs, out float[] tessNorms) 
        {
            IModelDoc2 compModel = comp.IGetModelDoc();

            if (compModel == null)
            {
                if (Path.GetExtension(comp.GetPathName()).Equals(".sldprt", StringComparison.CurrentCultureIgnoreCase))
                {
                    tessTriangs = comp.GetTessTriangles(true) as float[];
                    tessNorms = comp.GetTessNorms() as float[];
                }
                else 
                {
                    throw new NotSupportedException("Only parts are supported");
                }
            }
            else
            {
                if (compModel is IPartDoc)
                {
                    IPartDoc part = compModel as IPartDoc;
                    tessTriangs = part.GetTessTriangles(true) as float[];
                    tessNorms = part.GetTessNorms() as float[];
                }
                else
                {
                    throw new NotSupportedException("Only parts are supported");
                }
            }
        }

        private void ExportToStl(string filePath, float[] tessTriangs, float[] tessNorms) 
        {
            using (FileStream fileStream = File.Create(filePath)) 
            {
                using (BinaryWriter writer = new BinaryWriter(fileStream))
                {
                    byte[] header = new byte[80];

                    writer.Write(header);

                    uint triangsCount = (uint)tessTriangs.Length / 9;
                    writer.Write(triangsCount);

                    for (uint i = 0; i < triangsCount; i++) 
                    {
                        float normalX = tessNorms[i * 9];
                        float normalY = tessNorms[i * 9 + 1];
                        float normalZ = tessNorms[i * 9 + 2];

                        writer.Write(normalX);
                        writer.Write(normalY);
                        writer.Write(normalZ);

                        for (uint j = 0; j < 3; j++) 
                        {
                            float vertX = tessTriangs[i * 9 + j * 3];
                            float vertY = tessTriangs[i * 9 + j * 3 + 1];
                            float vertZ = tessTriangs[i * 9 + j * 3 + 2];

                            writer.Write(vertX);
                            writer.Write(vertY);
                            writer.Write(vertZ);
                        }

                        ushort atts = 0;
                        writer.Write(atts);
                    }
                }
            }
        }

        private string BrowseFile(string defName) 
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "STL Files (*.stl)|*.stl";
            dlg.FileName = defName + ".stl";

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                return dlg.FileName;
            }
            else 
            {
                return "";
            }
        }

        public SldWorks swApp;
    }
}