STL文件的读取与显示

 

STL文件的基本数据格式:

solid OBJECT
  facet normal 0 -0 -1
    outer loop
      vertex -17.220884323120117 17.570217132568359 0.81012475490570068
      vertex -17.220884323120117 18.465063095092773 0.81012475490570068
      vertex -15.970458030700684 17.570217132568359 0.81012475490570068
    endloop
  endfacet
  facet normal -0 -0 -1
    outer loop
      vertex -17.220884323120117 18.465063095092773 0.81012475490570068
      vertex -17.220884323120117 19.359909057617188 0.81012475490570068
      vertex -15.970458030700684 17.570217132568359 0.81012475490570068
    endloop
  endfacet

……………………

……………………

由若干数量的三角面片组成

facet normal 0 -0 -1
outer loop
vertex -17.220884323120117 17.570217132568359 0.81012475490570068
vertex -17.220884323120117 18.465063095092773 0.81012475490570068
vertex -15.970458030700684 17.570217132568359 0.81012475490570068
endloop
endface

为一个三角形单元:第一行三个数据为三角面片的法向量,三个vertex分别为三角形的三个顶点

测试平台:windows7  64位   vs2010旗舰版

------------------------------------------------------------------------------------------------------------

xaml

------------------------------------------------------------------------------------------------------------

<Window x:Class="WPF3D.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Basic3D Sample"
        
        Name="Main_Window" Width="800" Height="600"
        >
    <DockPanel LastChildFill="True">
        <StackPanel DockPanel.Dock="Left" Width="200" >
            <Label>投影模式</Label>
            <ComboBox Name="CameraMode" SelectionChanged="CameraMode_SelectionChanged" Width="100" HorizontalContentAlignment="Center">
                <ComboBoxItem>正交投影</ComboBoxItem>
                <ComboBoxItem>透视投影</ComboBoxItem>
            </ComboBox>
            <Label>放缩</Label>
            <Slider Minimum="-5" Maximum="5" Margin="3"></Slider>
            <Button Margin="20" Padding="10" Click="Button_Click"> 打开文件</Button>
            <TextBlock>
                <Label>三角面片个数:</Label>
                <Label Name="NumberOfFacets" Width="60"></Label>
                <Label></Label>
            </TextBlock>
            <TextBlock>
                <Label Content="绘  图  时  间  :"></Label>
                <Label Name="TimeOfDrawing" Width="60"></Label>
                <Label>ms</Label>
            </TextBlock>
            <ScrollViewer VerticalScrollBarVisibility="Auto" Padding="0 20 20 0">
                <StackPanel Name="ListVisual">
                        <TextBlock>
                            <Label>序号</Label>
                            <Label >三角形个数</Label>
                            <Label>Time(ms)</Label>
                        </TextBlock>
                </StackPanel>
            </ScrollViewer>
        </StackPanel>
        <Viewport3D Name="myViewport3D" >
            
        </Viewport3D>
    </DockPanel>

</Window>
 

------------------------------------------------------------------------------------------------------------

.cs

------------------------------------------------------------------------------------------------------------

