示例#1
0
        MeshSimplifier(List <Vec3> verts, int?target)
        {
            Console.WriteLine("Converting to indexed form");
            ConvertToIndexed(verts);

            var nmesh = new Mesh(Vertices.Select(x => new Vector3d(x.X, x.Y, x.Z)).ToArray(),
                                 Triangles.Select(x => x.Triangulate()).SelectMany(x => x).ToArray());

            nmesh.RecalculateNormals();
            nmesh.RecalculateTangents();
            Console.WriteLine("Decimating mesh");
            nmesh = target == null
                                ? MeshDecimation.DecimateMeshLossless(nmesh)
                                : MeshDecimation.DecimateMesh(nmesh, target.Value);

            Vertices = nmesh.Vertices.Select(x => new Vec3((float)x.x, (float)x.y, (float)x.z)).ToList();
            var inds = nmesh.Indices;

            Triangles = new List <Triangle>();
            for (var i = 0; i < inds.Length; i += 3)
            {
                Triangles.Add(new Triangle(inds[i], inds[i + 1], inds[i + 2]));
            }
        }
示例#2
0
        private void SetModelTask(ModelFileData modelData)
        {
            if (CurrentModelVisual != null)
            {
                this.Viewport.Children.Remove(CurrentModelVisual);
                CurrentModelVisual = null;
                GC.Collect(0, GCCollectionMode.Forced);
            }

            if (!this.Viewport.IsVisible)
            {
                this.ModelDataToLoadWhenVisible = modelData;
                return;
            }

            Model3DGroup  modelGroup  = new Model3DGroup();
            ModelVisual3D modelVisual = new ModelVisual3D();

            try
            {
                if (modelData != null)
                {
                    ModelFileData newModelData = new ModelFileData(modelData.FileFullPath);
                    this.ModelData    = newModelData;
                    Viewport.SubTitle = modelData.FileName;

                    newModelData.LoadBasicFileData();

                    if (userSettings.GetSettingBool(UserSettingEnum.EnableMaxSizeMBToLoadMeshInView) && modelData.FileSizeMB > userSettings.GetSettingInt(UserSettingEnum.MaxSizeMBToLoadMeshInView))
                    {
                        // TODO: Load generic model.
                        Viewport.SubTitle  = Loc.GetTextFormatted("FileSizeTooBigToLoadMB", modelData.FileSizeMB, userSettings.GetSettingInt(UserSettingEnum.MaxSizeMBToLoadMeshInView));
                        CurrentModelVisual = null;
                        return;
                    }

                    if (!newModelData.HasBytes())
                    {
                        newModelData.LoadFileBytes(newModelData.FileSizeMB < 50f);
                    }
                    if (newModelData.Mesh == null)
                    {
                        newModelData.ParseFile();
                    }
                    newModelData.ReleaseData(true, false);

                    if (newModelData.Mesh == null)
                    {
                        newModelData.ReleaseData(true, false);
                        SetModel(null);
                        return;
                    }

                    LoadModelInfoAvailableEvent?.Invoke(newModelData.FileName, newModelData.Mesh.TriangleCount, newModelData.Mesh.Vertices.Length, (int)newModelData.FileSizeKB);

                    float modelScale         = newModelData.Mesh.Scale / 4f;
                    float modelScaleMultiply = (newModelData.Mesh.Scale < 0.001f ? 0.1f : (newModelData.Mesh.Scale > 0.1 ? 10f : 1));


                    var transformTranslate           = new TranslateTransform3D(-newModelData.Mesh.OffsetX, -newModelData.Mesh.OffsetY, -newModelData.Mesh.OffsetZ);
                    AxisAngleRotation3D axisRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), 0);
                    transformObjectRotation = new RotateTransform3D(axisRotation, new Point3D(newModelData.Mesh.OffsetX, newModelData.Mesh.OffsetY, 0));
                    ScaleTransform3D transformScale = new ScaleTransform3D(modelScaleMultiply, modelScaleMultiply, modelScaleMultiply);

                    Transform3DGroup transforms = new Transform3DGroup();
                    transforms.Children.Add(transformObjectRotation);
                    transforms.Children.Add(transformTranslate);
                    transforms.Children.Add(transformScale);

                    Mesh3D mesh;

                    // Mesh decimation if enabled
                    if (userSettings.GetSettingBool(UserSettingEnum.EnableMeshDecimation) && newModelData.Mesh.TriangleCount > userSettings.GetSettingInt(UserSettingEnum.MinTrianglesForMeshDecimation))
                    {
                        MeshDecimator.Math.Vector3d[] vectors3D = newModelData.Mesh.Vertices.Select(v => new MeshDecimator.Math.Vector3d(v.x, v.y, v.z)).ToArray();
                        Mesh decimatorMesh = new Mesh(vectors3D, newModelData.Mesh.Triangles.ToArray());

                        Mesh decimatedMesh = MeshDecimation.DecimateMeshLossless(decimatorMesh);
                        mesh = new Mesh3D(decimatedMesh.Vertices.Select(v => new Point3D(v.x, v.y, v.z)), decimatedMesh.Indices);

                        // TODO: Possibly cache the decimated models to avoid re-processing.
                    }
                    else
                    {
                        mesh = new Mesh3D(Point3DFromLinearCoordinates(newModelData.Mesh.Vertices), newModelData.Mesh.Triangles);
                    }
                    GeometryModel3D geometryModel = new GeometryModel3D(mesh.ToMeshGeometry3D(), GetMaterial());
                    geometryModel.Freeze();

                    modelGroup.Children.Add(geometryModel);
                    modelGroup.Freeze();

                    _modelHeightPosition = newModelData.Mesh.Height * modelScaleMultiply;
                    newModelData.ReleaseData(true, true);

                    // Animation
                    if (ModelAutoRotationEnabled)
                    {
                        DoubleAnimation animation1 = new DoubleAnimation(-90, 395d, TimeSpan.FromMilliseconds(1000));
                        animation1.EasingFunction = new ExponentialEase();

                        DoubleAnimation animation2 = new DoubleAnimation(36d, 395d, TimeSpan.FromMilliseconds(7000));
                        animation2.RepeatBehavior = RepeatBehavior.Forever;

                        animation1.Completed += (o, e) => axisRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, animation2);
                        axisRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, animation1);
                    }

                    // Camera animation
                    var nomalizedOriginalPosition = _originalCameraPosition.ToVector3D();
                    nomalizedOriginalPosition.Normalize();
                    _modelCameraPosition = new Point3D(nomalizedOriginalPosition.X / modelScale * modelScaleMultiply, nomalizedOriginalPosition.Y / modelScale * modelScaleMultiply, nomalizedOriginalPosition.Z / modelScale * modelScaleMultiply);

                    Point3D targetCameraPosition = _modelCameraPosition;
                    if (_CurrentCameraPosition == CameraPositionEnum.Default)
                    {
                        var normalizedPosition = Viewport.Camera.Position.ToVector3D();
                        normalizedPosition.Normalize();
                        targetCameraPosition = new Point3D(normalizedPosition.X / modelScale * modelScaleMultiply, normalizedPosition.Y / modelScale * modelScaleMultiply, normalizedPosition.Z / modelScale * modelScaleMultiply);

                        Viewport.Camera.AnimateTo(targetCameraPosition, Viewport.Camera.LookDirection, Viewport.Camera.UpDirection, 500d);
                    }
                    else
                    {
                        ResetCamera(CameraPositionEnum.Current);
                    }

                    minZoom = targetCameraPosition.Multiply(0.5d).DistanceTo(new Point3D());
                    maxZoom = minZoom * 4d;

                    this.CurrentAxisRotation = axisRotation;
                    modelVisual.Transform    = transforms;
                }
                modelVisual.Content = modelGroup;
                this.Viewport.Children.Add(modelVisual);

                this.CurrentModelVisual = modelVisual;
            }
            catch (Exception ex)
            {
                if (CurrentModelVisual != null)
                {
                    this.Viewport.Children.Add(CurrentModelVisual);
                    this.CurrentModelVisual = null;
                }
            }
            if (modelData == null)
            {
                _modelCameraPosition = _originalCameraPosition;
                ResetCamera(CameraPositionEnum.Default, true);
                LoadModelInfoAvailableEvent?.Invoke("", 0, 0, 0);
                _modelHeightPosition = (float)(_originalCameraPosition.Z / 2d);
                Viewport.SubTitle    = string.Empty;
            }
            GC.Collect();
        }