public async Task AutoArrangeChildrenTests() { // arrange a single item around the origin { var scene = new InteractiveScene(); Object3D cube1; scene.Children.Add(cube1 = new Object3D() { Mesh = PlatonicSolids.CreateCube(20, 20, 20), Matrix = Matrix4X4.CreateTranslation(34, 22, 10) }); Assert.IsTrue(new AxisAlignedBoundingBox(24, 12, 0, 44, 32, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); await scene.AutoArrangeChildren(Vector3.Zero); Assert.IsTrue(new AxisAlignedBoundingBox(-10, -10, 0, 10, 10, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); } // arrange a single item around a typical bed center { var scene = new InteractiveScene(); Object3D cube1; scene.Children.Add(cube1 = new Object3D() { Mesh = PlatonicSolids.CreateCube(20, 20, 20), Matrix = Matrix4X4.CreateTranslation(34, 22, 10) }); Assert.IsTrue(new AxisAlignedBoundingBox(24, 12, 0, 44, 32, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); await scene.AutoArrangeChildren(new Vector3(100, 100, 0)); Assert.IsTrue(new AxisAlignedBoundingBox(90, 90, 0, 110, 110, 20).Equals(cube1.GetAxisAlignedBoundingBox(), .001)); } // arrange 4 items { var scene = new InteractiveScene(); for (int i = 0; i < 4; i++) { scene.Children.Add(new Object3D() { Mesh = PlatonicSolids.CreateCube(20, 20, 20), Matrix = Matrix4X4.CreateTranslation(i * 134, i * -122, 10) }); } var sceneAabb = scene.GetAxisAlignedBoundingBox(); Assert.Greater(sceneAabb.XSize, 60); Assert.Greater(sceneAabb.YSize, 60); await scene.AutoArrangeChildren(Vector3.Zero); sceneAabb = scene.GetAxisAlignedBoundingBox(); Assert.Less(sceneAabb.XSize, 60); Assert.Less(sceneAabb.YSize, 60); } // arrange 4 items, starting with 1 selected { var scene = new InteractiveScene(); Object3D child = null; for (int i = 0; i < 4; i++) { scene.Children.Add(child = new Object3D() { Mesh = PlatonicSolids.CreateCube(20, 20, 20), Matrix = Matrix4X4.CreateTranslation(i * 134, i * -122, 10) }); } scene.SelectedItem = child; var sceneAabb = scene.GetAxisAlignedBoundingBox(); Assert.Greater(sceneAabb.XSize, 60); Assert.Greater(sceneAabb.YSize, 60); await scene.AutoArrangeChildren(Vector3.Zero); sceneAabb = scene.GetAxisAlignedBoundingBox(); Assert.Less(sceneAabb.XSize, 60); Assert.Less(sceneAabb.YSize, 60); } }
public override void Load() { var library = ApplicationController.Instance.Library; long index = DateTime.Now.Ticks; var libraryItems = new List <GeneratorItem>() { new GeneratorItem( () => "Cube".Localize(), async() => await CubeObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Pyramid".Localize(), async() => await PyramidObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Wedge".Localize(), async() => await WedgeObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Half Wedge".Localize(), async() => await HalfWedgeObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Text".Localize(), async() => await TextObject3D.Create()) { DateCreated = new System.DateTime(index++) }, #if DEBUG new GeneratorItem( () => "Text2".Localize(), async() => await TextPathObject3D.Create()) { DateCreated = new System.DateTime(index++) }, #endif new GeneratorItem( () => "Cylinder".Localize(), async() => await CylinderObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Cone".Localize(), async() => await ConeObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Half Cylinder".Localize(), async() => await HalfCylinderObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Torus".Localize(), async() => await TorusObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Ring".Localize(), async() => await RingObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Sphere".Localize(), async() => await SphereObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Half Sphere".Localize(), async() => await HalfSphereObject3D.Create()) { DateCreated = new System.DateTime(index++) }, new GeneratorItem( () => "Image Converter".Localize(), () => { // Construct an image var imageObject = new ImageObject3D() { AssetPath = AggContext.StaticData.ToAssetPath(Path.Combine("Images", "mh-logo.png")) }; // Construct a scene var tempScene = new InteractiveScene(); tempScene.Children.Add(imageObject); tempScene.SelectedItem = imageObject; // Invoke ImageConverter operation, passing image and scene ApplicationController.Instance.Graph.Operations["ImageConverter"].Operation(imageObject, tempScene); // Return replacement object constructed in ImageConverter operation var constructedComponent = tempScene.SelectedItem; tempScene.Children.Remove(constructedComponent); return(Task.FromResult <IObject3D>(constructedComponent)); }) { DateCreated = new System.DateTime(index++) }, }; string title = "Primitive Shapes".Localize(); foreach (var item in libraryItems) { item.Category = title; Items.Add(item); } }
public virtual void WrapSelectedItemAndSelect(InteractiveScene scene) { var items = scene.GetSelectedItems(); var parent = items.First().Parent; RebuildLocks parentLock = (parent == null) ? null : parent.RebuilLockAll(); var firstChild = new Object3D(); this.Children.Add(firstChild); // if the items we are replacing are already in a list if (parent != null) { if (scene.UndoBuffer != null) { foreach (var item in items) { firstChild.Children.Add(item.Clone()); } var replace = new ReplaceCommand(items, new[] { this }); scene.UndoBuffer.AddAndDo(replace); } else { parent.Children.Modify(list => { foreach (var item in items) { list.Remove(item); firstChild.Children.Add(item); } list.Add(this); }); } } else // just add them { firstChild.Children.Modify(list => { list.AddRange(items); }); } parentLock?.Dispose(); // and select this var rootItem = this.Parents().Where(i => scene.Children.Contains(i)).FirstOrDefault(); if (rootItem != null) { scene.SelectedItem = rootItem; } scene.SelectedItem = this; parent?.Invalidate(new InvalidateArgs(parent, InvalidateType.Children)); }
public InteractiveScene SampleScene() { Object3D group; var scene = new InteractiveScene() { Color = Color.Black, MaterialIndex = this.RootMaterialIndex, OutputType = this.RootOutputType }; var supergroup = new Object3D() { Name = "SuperGroup", Color = Color.Violet, MaterialIndex = this.SuperGroupMaterialIndex, Matrix = this.SuperGroupMatrix, OutputType = this.SuperGroupOutputType }; scene.Children.Add(supergroup); group = new Object3D() { Name = "GroupA", Color = Color.Pink, MaterialIndex = this.GroupMaterialIndex, OutputType = this.GroupOutputType }; supergroup.Children.Add(group); group.Children.Add(new Object3D { Name = nameof(Color.Red), Color = Color.Red, MaterialIndex = this.RedMaterialIndex, Matrix = this.RedMatrix, OutputType = this.RedOutputType }); group = new Object3D() { Name = "GroupB", Color = Color.Pink, MaterialIndex = this.GroupMaterialIndex, OutputType = this.GroupOutputType }; supergroup.Children.Add(group); group.Children.Add(new Object3D { Name = nameof(Color.Green), Color = Color.Green, MaterialIndex = this.GreenMaterialIndex, Matrix = this.GreenMatrix, OutputType = this.GreenOutputType }); group = new Object3D() { Name = "GroupB", Color = Color.Pink, MaterialIndex = this.GroupMaterialIndex, OutputType = this.GroupOutputType }; supergroup.Children.Add(group); group.Children.Add(new Object3D { Name = nameof(Color.Blue), Color = Color.Blue, MaterialIndex = this.BlueMaterialIndex, Matrix = this.BlueMatrix, OutputType = this.BlueOutputType }); return(scene); }
public GenerateSupportPanel(ThemeConfig theme, InteractiveScene scene) : base(FlowDirection.TopToBottom) { supportGenerator = new SupportGenerator(scene); this.theme = theme; this.VAnchor = VAnchor.Fit; this.HAnchor = HAnchor.Absolute; this.Width = 300; this.BackgroundColor = theme.BackgroundColor; this.Padding = theme.DefaultContainerPadding; // Add an editor field for the SupportGenerator.SupportType PropertyInfo propertyInfo = typeof(SupportGenerator).GetProperty(nameof(SupportGenerator.SupportType)); var editor = PublicPropertyEditor.CreatePropertyEditor( new EditableProperty(propertyInfo, supportGenerator), null, new PPEContext(), theme); if (editor != null) { this.AddChild(editor); } // put in support pillar size var pillarSizeField = new DoubleField(theme); pillarSizeField.Initialize(0); pillarSizeField.DoubleValue = supportGenerator.PillarSize; pillarSizeField.ValueChanged += (s, e) => { supportGenerator.PillarSize = pillarSizeField.DoubleValue; // in case it was corrected set it back again if (pillarSizeField.DoubleValue != supportGenerator.PillarSize) { pillarSizeField.DoubleValue = supportGenerator.PillarSize; } }; var pillarRow = PublicPropertyEditor.CreateSettingsRow("Pillar Size".Localize(), "The width and depth of the support pillars".Localize(), theme); pillarRow.AddChild(pillarSizeField.Content); this.AddChild(pillarRow); // put in the angle setting var overHangField = new DoubleField(theme); overHangField.Initialize(0); overHangField.DoubleValue = supportGenerator.MaxOverHangAngle; overHangField.ValueChanged += (s, e) => { supportGenerator.MaxOverHangAngle = overHangField.DoubleValue; // in case it was corrected set it back again if (overHangField.DoubleValue != supportGenerator.MaxOverHangAngle) { overHangField.DoubleValue = supportGenerator.MaxOverHangAngle; } }; var overHangRow = PublicPropertyEditor.CreateSettingsRow("Overhang Angle".Localize(), "The angle to generate support for".Localize(), theme); overHangRow.AddChild(overHangField.Content); this.AddChild(overHangRow); // Button Row var buttonRow = new FlowLayoutWidget() { HAnchor = HAnchor.Stretch, VAnchor = VAnchor.Fit, Margin = new BorderDouble(top: 5) }; this.AddChild(buttonRow); buttonRow.AddChild(new HorizontalSpacer()); // add 'Remove Auto Supports' button var removeButton = theme.CreateDialogButton("Remove".Localize()); removeButton.ToolTipText = "Remove all auto generated supports".Localize(); removeButton.Click += (s, e) => supportGenerator.RemoveExisting(); buttonRow.AddChild(removeButton); // add 'Generate Supports' button var generateButton = theme.CreateDialogButton("Generate".Localize()); generateButton.ToolTipText = "Find and create supports where needed".Localize(); generateButton.Click += (s, e) => Rebuild(); buttonRow.AddChild(generateButton); theme.ApplyPrimaryActionStyle(generateButton); }
public InspectedItemDrawable(ISceneContext sceneContext) { this.scene = sceneContext.Scene; }
public SceneTraceDataDrawable(ISceneContext sceneContext) { this.sceneContext = sceneContext; this.scene = sceneContext.Scene; }
public SupportGenerator(InteractiveScene scene, double minimumSupportHeight) { this.minimumSupportHeight = minimumSupportHeight; this.scene = scene; }
// TODO: Figure out how best to collapse the InsertionGroup after the load task completes public InsertionGroupObject3D(IEnumerable <ILibraryItem> items, View3DWidget view3DWidget, InteractiveScene scene, Vector2 bedCenter, Func <bool> dragOperationActive, bool trackSourceFiles = false) { if (items == null) { return; } // Add a temporary placeholder to give us some bounds this.scene = scene; this.view3DWidget = view3DWidget; this.LoadingItemsTask = Task.Run((Func <Task>)(async() => { var newItemOffset = Vector2.Zero; if (dragOperationActive != null && !dragOperationActive()) { newItemOffset = bedCenter; } var offset = Matrix4X4.Identity; // Add the placeholder 'Loading...' object var placeholderItem = new Object3D() { Mesh = placeHolderMesh, Matrix = Matrix4X4.Identity, Parent = this }; this.Children.Add(placeholderItem); // Filter to content file types only foreach (var item in items.Where(item => item.IsContentFileType()).ToList()) { // Acquire var progressControl = new DragDropLoadProgress(view3DWidget, null); // Position at accumulating offset placeholderItem.Matrix *= Matrix4X4.CreateTranslation(newItemOffset.X, (double)newItemOffset.Y, 0); placeholderItem.Visible = true; progressControl.TrackingObject = placeholderItem; var loadedItem = await item.CreateContent(progressControl.ProgressReporter); if (loadedItem != null) { var aabb = loadedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity); // lets move the cube to the center of the loaded thing placeholderItem.Matrix *= Matrix4X4.CreateTranslation(-10 + aabb.XSize / 2, 0, 0); placeholderItem.Visible = false; // Copy scale/rotation/translation from the source and Center loadedItem.Matrix = loadedItem.Matrix * Matrix4X4.CreateTranslation((double)-aabb.Center.X, (double)-aabb.Center.Y, (double)-aabb.minXYZ.Z) * placeholderItem.Matrix; // check if the item has 0 height (it is probably an image) if (loadedItem.ZSize() == 0) { // raise it up a bit so it is not z fighting with the bed loadedItem.Matrix *= Matrix4X4.CreateTranslation(0, 0, .1); } loadedItem.Color = loadedItem.Color; // Set mesh path if tracking requested if (trackSourceFiles && item is FileSystemFileItem fileItem && item.IsMeshFileType()) { loadedItem.MeshPath = fileItem.Path; } // Notification should force invalidate and redraw //progressReporter?.Invoke(1, ""); this.Children.Add(loadedItem); loadedItem.MakeNameNonColliding(); // Wait for content to load // Adjust next item position // TODO: do something more interesting than increment in x newItemOffset.X = loadedItem.GetAxisAlignedBoundingBox(Matrix4X4.Identity).XSize / 2 + 10; } progressControl.ProgressReporter(1.3, ""); } this.Children.Remove(placeholderItem); this.ContentAcquired = true; ContentLoaded?.Invoke(this, null); if (dragOperationActive != null && !dragOperationActive()) { this.Collapse(); } this.Invalidate(new InvalidateArgs(this, InvalidateType.Content)); })); }