private void UpdateLines() { var sphereMesh = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 100, Convert.ToInt32(SegmentsSlider.Value)); GeometryModel3D wireframeModel = Ab3d.Models.WireframeFactory.CreateWireframe(sphereMesh.Geometry, 1, Colors.White, MainViewport); MainModel3DGroup.Children.Clear(); MainModel3DGroup.Children.Add(wireframeModel); // After the line is connected to Viewport3D we can create its geometry. // This is automatically done with LinesUpdater in its Rendering event handler. // But to get the linesGeometry.Positions.Count we can call the Refresh method manually to recreate the Geometry. Ab3d.Utilities.LinesUpdater.Instance.Refresh(); PositionsTextBlock.Text = string.Format("Sphere positions count: {0}", sphereMesh.Geometry.Positions.Count); var linesGeometry = wireframeModel.Geometry as MeshGeometry3D; if (linesGeometry == null) { LinesTextBlock.Text = ""; } else { LinesTextBlock.Text = string.Format("3D Line Positions count: {0:0}", linesGeometry.Positions.Count / 4); // 4 positions for one line } FpsMeter1.Reset(); // Resets the average }
public BooleanOperationsSample() { InitializeComponent(); var boxMesh = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(100, 100, 100), 1, 1, 1).Geometry; var sphereMesh = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 65, 16).Geometry; // Note that we set processOnlyIntersectingTriangles to false because boxMesh and sphereMesh are almost the same size and // therefore all triangles need to be processes. With false value we skip checking which triangles are intersecting. // If the sphereMesh would be much smaller than it is recommended to set that to true (this is also the default value so we can skip that). // See the next (AdvancedBooleanOperations) for more info about that. // Subtract var subtractedMesh = Ab3d.Utilities.MeshBooleanOperations.Subtract(boxMesh, sphereMesh, processOnlyIntersectingTriangles: false); ShowMesh(subtractedMesh, -150); // Intersect var intersectedMesh = Ab3d.Utilities.MeshBooleanOperations.Intersect(boxMesh, sphereMesh, processOnlyIntersectingTriangles: false); ShowMesh(intersectedMesh, 0); //Union var unionMesh = Ab3d.Utilities.MeshBooleanOperations.Union(boxMesh, sphereMesh, processOnlyIntersectingTriangles: false); ShowMesh(unionMesh, 150); // SEE ALSO: // AdvancedBooleanOperations.xaml.cs // UseCases/ModelingWithBooleanOperations.xaml.cs // Utilities/TextureCoordinatesGeneratorSample (to generate texture coordinates that are lost with boolean operations) }
private void CreateInstances() { MeshGeometry3D meshGeometry3D; double modelScaleFactor; if (MeshTypeComboBox.SelectedIndex == 2) // Bunnies { // Load standard Standfor Bunny model (res3) with 11533 position meshGeometry3D = LoadMeshFromObjFile("bun_zipper_res3.obj"); var bounds = meshGeometry3D.Bounds; double diagonalSize = Math.Sqrt(bounds.SizeX * bounds.SizeX + bounds.SizeY * bounds.SizeY + bounds.SizeZ * bounds.SizeZ); modelScaleFactor = 20 / diagonalSize; // Scale model so that its diagonal is 20 units big } else if (MeshTypeComboBox.SelectedIndex == 1) // Spheres { // Sphere with 382 meshGeometry3D = new Ab3d.Meshes.SphereMesh3D(centerPosition: new Point3D(0, 0, 0), radius: 5, segments: 20, generateTextureCoordinates: false).Geometry; modelScaleFactor = 1; } else { // Box with 24 positions (for each corner we need 3 positions to create sharp edges - we need 3 normal vectors for each edge) meshGeometry3D = new Ab3d.Meshes.BoxMesh3D(centerPosition: new Point3D(0, 0, 0), size: new Size3D(10, 10, 10), xSegments: 1, ySegments: 1, zSegments: 1).Geometry; modelScaleFactor = 1; } int selectedInstancesYCount = GetSelectedInstancesYCount(); bool useTransparency = UseTransparencyCheckBox.IsChecked ?? false; float alphaColor = useTransparency ? 0.3f : 1.0f; // When we use transparency, we set alpha color to 0.3 (we also need to set UseAlphaBlend to true - see below) // The following method prepare InstanceData array with data for each instance (WorldMatrix and Color) InstanceData[] instancedData = CreateInstancesData(new Point3D(0, 200, 0), new Size3D(400, 400, 400), (float)modelScaleFactor, 20, selectedInstancesYCount, 20, useTransparency); // Create InstancedGeometryVisual3D with selected meshGeometry and InstancesData var instancedMeshGeometryVisual3D = new InstancedMeshGeometryVisual3D(meshGeometry3D); instancedMeshGeometryVisual3D.InstancesData = instancedData; // When we use transparency, we also need to set UseAlphaBlend to true instancedMeshGeometryVisual3D.UseAlphaBlend = useTransparency; // If we would only change the InstancedData we would need to call Update method (but here this is not needed because we have set the data for the first time) //_instancedGeometryVisual3D.Update(); ObjectsPlaceholder.Children.Clear(); ObjectsPlaceholder.Children.Add(instancedMeshGeometryVisual3D); // Update statistics: //PositionsPerMeshTextBlock.Text = string.Format("Positions per mesh: {0:#,##0}", meshGeometry3D.Positions.Count); TotalTextBlock.Text = string.Format("Total positions: {0:#,##0} * {1:#,##0} = {2:#,##0}", meshGeometry3D.Positions.Count, 20 * 20 * selectedInstancesYCount, meshGeometry3D.Positions.Count * selectedInstancesYCount * 20 * 20); }
public BooleanOperationsSample() { InitializeComponent(); var boxMesh = new Ab3d.Meshes.BoxMesh3D(new Point3D(0, 0, 0), new Size3D(100, 100, 100), 1, 1, 1).Geometry; var sphereMesh = new Ab3d.Meshes.SphereMesh3D(new Point3D(0, 0, 0), 65, 16).Geometry; // Subtract var subtractedMesh = Ab3d.Utilities.MeshBooleanOperations.Subtract(boxMesh, sphereMesh); ShowMesh(subtractedMesh, -150); // Intersect var intersectedMesh = Ab3d.Utilities.MeshBooleanOperations.Intersect(boxMesh, sphereMesh); ShowMesh(intersectedMesh, 0); //Union var unionMesh = Ab3d.Utilities.MeshBooleanOperations.Union(boxMesh, sphereMesh); ShowMesh(unionMesh, 150); }