PerspectiveCamera myPerCamera = new PerspectiveCamera();
        OrthographicCamera myOrthoCamera = new OrthographicCamera();
        ModelVisual3D myModelLight = new ModelVisual3D();
        ModelVisual3D myModel = new ModelVisual3D();
        Model3DGroup myModelGroup = new Model3DGroup();
        GeometryModel3D myGeomentryModel1 = new GeometryModel3D();
        GeometryModel3D myGeomentryModel2 = new GeometryModel3D();
        GeometryModel3D myGeomentryModel3 = new GeometryModel3D();
        MeshGeometry3D myMeshModel1 = new MeshGeometry3D();

        DiffuseMaterial myDiffMaterial = new DiffuseMaterial();
        
        AmbientLight myAmbientLight = new AmbientLight();
        DirectionalLight myDirectionLight = new DirectionalLight();
        PointLight myPointLight = new PointLight();
        string filePath = null;

        private MeshGeometry3D getMeshModeFromSTLFile(string path)
        {
            MeshGeometry3D mesh = new MeshGeometry3D();
            int IndexOfTriangles = 0;
            StreamReader sr = new StreamReader(path);
            string line;
            Vector3D vec = new Vector3D();
            string[] split=new string[4];
            while ((line = sr.ReadLine()) != null)
            {
                line = line.TrimStart();
                if (line.StartsWith("facet normal"))
                {
                    //向量
                    line = line.Substring(12);
                    //split = line.Split(' ');
                    //vec = new Vector3D(double.Parse(split[1]), double.Parse(split[2]), double.Parse(split[3]));

                    //点
                    line = sr.ReadLine();
                    line = sr.ReadLine();
                    split = line.TrimStart().Split(' ');
                    mesh.Positions.Add(new Point3D(double.Parse(split[1]), double.Parse(split[2]), double.Parse(split[3])));
                    //mesh.Normals.Add(vec);
                    mesh.TriangleIndices.Add(IndexOfTriangles++);

                    line = sr.ReadLine();
                    split = line.TrimStart().Split(' ');
                    mesh.Positions.Add(new Point3D(double.Parse(split[1]), double.Parse(split[2]), double.Parse(split[3])));
                    //mesh.Normals.Add(vec);
                    mesh.TriangleIndices.Add(IndexOfTriangles++);

                    line = sr.ReadLine();
                    split = line.TrimStart().Split(' ');
                    mesh.Positions.Add(new Point3D(double.Parse(split[1]), double.Parse(split[2]), double.Parse(split[3])));
                    //mesh.Normals.Add(vec);
                    mesh.TriangleIndices.Add(IndexOfTriangles++);
                    
                    
                }
                    
            }
            NumberOfFacets.Content = (IndexOfTriangles/3).ToString();
            return mesh;
        }

        private void drawModel()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Viewport3D myViewPort = new Viewport3D();
            myModelLight.Content = myAmbientLight;
            ScaleTransform3D scale = new ScaleTransform3D(0.1, 0.1, 0.1);

            myGeomentryModel1.Geometry = getMeshModeFromSTLFile(filePath);
            myDiffMaterial = new DiffuseMaterial(Brushes.Blue);
            myGeomentryModel1.Material = myDiffMaterial;
            myGeomentryModel1.BackMaterial = new DiffuseMaterial(Brushes.Coral);
            myModelGroup.Children.Add(myGeomentryModel1);
            myModel.Content = myModelGroup;
            myOrthoCamera.Position = new Point3D(-1000, -1000, -1000);
            myOrthoCamera.NearPlaneDistance = 10;
            myOrthoCamera.FarPlaneDistance = double.PositiveInfinity;
            myOrthoCamera.LookDirection = new Vector3D(1, 1, 1);
            myOrthoCamera.UpDirection = new Vector3D(0, 1, 0);
            myOrthoCamera.Width = 200;
            //myModel.Transform = scale;
            myViewport3D.Camera = myOrthoCamera;
            myViewport3D.Children.Clear();
            myViewport3D.Children.Add(myModelLight);
            myViewport3D.Children.Add(myModel);
            sw.Stop();
            TimeOfDrawing.Content = sw.ElapsedMilliseconds.ToString();
            TextBlock tb=new TextBlock();
            tb.Text="    " + (ListVisual.Children.Count).ToString() + ":\t"+ NumberOfFacets.Content +"\t\t"+ TimeOfDrawing.Content;
            ListVisual.Children.Add(tb);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Forms.OpenFileDialog fileDlg = new System.Windows.Forms.OpenFileDialog();
            //penFileDialog1.InitialDirectory = "c:\\";
            //openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
            //openoFileDialog1.FilterIndex = 2;
            //openFileDialog1.RestoreDirectory = true;
            fileDlg.InitialDirectory = "E:\\";
            fileDlg.Filter = "STL file(*.stl)|*.stl|All files(*.*)|*.*";
            fileDlg.FilterIndex = 0;

            fileDlg.ShowDialog();
            filePath = fileDlg.FileName;

            if (filePath != null && filePath.ToLower().EndsWith(".stl"))
            {
                drawModel();
            }
        }

        private void CameraMode_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox cb = sender as ComboBox;
            switch (cb.SelectedIndex)
            {
                case 0:
                    myViewport3D.Camera = myOrthoCamera;
                    break;
                case 1:
                    myPerCamera.Position = new Point3D(1000, 1000, 1000);
                    myPerCamera.NearPlaneDistance = 10;
                    myPerCamera.LookDirection = new Vector3D(-1, -1, -1);
                    myPerCamera.UpDirection = new Vector3D(0, 1, 0);
                    myPerCamera.FieldOfView = 10;
                    myPerCamera.FarPlaneDistance = double.PositiveInfinity;
                    myViewport3D.Camera = myPerCamera;
                    break;
                default:
                    break;
            }
        }
private void myViewport3D_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if(e.Delta>0)
            {
                myOrthoCamera.Width *=1.2;
                myPerCamera.FieldOfView *=1.2;
            }
            if(e.Delta<0)              
            {
                myOrthoCamera.Width /= 1.2;
                myPerCamera.FieldOfView /= 1.2;
            }
            switch (CameraMode.SelectedIndex)
            {
                case 0:
                    myViewport3D.Camera = myOrthoCamera;
                    break;
                case 1:                    
                    myViewport3D.Camera = myPerCamera;
                    break;
                default:
                    break;
            }
        }


 

效果:

image

 

image

image

posted @ 2013-08-18 19:41  bacazy  Views(6823)  Comments(4Edit  收藏  举报