/// <summary> /// Builds the model. /// </summary> /// <returns>A Model3D object.</returns> private Model3DGroup BuildModel() { Model3DGroup modelGroup = null; this.Dispatch(() => { modelGroup = new Model3DGroup(); modelGroup.SetName("groupModel"); int n = 0; foreach (var g in this.Groups) { int m = 0; foreach (var gm in g.CreateModels()) { if (this.Freeze) { gm.Freeze(); } gm.SetName("model_" + n.ToString() + "_" + m.ToString()); modelGroup.Children.Add(gm); m++; } n++; } if (this.Freeze) { modelGroup.Freeze(); } }); return(modelGroup); }
private static Model3DGroup CreateAxisAndArrowHead(RotateTransform3D rotateTransform, TranslateTransform3D translateTransform, Material material) { Model3DGroup model3Dgroup = new Model3DGroup(); Model3DCollection model3Dcollection = new Model3DCollection(); model3Dgroup.Children = model3Dcollection; Model3DGroup cylinder = Cylinder.CreateCylinder(0.02, 0.5, 12, material, material, (Material)null); if (rotateTransform != null) { cylinder.Transform = (Transform3D)rotateTransform; } model3Dgroup.Children.Add((Model3D)cylinder); Model3DGroup cone = Cone.CreateCone(0.04, 0.1, 12, material, material); if (rotateTransform != null) { cone.Transform = (Transform3D) new Transform3DGroup() { Children = { (Transform3D)rotateTransform, (Transform3D)translateTransform } } } ; else { cone.Transform = (Transform3D)translateTransform; } model3Dgroup.Children.Add((Model3D)cone); model3Dgroup.Freeze(); return(model3Dgroup); }
/// <summary> /// Builds the model. /// </summary> /// <returns>The model.</returns> public Model3DGroup ToModel3D() { Model3DGroup modelGroup = null; this.Dispatch( () => { modelGroup = new Model3DGroup(); int i = 0; foreach (var mesh in this.Meshes) { var gm = new GeometryModel3D { Geometry = mesh.ToMesh(), Material = this.Materials[i], BackMaterial = this.Materials[i] }; if (this.Freeze) { gm.Freeze(); } modelGroup.Children.Add(gm); i++; } if (this.Freeze) { modelGroup.Freeze(); } }); return(modelGroup); }
private void Paint3DScena() { //Создаем фон int width = scenario.map.GetMap().GetLength(0), height = scenario.map.GetMap().GetLength(1); Point3D p1 = new Point3D(-width / 2, 0, -height / 2); Point3D p2 = new Point3D(width / 2, 0, -height / 2); Point3D p3 = new Point3D(width / 2, 0, height / 2); Point3D p4 = new Point3D(-width / 2, 0, height / 2); ImageBrush brush; if (File.Exists(Properties.Settings.Default.ScenarioPath + "image.jpg")) { brush = new ImageBrush(new BitmapImage(new Uri(Properties.Settings.Default.ScenarioPath + "image.jpg"))); } else { brush = new ImageBrush(scenario.Image); } //добавляем фон в группу Model3DGroup background = new Model3DGroup(); background.Children.Add(CreateBackgroundModelGroup(p1, p2, p3, p4, brush)); background.Freeze(); ModelVisual3D backgroundModel = new ModelVisual3D(); backgroundModel.Content = background; //Заполняем ViewPort фоном mainViewport.Children.Add(backgroundModel); }
/// <summary> /// Builds the model. /// </summary> /// <returns>A Model3D object.</returns> private Model3DGroup BuildModel() { Model3DGroup modelGroup = null; this.Dispatch(() => { modelGroup = new Model3DGroup(); foreach (var g in this.Groups) { foreach (var gm in g.CreateModels()) { if (this.Freeze) { gm.Freeze(); } modelGroup.Children.Add(gm); } } if (this.Freeze) { modelGroup.Freeze(); } }); return(modelGroup); }
/// <summary> /// Creates a <see cref="Model3DGroup" /> from the loaded file. /// </summary> /// <returns>A <see cref="Model3DGroup" />.</returns> public Model3DGroup CreateModel3D() { Model3DGroup modelGroup = null; this.Dispatch(() => { modelGroup = new Model3DGroup(); var g = this.CreateMeshGeometry3D(); var gm = new GeometryModel3D { Geometry = g, Material = this.DefaultMaterial, BackMaterial = DefaultMaterial }; if (this.Freeze) { gm.Freeze(); } modelGroup.Children.Add(gm); if (this.Freeze) { modelGroup.Freeze(); } }); return(modelGroup); }
private async void Load_Async() { // *** Opening dialog for choosing the object OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Obj files (*.obj)| *.obj"; openFileDialog.InitialDirectory = Environment.CurrentDirectory; // *** Disable the buttons Load.IsEnabledModificate = false; Clear.IsEnabledModificate = false; // *** Getting full path of the object string fullPath = null; try { if (openFileDialog.ShowDialog() == true) { fullPath = openFileDialog.FileName; } } catch (Exception ex) { MessageBox.Show("Oops, something went wrong ->" + ex.Message); } if (fullPath != null) { await Task.Run(() => { // *** Getting directly the object ObjReader CurrentHelixObjReader = new ObjReader(); try { NewModel = CurrentHelixObjReader.Read(fullPath); NewModel.Freeze(); } catch (Exception) { NewModel = null; } }); Clear.IsEnabledModificate = true; } else { Clear.IsEnabledModificate = false; } // *** Enable the buttons Load.IsEnabledModificate = true; }
public static ModelVisual3D GetCylinder(MaterialGroup materialGroup, Point3D midPoint, double radius, double depth) { var cylinder = new Model3DGroup(); var nearCircle = new CircleAssitor(); var farCircle = new CircleAssitor(); var twoPi = Math.PI * 2; var firstPass = true; double x; double y; var increment = 0.1d; for (double i = 0; i < twoPi + increment; i = i + increment) { x = (radius * Math.Cos(i)); y = (-radius * Math.Sin(i)); farCircle.CurrentTriangle.P0 = midPoint; farCircle.CurrentTriangle.P1 = farCircle.LastPoint; farCircle.CurrentTriangle.P2 = new Point3D(x + midPoint.X, y + midPoint.Y, midPoint.Z); nearCircle.CurrentTriangle = farCircle.CurrentTriangle.Clone(depth, true); if (!firstPass) { cylinder.Children.Add(CreateTriangleModel(materialGroup, farCircle.CurrentTriangle)); cylinder.Children.Add(CreateTriangleModel(materialGroup, nearCircle.CurrentTriangle)); cylinder.Children.Add(CreateTriangleModel(materialGroup, farCircle.CurrentTriangle.P2, farCircle.CurrentTriangle.P1, nearCircle.CurrentTriangle.P2)); cylinder.Children.Add(CreateTriangleModel(materialGroup, nearCircle.CurrentTriangle.P2, nearCircle.CurrentTriangle.P1, farCircle.CurrentTriangle.P2)); } else { farCircle.FirstPoint = farCircle.CurrentTriangle.P1; nearCircle.FirstPoint = nearCircle.CurrentTriangle.P1; firstPass = false; } farCircle.LastPoint = farCircle.CurrentTriangle.P2; nearCircle.LastPoint = nearCircle.CurrentTriangle.P2; } cylinder.Freeze(); var model = new ModelVisual3D { Content = cylinder }; return(model); }
static Transition3D() { Model3DGroup defaultLight = new Model3DGroup(); Vector3D direction = new Vector3D(1, 1, 1); direction.Normalize(); byte ambient = 108; // 108 is minimum for directional to be < 256 (for direction = [1,1,1]) byte directional = (byte)Math.Min((255 - ambient) / Vector3D.DotProduct(direction, new Vector3D(0, 0, 1)), 255); defaultLight.Children.Add(new AmbientLight(Color.FromRgb(ambient, ambient, ambient))); defaultLight.Children.Add(new DirectionalLight(Color.FromRgb(directional, directional, directional), direction)); defaultLight.Freeze(); LightProperty = DependencyProperty.Register("Light", typeof(Model3D), typeof(Transition3D), new UIPropertyMetadata(defaultLight)); }
private Model3DGroup CreateMockModel(ImageSource image, double width, double height) { //Создаем фон Point3D p1 = new Point3D(0, 0, 0); Point3D p2 = new Point3D(0, width, 0); Point3D p3 = new Point3D(height, width, 0); Point3D p4 = new Point3D(height, 0, 0); ImageBrush brush = new ImageBrush(image); //добавляем фон в группу Model3DGroup background = new Model3DGroup(); background.Children.Add(CreateBackgroundModelGroup(p1, p2, p3, p4, brush)); background.Freeze(); return(background); }
public static ModelVisual3D GetTexturedCube(DiffuseMaterial materialGroup, Point3D point, Size3D size) { var farPoint = new Point3D(point.X - (size.X / 2), point.Y - (size.Y / 2), point.Z - (size.Z / 2)); var nearPoint = new Point3D(point.X + (size.X / 2), point.Y + (size.Y / 2), point.Z + (size.Z / 2)); var cube = new Model3DGroup(); var p0 = new Point3D(farPoint.X, farPoint.Y, farPoint.Z); var p1 = new Point3D(nearPoint.X, farPoint.Y, farPoint.Z); var p2 = new Point3D(nearPoint.X, farPoint.Y, nearPoint.Z); var p3 = new Point3D(farPoint.X, farPoint.Y, nearPoint.Z); var p4 = new Point3D(farPoint.X, nearPoint.Y, farPoint.Z); var p5 = new Point3D(nearPoint.X, nearPoint.Y, farPoint.Z); var p6 = new Point3D(nearPoint.X, nearPoint.Y, nearPoint.Z); var p7 = new Point3D(farPoint.X, nearPoint.Y, nearPoint.Z); //front side triangles cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p3, p2, p6, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p3, p6, p7, 0, 0, 1, -1, 0, -1)); //right side triangles //cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p1, p5, 0, 1, 1, 1, 1, 0)); //cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p5, p6, 1, 1, 1, 0, 0, 0)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p1, p5, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p5, p6, 0, 0, 1, -1, 0, -1)); //back side triangles cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p1, p0, p4, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p1, p4, p5, 0, 0, 1, -1, 0, -1)); //left side triangles cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p0, p3, p7, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p0, p7, p4, 0, 0, 1, -1, 0, -1)); //top side triangles cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p7, p6, p5, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p7, p5, p4, 0, 0, 1, -1, 0, -1)); //bottom side triangles cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p3, p0, 0, 0, 1, 0, 1, -1)); cube.Children.Add(CreateTexturedTriangleModel(materialGroup, p2, p0, p1, 0, 0, 1, -1, 0, -1)); cube.Freeze(); var model = new ModelVisual3D(); model.Content = cube; return(model); }
public static Model3DGroup AddCouchBodyMesh(Structure body, Structure couch) { var modelGroup = new Model3DGroup(); // Create some materials var material = new DiffuseMaterial(new SolidColorBrush(Colors.LightBlue)); var darkblueMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.DarkBlue)); var magentaMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Magenta)); if (couch != null) { modelGroup.Children.Add(new GeometryModel3D { Geometry = couch.MeshGeometry, Material = magentaMaterial, BackMaterial = darkblueMaterial }); } modelGroup.Children.Add(new GeometryModel3D { Geometry = body.MeshGeometry, Material = material, BackMaterial = darkblueMaterial }); modelGroup.Freeze(); return(modelGroup); }
private static Model3DGroup CreateCube(Vector3D axis, Material material) { Model3DGroup model3Dgroup = new Model3DGroup(); Model3DCollection model3Dcollection = new Model3DCollection(); model3Dgroup.Children = model3Dcollection; double num = -0.04; Model3DGroup cube = Cube.CreateCube(new Rect3D(new Point3D(num, num, num), new Size3D(0.08, 0.08, 0.08)), material); cube.Transform = (Transform3D) new Transform3DGroup() { Children = { (Transform3D) new TranslateTransform3D(axis * 0.35) } }; model3Dgroup.Children.Add((Model3D)cube); model3Dgroup.Freeze(); return(model3Dgroup); }
public Model3DGroup GetNewStitching() { //if (!m_stitchingHasChanged || !m_hasStitching) // return null; m_stitchingHasChanged = false; Model3DGroup model = new Model3DGroup(); for (int i = 0; i < 3; i++) { if (m_stitchingGeometry[i] != null) { model.Children.Add(m_stitchingGeometry[i]); } } model.Freeze(); return(model); }
private Model3DGroup CreatePartModel() { if (string.IsNullOrEmpty(PartNumber)) { return(null); } _edges = new WireLines(); _edges.Thickness = 1.5; // Create a model to hold the part geometry Model3DGroup model = new Model3DGroup(); // Create the Geometery for main mesh. MeshGeometry3D mesh = new MeshGeometry3D(); Material material = SetMaterial(PartColor); GeometryModel3D geometry = new GeometryModel3D(mesh, material) { BackMaterial = material }; model.Children.Add(geometry); GeneratePartMesh(PartNumber + ".dat", false, Matrix3D.Identity, model, PartColor); // Ldraw follows -Y so invert the part on the Y axis. RotateTransform3D invertY = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 180)); model.Transform = invertY; _edges.Transform = invertY; //Children.Add(_edges); if (model.CanFreeze) { model.Freeze(); } return(model); }
public static ModelVisual3D CreateSphere(Point3D center, double radius, int u, int v, Color color) { Model3DGroup spear = new Model3DGroup(); if (u < 2 || v < 2) { return(null); } Point3D[,] pts = new Point3D[u, v]; for (int i = 0; i < u; i++) { for (int j = 0; j < v; j++) { pts[i, j] = GetPosition(radius, i * 180 / (u - 1), j * 360 / (v - 1)); pts[i, j] += (Vector3D)center; } } Point3D[] p = new Point3D[4]; for (int i = 0; i < u - 1; i++) { for (int j = 0; j < v - 1; j++) { p[0] = pts[i, j]; p[1] = pts[i + 1, j]; p[2] = pts[i + 1, j + 1]; p[3] = pts[i, j + 1]; spear.Children.Add(CreateTriangleFace(p[0], p[1], p[2], color)); spear.Children.Add(CreateTriangleFace(p[2], p[3], p[0], color)); } } spear.Freeze(); ModelVisual3D model = new ModelVisual3D(); model.Content = spear; return(model); }
public static Model3DGroup CreateTriangleFace(Point3D p0, Point3D p1, Point3D p2, Color color) { MeshGeometry3D mesh = new MeshGeometry3D(); mesh.Positions.Add(p0); mesh.Positions.Add(p1); mesh.Positions.Add(p2); mesh.TriangleIndices.Add(0); mesh.TriangleIndices.Add(1); mesh.TriangleIndices.Add(2); Vector3D normal = VectorHelper.CalcNormal(p0, p1, p2); mesh.Normals.Add(normal); mesh.Normals.Add(normal); mesh.Normals.Add(normal); mesh.Freeze(); Material material = new DiffuseMaterial( new SolidColorBrush(color)); GeometryModel3D model = new GeometryModel3D( mesh, material); model.Freeze(); Model3DGroup group = new Model3DGroup(); group.Children.Add(model); group.Freeze(); return(group); }
/* * void Transform(double adjustBy) * { * _angle += adjustBy; * * var rotateTransform3D = new RotateTransform3D { CenterX = 0, CenterZ = 0 }; * var axisAngleRotation3D = new AxisAngleRotation3D { Axis = new Vector3D(1, 1, 1), Angle = _angle }; * rotateTransform3D.Rotation = axisAngleRotation3D; * var myTransform3DGroup = new Transform3DGroup(); * myTransform3DGroup.Children.Add(rotateTransform3D); * _models.ForEach(x => x.Transform = myTransform3DGroup); * }*/ public static ModelVisual3D GetFloor(MaterialGroup materialGroup, Point3D midPoint) { var cylinder = new Model3DGroup(); Triangle triangle = new Triangle(); triangle.P0 = new Point3D(-100, midPoint.Y, 100); triangle.P1 = new Point3D(100, midPoint.Y, -100); triangle.P2 = new Point3D(-100, midPoint.Y, -100); //cylinder.Children.Add(CreateTriangleFace(triangle.P2, triangle.P1, triangle.P0, Color.FromRgb(255,0,0))); cylinder.Children.Add(CreateTriangleModel(materialGroup, triangle)); triangle.P0 = new Point3D(100, midPoint.Y, -100); triangle.P1 = new Point3D(-100, midPoint.Y, 100); triangle.P2 = new Point3D(100, midPoint.Y, 100); //cylinder.Children.Add(CreateTriangleFace(triangle.P2, triangle.P1, triangle.P0, Color.FromRgb(255,0,0))); cylinder.Children.Add(CreateTriangleModel(materialGroup, triangle)); cylinder.Freeze(); var model = new ModelVisual3D { Content = cylinder }; return(model); }
private static Model3DGroup CreateTorus(RotateTransform3D rotateTransform3D, Material material) { Model3DGroup model3Dgroup = new Model3DGroup(); Model3DCollection model3Dcollection = new Model3DCollection(); model3Dgroup.Children = model3Dcollection; Model3DGroup quarterTorus = Torus.CreateQuarterTorus(0.35, 0.015, 24, 15, material); if (rotateTransform3D != null) { quarterTorus.Transform = (Transform3D) new Transform3DGroup() { Children = { (Transform3D)rotateTransform3D } } } ; model3Dgroup.Children.Add((Model3D)quarterTorus); model3Dgroup.Freeze(); return(model3Dgroup); } }
private Model3DGroup CreateManyObjects() { // NOTE: // When creatinig many instances of the same mesh, it is many many times faster // to use DirectX object instaning then creating individual objects as it is done here. // See InstancedMeshGeometry3DTest and InstanceModelGroupVisual3DTest for more info. // But in this sample we want to simulate a creation of a complex scene. var model3DGroup = new Model3DGroup(); for (int i = 0; i < 1000; i++) { var sphereModel3D = Ab3d.Models.Model3DFactory.CreateSphere(centerPosition: GetRandomPosition(200), radius: 5, segments: 30, material: new DiffuseMaterial(new SolidColorBrush(GetRandomColor()))); model3DGroup.Children.Add(sphereModel3D); } model3DGroup.Freeze(); // Freeze the Model3DGroup so the objects can be read on different thread return(model3DGroup); }
public DXEventManager3DSample() { InitializeComponent(); Box1Visual3D.SetName("Box1Visual3D"); BoxesGroupVisual3D.SetName("BoxesGroupVisual3D"); Box2Visual3D.SetName("Box2Visual3D"); Box3Visual3D.SetName("Box3Visual3D"); Box4Visual3D.SetName("Box4Visual3D"); Line1.SetName("Line1"); Line2.SetName("Line2"); Rectangle1.SetName("Rectangle1"); var meshGeometry3D = new Ab3d.Meshes.SphereMesh3D(centerPosition: new Point3D(0, 0, 0), radius: 5, segments: 20, generateTextureCoordinates: false).Geometry; // The following method prepare InstanceData array with data for each instance (WorldMatrix and Color) InstanceData[] instancedData = DXEnginePerformance.InstancedMeshGeometry3DTest.CreateInstancesData(center: new Point3D(0, 0, 0), size: new Size3D(200, 50, 50), modelScaleFactor: 1, xCount: 10, yCount: 3, zCount: 3, useTransparency: false); // Create InstancedGeometryVisual3D with selected meshGeometry and InstancesData _instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(meshGeometry3D); _instancedMeshGeometryVisual3D.InstancesData = instancedData; _instancedMeshGeometryVisual3D.SetName("InstancedMeshGeometryVisual3D"); _instancedMeshGeometryVisual3D.Transform = new TranslateTransform3D(0, 50, 0); MainViewport3D.Children.Add(_instancedMeshGeometryVisual3D); _selectedInstanceIndex = -1; var model3DGroup = new Model3DGroup(); model3DGroup.SetName("Model3DGroup"); var frozenModel3DGroup = new Model3DGroup(); frozenModel3DGroup.SetName("FrozenModel3DGroup"); var box1Material = new DiffuseMaterial(Brushes.LightPink); var box2Material = new DiffuseMaterial(Brushes.LightCyan); var boxModel3D = Ab3d.Models.Model3DFactory.CreateBox(new Point3D(-100, 2, 25), new Size3D(60, 4, 50), box2Material); frozenModel3DGroup.Children.Add(boxModel3D); var pyramidModel3D = Ab3d.Models.Model3DFactory.CreatePyramid(new Point3D(-100, 2, 20), new Size3D(20, 20, 20), box2Material); frozenModel3DGroup.Children.Add(pyramidModel3D); for (int i = 0; i < 5; i++) { var geometryModel3D = new GeometryModel3D(meshGeometry3D, box1Material); geometryModel3D.Transform = new TranslateTransform3D(-130 + i * 15, 5, 80); geometryModel3D.SetName("GroupedSphere_" + i.ToString()); model3DGroup.Children.Add(geometryModel3D); geometryModel3D = new GeometryModel3D(meshGeometry3D, box2Material); geometryModel3D.Transform = new TranslateTransform3D(-130 + i * 15, 10, 50); geometryModel3D.SetName("FrozenGroupedSphere_" + i.ToString()); frozenModel3DGroup.Children.Add(geometryModel3D); } frozenModel3DGroup.Freeze(); MainViewport3D.Children.Add(model3DGroup.CreateModelVisual3D()); MainViewport3D.Children.Add(frozenModel3DGroup.CreateModelVisual3D()); _dxEventManager3D = new DXEventManager3D(MainDXViewportView); RegisterEventSource(Box1Visual3D); RegisterEventSource(BoxesGroupVisual3D); RegisterEventSource(Line1); RegisterEventSource(Line2); RegisterEventSource(Rectangle1); RegisterEventSource(_instancedMeshGeometryVisual3D); RegisterEventSource(model3DGroup); RegisterEventSource(frozenModel3DGroup); // Prevent TransparentPlaneVisual3D to be used by hit-testing _dxEventManager3D.RegisterExcludedVisual3D(TransparentPlaneVisual3D); this.PreviewMouseMove += delegate(object sender, MouseEventArgs args) { var position = args.GetPosition(this); MousePositionTextBlock.Text = $"Mouse pos: {position.X:0} {position.Y:0}"; }; this.PreviewMouseDown += delegate(object sender, MouseButtonEventArgs e) { var position = e.GetPosition(this); if (position == _lastMouseDownPosition) { return; } System.Diagnostics.Debug.WriteLine("Mouse position: " + position.ToString()); _lastMouseDownPosition = position; }; // IMPORTANT: // It is very important to call Dispose method on DXSceneView after the control is not used any more (see help file for more info) this.Unloaded += (sender, args) => MainDXViewportView.Dispose(); }
private void CreateScene(Viewport3D parentViewport3D, double sphereRadius, double depthBias, TargetPositionCamera targetPositionCamera, bool showSphere) { parentViewport3D.Children.Clear(); if (showSphere) { var sphereVisual3D = new Ab3d.Visuals.SphereVisual3D() { CenterPosition = new Point3D(0, 0, 0), Radius = sphereRadius, Segments = 10, Material = new DiffuseMaterial(Brushes.SkyBlue), UseCachedMeshGeometry3D = false // This will create a new MeshGeometry3D and will not use the shared MeshGeometry3D with radius = 1 }; parentViewport3D.Children.Add(sphereVisual3D); var sphereMesh = ((GeometryModel3D)sphereVisual3D.Content).Geometry as MeshGeometry3D; var sphereLinePositions = CollectWireframeLinePositions(sphereMesh); var multiLineVisual3D = new Ab3d.Visuals.MultiLineVisual3D() { Positions = sphereLinePositions, LineThickness = 0.5, LineColor = Colors.Black }; // To specify line depth bias to the Ab3d.PowerToys line Visual3D objects, // we use SetDXAttribute extension method and use LineDepthBias as DXAttributeType // NOTE: This can be used only before the Visual3D is created by DXEngine. // If you want to change the line bias after the object has been rendered, use the SetDepthBias method (defined below) multiLineVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias); // It would be also possible to set the depth with changing the DepthBias on the WpfWireframeVisual3DNode. // This is done with using the SetDepthBias method //SetDepthBias(dxViewportView, wireframeVisual3D, depthBias); parentViewport3D.Children.Add(multiLineVisual3D); _shownLineVisual3D = multiLineVisual3D; } else { if (_sampleModel == null) { var readerObj = new Ab3d.ReaderObj(); _sampleModel = readerObj.ReadModel3D(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Resources\Models\Teapot.obj"), null, new DiffuseMaterial(Brushes.SkyBlue)); _sampleModel.Freeze(); } double readObjectRadius = Math.Sqrt(_sampleModel.Bounds.SizeX * _sampleModel.Bounds.SizeX + _sampleModel.Bounds.SizeZ + _sampleModel.Bounds.SizeZ) / 2; double scaleFactor = sphereRadius / readObjectRadius; var finalModel = new Model3DGroup(); finalModel.Children.Add(_sampleModel); finalModel.Transform = new ScaleTransform3D(scaleFactor, scaleFactor, scaleFactor); finalModel.Freeze(); var wireframeVisual3D = new WireframeVisual3D() { OriginalModel = finalModel, WireframeType = WireframeVisual3D.WireframeTypes.WireframeWithOriginalSolidModel, UseModelColor = false, LineColor = Colors.Black, LineThickness = 0.5 }; // To specify line depth bias to the WireframeVisual3D, // we use SetDXAttribute extension method and use LineDepthBias as DXAttributeType wireframeVisual3D.SetDXAttribute(DXAttributeType.LineDepthBias, depthBias); // It would be also possible to set the depth with changing the DepthBias on the WpfWireframeVisual3DNode. // This is done with using the SetDepthBias method //SetDepthBias(dxViewportView, wireframeVisual3D, depthBias); parentViewport3D.Children.Add(wireframeVisual3D); _shownLineVisual3D = wireframeVisual3D; } _previousCameraDistance = sphereRadius * 4; targetPositionCamera.Distance = _previousCameraDistance; targetPositionCamera.Offset = new Vector3D(0, sphereRadius * 0.4, 0); }
private void UpdateCurrentTile(PointCloudTile tile) { if (tile == null) { return; } List <PointCloudTile> tilesToLoad = new List <PointCloudTile>(); int pointsToLoad = 0; Model3DGroup emptyModelGroup = new Model3DGroup(); emptyModelGroup.Freeze(); bool isDirty = false; int radius = 2; int xMin = Math.Max(0, tile.Col - radius); int xMax = Math.Min(tile.Col + radius + 1, CurrentTileSource.TileSet.Cols); int yMin = Math.Max(0, tile.Row - radius); int yMax = Math.Min(tile.Row + radius + 1, CurrentTileSource.TileSet.Rows); for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { PointCloudTile currentTile = CurrentTileSource.TileSet.GetTile(y, x); if (currentTile != null) { if (!m_loadedTiles.ContainsKey(currentTile)) { tilesToLoad.Add(currentTile); pointsToLoad += currentTile.PointCount; isDirty = true; } } } } PointCloudTile[] loadedTiles = m_loadedTiles.Keys.ToArray(); SortByDistanceFromTile(loadedTiles, tile); Array.Reverse(loadedTiles); // drop loaded tiles that are the farthest from the center int totalAllowedPoints = MAX_BUFFER_SIZE_BYTES / CurrentTileSource.PointSizeBytes; int loadedPoints = loadedTiles.Sum(t => t.PointCount); int potentialTotalPoints = loadedPoints + pointsToLoad; Dictionary <PointCloudTile, TileInfo3D> alteredTiles = new Dictionary <PointCloudTile, TileInfo3D>(); if (potentialTotalPoints > totalAllowedPoints) { int pointsToDrop = potentialTotalPoints - totalAllowedPoints; int i = 0; while (pointsToDrop > 0) { PointCloudTile currentTile = loadedTiles[i]; TileInfo3D tileInfo = m_tileInfo[currentTile]; GeometryModel3D model = m_loadedTiles[currentTile]; m_meshTileMap.Remove(model); m_loadedTiles.Remove(currentTile); //m_loadedTileBuffers.Remove(currentTile); // replace high-res tile with low-res geometry int modelIndex = tileInfo.Tile.ValidIndex; m_tileModelCollection[modelIndex] = tileInfo.LowResGeometry; // clear stitching m_stitchingModelCollection[modelIndex] = emptyModelGroup; tileInfo.ClearGeometry(); alteredTiles.Add(currentTile, tileInfo); pointsToDrop -= currentTile.PointCount; ++i; } } Jacere.Core.Geometry.Point3D centerOfMass = CurrentTileSource.CenterOfMass; PointCloudTile[] tilesToLoadArray = tilesToLoad.ToArray(); #warning sort so that disk reads are in order? or make a tile cache SortByDistanceFromTile(tilesToLoadArray, tile); foreach (PointCloudTile currentTile in tilesToLoadArray) { TileInfo3D tileInfo = m_tileInfo[currentTile]; CurrentTileSource.LoadTileGrid(currentTile, m_buffer, m_gridHighRes, m_quantizedGridHighRes); if (ENABLE_HEIGHT_EXAGGERATION) { m_gridHighRes.Multiply(m_heightExaggerationFactor, (float)centerOfMass.Z); } Jacere.Core.Geometry.Extent3D tileExtent = currentTile.Extent; MeshGeometry3D mesh = CurrentTileSource.GenerateMesh(m_gridHighRes, tileExtent); DiffuseMaterial material = new DiffuseMaterial(); if (USE_HIGH_RES_TEXTURE) { material.Brush = m_overviewTextureBrush; mesh.TextureCoordinates = MeshUtils.GeneratePlanarTextureCoordinates(mesh, m_overallCenteredExtent, MathUtils.ZAxis); } else { material.Brush = m_solidBrush; } material.Freeze(); GeometryModel3D geometryModel = new GeometryModel3D(mesh, material); geometryModel.Freeze(); // replace low-res tile with high-res geometry int modelIndex = tileInfo.Tile.ValidIndex; m_tileModelCollection[modelIndex] = geometryModel; // clear stitching m_stitchingModelCollection[modelIndex] = emptyModelGroup; tileInfo.UpdateGeometry(geometryModel, m_gridHighRes); alteredTiles.Add(currentTile, tileInfo); m_meshTileMap.Add(geometryModel, currentTile); m_loadedTiles.Add(currentTile, geometryModel); //m_loadedTileBuffers.Add(currentTile, inputBuffer); } // in the future, I could have a list of which tiles need to be checked for stitching updates // go through the stitching groups and replace any empty ones with the appropriate stitching if (ENABLE_STITCHING && isDirty) { PointCloudTile[] alteredTileArray = alteredTiles.Keys.ToArray(); foreach (PointCloudTile currentTile in alteredTileArray) { // this amount of clearing is excessive. I only want to clear one of the edges if (currentTile.Col < CurrentTileSource.TileSet.Cols - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row, currentTile.Col + 1); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.Left); } } if (currentTile.Row < CurrentTileSource.TileSet.Rows - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row + 1, currentTile.Col); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.Top); } } if (currentTile.Col < CurrentTileSource.TileSet.Cols - 1 && currentTile.Row < CurrentTileSource.TileSet.Rows - 1) { PointCloudTile adjacentTile = CurrentTileSource.TileSet.GetTile(currentTile.Row + 1, currentTile.Col + 1); if (adjacentTile != null && m_tileInfo.ContainsKey(adjacentTile)) { TileInfo3D adjacentTileInfo = m_tileInfo[adjacentTile]; if (!alteredTiles.ContainsKey(adjacentTile)) { alteredTiles.Add(adjacentTile, adjacentTileInfo); } m_stitchingModelCollection[adjacentTileInfo.Tile.ValidIndex] = emptyModelGroup; adjacentTileInfo.UpdateStitching(null, null, TileStitchingEdge.TopLeft); } } } foreach (KeyValuePair <PointCloudTile, TileInfo3D> kvp in alteredTiles) { int i = kvp.Value.Tile.ValidIndex; Model3DGroup stitchingGroup = m_stitchingModelCollection[i] as Model3DGroup; if (stitchingGroup.Children.Count == 0) { GeometryModel3D geometryModel = m_tileModelCollection[i] as GeometryModel3D; Model3DGroup newStitchingGroup = GenerateTileStitching(CurrentTileSource, kvp.Value); if (newStitchingGroup.Children.Count > 0) { m_stitchingModelCollection[i] = newStitchingGroup; } } } //for (int i = 0; i < m_stitchingModelCollection.Count; i++) //{ // Model3DGroup stitchingGroup = m_stitchingModelCollection[i] as Model3DGroup; // // this is an incorrect condition, but it won't be apparent until I get multi-res stitching // if (stitchingGroup.Children.Count < 3) // { // GeometryModel3D geometryModel = m_tileModelCollection[i] as GeometryModel3D; // PointCloudTile currentTile = m_meshTileMap[geometryModel]; // TileInfo3D currentTileInfo = m_tileInfo[currentTile]; // Model3DGroup newStitchingGroup = GenerateTileStitching(CurrentTileSource, currentTileInfo); // if (newStitchingGroup.Children.Count > 0) // m_stitchingModelCollection[i] = newStitchingGroup; // } //} } }
/// <summary> /// Reads the model from the specified stream. /// </summary> /// <param name="s">The stream.</param> /// <returns>The model.</returns> public override Model3DGroup Read(Stream s) { using (var reader = new BinaryReader(s)) { long length = reader.BaseStream.Length; // http://gpwiki.org/index.php/Loading_3ds_files // http://www.flipcode.com/archives/3DS_File_Loader.shtml // http://sandy.googlecode.com/svn/trunk/sandy/as3/branches/3.0.2/src/sandy/parser/Parser3DS.as var headerId = this.ReadChunkId(reader); if (headerId != ChunkID.MAIN3DS) { throw new FileFormatException("Unknown file"); } int headerSize = this.ReadChunkSize(reader); //if (headerSize != length) //{ // throw new FileFormatException("Incomplete file (file length does not match header)"); //} while (reader.BaseStream.Position < reader.BaseStream.Length) { var id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); switch (id) { case ChunkID.EDIT_MATERIAL: this.ReadMaterial(reader, size); break; case ChunkID.EDIT_OBJECT: this.ReadObject(reader, size); break; case ChunkID.EDIT3DS: case ChunkID.OBJ_CAMERA: case ChunkID.OBJ_LIGHT: case ChunkID.OBJ_TRIMESH: // don't read the whole chunk, read the sub-defines... break; default: // download the whole chunk this.ReadData(reader, size - 6); break; } } Model3DGroup mg = null; this.Dispatch( () => { mg = new Model3DGroup(); foreach (var m in this.meshes) { var model = m.CreateModel(); if (this.Freeze) { model.Freeze(); } mg.Children.Add(model); } if (this.Freeze) { mg.Freeze(); } }); return(mg); } }
private void SetLod(int index) { model = geometry.ReadGeometry(index); var meshes = GetMeshes(model).ToList(); TreeViewItems.Clear(); modelGroup.Children.Clear(); foreach (var region in model.Regions) { var regNode = new TreeItemModel { Header = region.Name, IsChecked = true }; foreach (var perm in region.Permutations) { var mesh = meshes.ElementAtOrDefault(perm.MeshIndex); if (mesh == null || perm.MeshCount <= 0) { continue; } var permNode = new TreeItemModel { Header = perm.Name, IsChecked = true }; regNode.Items.Add(permNode); var tGroup = new Transform3DGroup(); if (perm.TransformScale != 1) { var tform = new ScaleTransform3D(perm.TransformScale, perm.TransformScale, perm.TransformScale); tform.Freeze(); tGroup.Children.Add(tform); } if (!perm.Transform.IsIdentity) { var tform = new MatrixTransform3D(new Matrix3D { M11 = perm.Transform.M11, M12 = perm.Transform.M12, M13 = perm.Transform.M13, M21 = perm.Transform.M21, M22 = perm.Transform.M22, M23 = perm.Transform.M23, M31 = perm.Transform.M31, M32 = perm.Transform.M32, M33 = perm.Transform.M33, OffsetX = perm.Transform.M41, OffsetY = perm.Transform.M42, OffsetZ = perm.Transform.M43 }); tform.Freeze(); tGroup.Children.Add(tform); } Model3DGroup permGroup; if (tGroup.Children.Count == 0 && perm.MeshCount == 1) { permGroup = meshes[perm.MeshIndex]; } else { permGroup = new Model3DGroup(); for (int i = 0; i < perm.MeshCount; i++) { if (tGroup.Children.Count > 0) { (permGroup.Transform = tGroup).Freeze(); permGroup.Children.Add(meshes[perm.MeshIndex + i]); permGroup.Freeze(); } else { permGroup.Children.Add(meshes[perm.MeshIndex + i]); } } } permNode.Tag = new MeshTag(permGroup, perm); modelGroup.Children.Add(permGroup); } if (regNode.HasItems) { TreeViewItems.Add(regNode); } } renderer.ScaleToContent(new[] { modelGroup }); }
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(); }
public static Model3DGroup AddFieldMesh(PlanSetup planSetup, Beam beam, string status) { DiffuseMaterial collimatorMaterialStatic = new DiffuseMaterial(new SolidColorBrush(Colors.Green)); DiffuseMaterial collimatorMaterialVMAT = new DiffuseMaterial(new SolidColorBrush(Colors.GreenYellow)); if (status == "Collision") { collimatorMaterialStatic = new DiffuseMaterial(new SolidColorBrush(Colors.Red)); collimatorMaterialVMAT = new DiffuseMaterial(new SolidColorBrush(Colors.Red)); } if (status == "Warning") { collimatorMaterialStatic = new DiffuseMaterial(new SolidColorBrush(Colors.DarkOrange)); collimatorMaterialVMAT = new DiffuseMaterial(new SolidColorBrush(Colors.DarkOrange)); } DiffuseMaterial redMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Red)); DiffuseMaterial darkblueMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.DarkBlue)); var isoModelGroup = new Model3DGroup(); var collimatorMaterial = new DiffuseMaterial(new SolidColorBrush(Colors.Green)); var modelGroup = new Model3DGroup(); bool isVMAT = false; bool isStatic = false; bool isElectron = false; bool isSRSArc = false; var upDir = new Vector3D(0, -1, 0); var isoctr = GetIsocenter(beam); var iso3DMesh = CalculateIsoMesh(isoctr); if (beam.EnergyModeDisplayName.Contains("E")) { isElectron = true; } if (beam.EnergyModeDisplayName.Contains("SRS")) { isSRSArc = true; } if (beam.MLCPlanType.ToString() == "VMAT" || beam.Technique.Id.Contains("ARC")) { isVMAT = true; collimatorMaterial = collimatorMaterialVMAT; } if (beam.Technique.ToString().Contains("STATIC")) { isStatic = true; collimatorMaterial = collimatorMaterialStatic; } if (planSetup.TreatmentOrientation.ToString() == "HeadFirstProne") { upDir = new Vector3D(0, 1, 0); } MeshGeometry3D collimatorMesh = CalculateCollimatorMesh(beam, isoctr, isVMAT, isStatic, isElectron, isSRSArc); modelGroup.Children.Add(new GeometryModel3D { Geometry = collimatorMesh, Material = collimatorMaterial, BackMaterial = darkblueMaterial }); modelGroup.Children.Add(new GeometryModel3D { Geometry = iso3DMesh, Material = redMaterial, BackMaterial = redMaterial }); modelGroup.Freeze(); return(modelGroup); }
public ItemEditorViewModel( IManualTagEditor tagEdiotr, IItemService itemService, FileVersionListViewModel fileVersionList, INotificationCenterService notificationCenter, ILibraryManagementService libraryManagement, IFileItemLinkService fileItemLinkService, OpenFileCommand openFile, FileToClipboardCommand fileToClipboard, ISettingsService settingsService, IThumbnailManagementService thumbnailManagementService) { this.TagEditor = tagEdiotr; this._itemService = itemService; FileVersionList = fileVersionList; this.notificationCenter = notificationCenter; this.libraryManagement = libraryManagement; this.fileItemLinkService = fileItemLinkService; OpenFile = openFile; FileToClipboard = fileToClipboard; this.thumbnailManagementService = thumbnailManagementService; this.TagEditor.Editmode = true; this.TagEditor.CompletePool = true; this.TagEditor.PermitNewTags = true; this.disposables.Add(_selectedItemIdChanges); this.SelectedItemChanges = this._itemService .GetExtended(this.SelectedItemIdChanges) .TakeUntil(destroy); this.Save = new RelayCommand(_ => _save()); this.CreateThumbnail = new RelayCommand(_ => createThumbnail()); var selectedVersionChanges = this.WhenAnyValue(x => x.SelectedVersion).TakeUntil(destroy); var curLink = this.newLinks.Connect() .ChangeKey(link => link.Version) .WatchValue(selectedVersionChanges, link => link.Version); var curFileFilter = selectedVersionChanges.CombineLatest(SelectedItemChanges, (version, item) => new { version, item }) .Select( x => { return(new Func <VersionedFile, bool>((VersionedFile vFile) => x.version.HasValue && x.item.HasValue && (vFile.Version == x.version.Value) && (vFile.ItemId == x.item.Value.ItemId))); }); var files = this.fileItemLinkService.BuildversionedFiles(newLinks.Connect()); var curFiles = files.Filter(curFileFilter) .Select(x => x.FirstOrDefault(x => x.Reason != ChangeReason.Remove).Current.ToNullable()); this._selectedFiles = curFiles .TakeUntil(destroy) .ToProperty(this, nameof(SelectedFiles)); this._cameraRotationMode = settingsService .WhenAnyValue(x => x.CameraRotationMode) .Select(x => (CameraRotationMode)x) .ToProperty(this, nameof(CameraRotationMode)); _cameraRotationMode.DisposeWith(disposables); DateTime mostRecentRequest = default; curFiles .ObserveOn(RxApp.TaskpoolScheduler) .TakeUntil(destroy) .Select(files => { mostRecentRequest = DateTime.Now; var orderTime = DateTime.Now; if (!files.HasValue || files?.File.AbsolutePath == null) { return(null); } this.MaterialBrush = new SolidColorBrush(Colors.LightGray); var mat = new DiffuseMaterial(this.MaterialBrush); ModelImporter importer = new ModelImporter() { DefaultMaterial = mat }; Model3DGroup model = importer.Load(files.Value.File.AbsolutePath); model.SetMaterial(mat); model.PlaceAtOrigin(); model.Freeze(); return(new { timestamp = mostRecentRequest, model }); }) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => { this.ViewportContent = null; if (x == null) { return; } LoadingModel = true; RxApp.MainThreadScheduler.Schedule(x.model, (_, model) => { if (x.timestamp == mostRecentRequest) { this.ViewportContent = model; LoadingModel = false; } return(null); }); }); var linkFilter = selectedVersionChanges.Select(version => new Func <FileItemLink, bool>(link => link.Version == version) ); var selectedLinkChanges = this.newLinks .Connect() .RemoveKey() .Filter(linkFilter) .Select(x => x.FirstOrDefault().Item.Current); this.SelectedItemChanges.Subscribe( LoadItem, ex => this.notificationCenter.OnError(ex)); }
private IEnumerable <Model3DGroup> GetMeshes(IGeometryModel model) { var indexes = model.Regions.SelectMany(r => r.Permutations) .SelectMany(p => Enumerable.Range(p.MeshIndex, p.MeshCount)) .Distinct().ToList(); var materials = GetMaterials(model).ToList(); for (int i = 0; i < model.Meshes.Count; i++) { var mesh = model.Meshes[i]; if (mesh.Submeshes.Count == 0 || !indexes.Contains(i)) { yield return(null); continue; } var mGroup = new Model3DGroup(); var tGroup = new Transform3DGroup(); var texMatrix = Matrix.Identity; if (mesh.BoundsIndex >= 0) { var bounds = model.Bounds[mesh.BoundsIndex.Value]; texMatrix = new Matrix { M11 = bounds.UBounds.Length, M22 = bounds.VBounds.Length, OffsetX = bounds.UBounds.Min, OffsetY = bounds.VBounds.Min }; var transform = new Matrix3D { M11 = bounds.XBounds.Length, M22 = bounds.YBounds.Length, M33 = bounds.ZBounds.Length, OffsetX = bounds.XBounds.Min, OffsetY = bounds.YBounds.Min, OffsetZ = bounds.ZBounds.Min }; var tform = new MatrixTransform3D(transform); tform.Freeze(); tGroup.Children.Add(tform); } foreach (var sub in mesh.Submeshes) { try { var geom = new MeshGeometry3D(); var indices = mesh.Indicies.Skip(sub.IndexStart).Take(sub.IndexLength).ToList(); if (mesh.IndexFormat == IndexFormat.TriangleStrip) { indices = indices.Unstrip().ToList(); } var vertStart = indices.Min(); var vertLength = indices.Max() - vertStart + 1; var verts = mesh.Vertices.Skip(vertStart).Take(vertLength); var positions = verts.Select(v => new Point3D(v.Position[0].X, v.Position[0].Y, v.Position[0].Z)); (geom.Positions = new Point3DCollection(positions)).Freeze(); (geom.TriangleIndices = new Int32Collection(indices.Select(j => j - vertStart))).Freeze(); if (mesh.Vertices[0].TexCoords.Count > 0) { var texcoords = verts.Select(v => new Point(v.TexCoords[0].X, v.TexCoords[0].Y)).ToArray(); if (!texMatrix.IsIdentity) { texMatrix.Transform(texcoords); } (geom.TextureCoordinates = new PointCollection(texcoords)).Freeze(); } if (mesh.Vertices[0].Normal.Count > 0) { var normals = verts.Select(v => new Vector3D(v.Normal[0].X, v.Normal[0].Y, v.Normal[0].Z)); (geom.Normals = new Vector3DCollection(normals)).Freeze(); } var mat = materials.ElementAtOrDefault(sub.MaterialIndex) ?? ErrorMaterial; var subGroup = new GeometryModel3D(geom, mat) { BackMaterial = mat }; subGroup.Freeze(); mGroup.Children.Add(subGroup); } catch { } } (mGroup.Transform = tGroup).Freeze(); mGroup.Freeze(); yield return(mGroup); } }