Working on mesh wrapper and rebuild issues

This commit is contained in:
Lars Brubaker 2018-05-30 16:42:17 -07:00
parent a0ff7fa653
commit 25883fc0bc
18 changed files with 247 additions and 79 deletions

View file

@ -29,11 +29,14 @@ either expressed or implied, of the FreeBSD Project.
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using System;
namespace MatterHackers.MatterControl.CustomWidgets
{
public class LeftResizeContainer : FlowLayoutWidget
{
public event EventHandler Resized;
private double downWidth = 0;
private bool mouseDownOnBar = false;
private double mouseDownX;
@ -65,6 +68,11 @@ namespace MatterHackers.MatterControl.CustomWidgets
}
}
protected virtual void OnResized(EventArgs e)
{
this.Resized?.Invoke(this, e);
}
public override void OnDraw(Graphics2D graphics2D)
{
graphics2D.FillRectangle(LocalBounds.Left, LocalBounds.Bottom, LocalBounds.Left + this.SplitterWidth, LocalBounds.Top, this.SpliterBarColor);
@ -97,7 +105,15 @@ namespace MatterHackers.MatterControl.CustomWidgets
public override void OnMouseUp(MouseEventArgs mouseEvent)
{
var mouseUpX = TransformToScreenSpace(mouseEvent.Position).X;
if(mouseDownOnBar
&& mouseUpX != mouseDownX)
{
OnResized(null);
}
mouseDownOnBar = false;
base.OnMouseUp(mouseEvent);
}
}

View file

@ -328,8 +328,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType == InvalidateType.Content
|| invalidateType.InvalidateType == InvalidateType.Matrix)
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Content)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildSuspended)
{

View file

@ -35,6 +35,7 @@ using System.Threading;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.DataConverters3D;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.PartPreviewWindow.View3D;
@ -57,6 +58,7 @@ namespace MatterHackers.MatterControl.DesignTools
public CurveObject3D()
{
Name = "Curve".Localize();
}
public override void Rebuild(UndoBuffer undoBuffer)
@ -167,9 +169,9 @@ namespace MatterHackers.MatterControl.DesignTools
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType == InvalidateType.Content
|| invalidateType.InvalidateType == InvalidateType.Matrix
|| invalidateType.InvalidateType == InvalidateType.Mesh)
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Content)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildSuspended)
{

View file

@ -109,8 +109,9 @@ namespace MatterHackers.MatterControl.DesignTools.Operations
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType == InvalidateType.Content
|| invalidateType.InvalidateType == InvalidateType.Matrix)
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Content)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildSuspended)
{

View file

@ -59,8 +59,6 @@ namespace MatterHackers.MatterControl.DesignTools
var currentMatrix = Matrix;
Matrix = Matrix4X4.Identity;
var meshWrapper = this.WrappedObjects();
var aabb = this.GetAxisAlignedBoundingBox();
foreach (var items in this.WrappedObjects())
@ -91,11 +89,11 @@ namespace MatterHackers.MatterControl.DesignTools
transformedMesh.MarkAsChanged();
transformedMesh.CalculateNormals();
// set the matrix back
Matrix = currentMatrix;
}
// set the matrix back
Matrix = currentMatrix;
ResumeRebuild();
base.Invalidate(new InvalidateArgs(this, InvalidateType.Content));
@ -103,9 +101,9 @@ namespace MatterHackers.MatterControl.DesignTools
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType == InvalidateType.Content
|| invalidateType.InvalidateType == InvalidateType.Matrix
|| invalidateType.InvalidateType == InvalidateType.Mesh)
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Content)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildSuspended)
{

View file

@ -224,14 +224,18 @@ namespace MatterHackers.MatterControl.CustomWidgets
// TODO: Resolve and implement
// Allow the container to draw an overlay - use signal interface or add method to interface?
//var iconWithOverlay = ActiveContainer.DrawOverlay()
if (this.imageWidget != null)
if (thumbnail != null
&& (this.imageWidget.Image == null
|| !thumbnail.Equals(this.imageWidget.Image, 5)))
{
this.imageWidget.Image = thumbnail;
}
this.ImageSet?.Invoke(this, null);
this.ImageSet?.Invoke(this, null);
this.Invalidate();
this.Invalidate();
}
}
}

View file

@ -94,11 +94,11 @@ namespace MatterHackers.GCodeVisualizer
List<RenderFeatureBase> renderFeaturesForLayer = renderFeatures[layerToCreate];
int startRenderIndex = gCodeFileToDraw.GetInstructionIndexAtLayer(layerToCreate);
int startRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate);
int endRenderIndex = gCodeFileToDraw.LineCount - 1;
if (layerToCreate < gCodeFileToDraw.LayerCount - 1)
{
endRenderIndex = gCodeFileToDraw.GetInstructionIndexAtLayer(layerToCreate + 1);
endRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate + 1);
}
for (int instructionIndex = startRenderIndex; instructionIndex < endRenderIndex; instructionIndex++)

View file

@ -70,7 +70,7 @@ namespace MatterControl.Printing
public abstract double GetFilamentWeightGrams(double filamentDiameterMm, double density);
public abstract int GetInstructionIndexAtLayer(int layerIndex);
public abstract int GetFirstLayerInstruction(int layerIndex);
public abstract double GetLayerHeight(int layerIndex);

View file

@ -173,7 +173,7 @@ namespace MatterControl.Printing
return 100;
}
public override int GetInstructionIndexAtLayer(int layerIndex)
public override int GetFirstLayerInstruction(int layerIndex)
{
return 0;
}

View file

@ -53,6 +53,8 @@ namespace MatterControl.Printing
private List<double> layerHeights = new List<double>();
private List<PrinterMachineInstruction> GCodeCommandQueue = new List<PrinterMachineInstruction>();
private bool foundFirstLayerMarker;
public GCodeMemoryFile(bool gcodeHasExplicitLayerChangeInfo = false)
{
this.gcodeHasExplicitLayerChangeInfo = gcodeHasExplicitLayerChangeInfo;
@ -75,7 +77,7 @@ namespace MatterControl.Printing
cancellationToken, null);
if (loadedFile != null)
{
this.IndexOfChangeInZ = loadedFile.IndexOfChangeInZ;
this.IndexOfLayerStart = loadedFile.IndexOfLayerStart;
this.center = loadedFile.center;
this.parsingLastZ = loadedFile.parsingLastZ;
this.GCodeCommandQueue = loadedFile.GCodeCommandQueue;
@ -91,7 +93,7 @@ namespace MatterControl.Printing
public override void Clear()
{
IndexOfChangeInZ.Clear();
IndexOfLayerStart.Clear();
GCodeCommandQueue.Clear();
}
@ -104,11 +106,11 @@ namespace MatterControl.Printing
public void Insert(int insertIndex, PrinterMachineInstruction printerMachineInstruction)
{
for (int i = 0; i < IndexOfChangeInZ.Count; i++)
for (int i = 0; i < IndexOfLayerStart.Count; i++)
{
if (insertIndex < IndexOfChangeInZ[i])
if (insertIndex < IndexOfLayerStart[i])
{
IndexOfChangeInZ[i]++;
IndexOfLayerStart[i]++;
}
}
@ -240,6 +242,9 @@ namespace MatterControl.Printing
GCodeMemoryFile loadedGCodeFile = new GCodeMemoryFile(gcodeHasExplicitLayerChangeInfo);
// Add the first start index (of 0)
loadedGCodeFile.IndexOfLayerStart.Add(0);
int crCount = CountNumLines(gCodeString);
int lineIndex = 0;
foreach (string outputString in CustomSplit(gCodeString, '\n'))
@ -270,16 +275,16 @@ namespace MatterControl.Printing
case ';':
if (gcodeHasExplicitLayerChangeInfo && IsLayerChange(lineString))
{
// If we just found the start of the file and we have not added any layers yet
// Make sure we start at the beginging
if (lineString.EndsWith("LAYER:0")
&& loadedGCodeFile.IndexOfChangeInZ.Count == 0)
// The first "layer" statement in the gcode file is after the start gcode and we ignore
// it because we already added a marker for the start of the file (before start gcode)
if (!loadedGCodeFile.foundFirstLayerMarker)
{
loadedGCodeFile.IndexOfChangeInZ.Add(0);
break;
loadedGCodeFile.foundFirstLayerMarker = true;
}
else
{
loadedGCodeFile.IndexOfLayerStart.Add(loadedGCodeFile.GCodeCommandQueue.Count);
}
loadedGCodeFile.IndexOfChangeInZ.Add(loadedGCodeFile.GCodeCommandQueue.Count);
}
else if (lineString.StartsWith("; LAYER_HEIGHT:"))
{
@ -437,11 +442,11 @@ namespace MatterControl.Printing
return 100;
}
public override int GetInstructionIndexAtLayer(int layerIndex)
public override int GetFirstLayerInstruction(int layerIndex)
{
if (layerIndex < IndexOfChangeInZ.Count - 1)
if (layerIndex < IndexOfLayerStart.Count)
{
return IndexOfChangeInZ[layerIndex];
return IndexOfLayerStart[layerIndex];
}
// else return the last instruction
@ -450,11 +455,11 @@ namespace MatterControl.Printing
public override int LayerCount
{
get { return IndexOfChangeInZ.Count; }
get { return IndexOfLayerStart.Count; }
}
public HashSet<float> Speeds { get; private set; }
public List<int> IndexOfChangeInZ { get; set; } = new List<int>();
public List<int> IndexOfLayerStart { get; set; } = new List<int>();
private void ParseMLine(string lineString, PrinterMachineInstruction processingMachineState)
{
@ -692,10 +697,10 @@ namespace MatterControl.Printing
if (!gcodeHasExplicitLayerChangeInfo)
{
if (processingMachineState.Z != parsingLastZ || IndexOfChangeInZ.Count == 0)
if (processingMachineState.Z != parsingLastZ || IndexOfLayerStart.Count == 0)
{
// if we changed z or there is a movement and we have never started a layer index
IndexOfChangeInZ.Add(GCodeCommandQueue.Count);
IndexOfLayerStart.Add(GCodeCommandQueue.Count);
}
}
parsingLastZ = processingMachineState.Position.Z;
@ -919,9 +924,9 @@ namespace MatterControl.Printing
return 0;
}
if (IndexOfChangeInZ.Count > 2)
if (IndexOfLayerStart.Count > 2)
{
return GCodeCommandQueue[IndexOfChangeInZ[2]].Z - GCodeCommandQueue[IndexOfChangeInZ[1]].Z;
return GCodeCommandQueue[IndexOfLayerStart[2]].Z - GCodeCommandQueue[IndexOfLayerStart[1]].Z;
}
return .5;
@ -942,9 +947,9 @@ namespace MatterControl.Printing
if (instructionIndex >= 0
&& instructionIndex <= LineCount)
{
for(var i = IndexOfChangeInZ.Count - 1; i >=0; i--)
for(var i = IndexOfLayerStart.Count - 1; i >=0; i--)
{
var lineStart = IndexOfChangeInZ[i];
var lineStart = IndexOfLayerStart[i];
if (instructionIndex >= lineStart)
{
@ -964,13 +969,13 @@ namespace MatterControl.Printing
if (currentLayer > -1)
{
int startIndex = IndexOfChangeInZ[currentLayer];
int startIndex = IndexOfLayerStart[currentLayer];
int endIndex = LineCount - 1;
if (currentLayer < LayerCount - 1)
{
endIndex = IndexOfChangeInZ[currentLayer + 1];
endIndex = IndexOfLayerStart[currentLayer + 1];
}
else
{

View file

@ -140,8 +140,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return "---";
}
int startInstruction = loadedGCode.GetInstructionIndexAtLayer(startLayer);
int endInstruction = loadedGCode.GetInstructionIndexAtLayer(endLayer);
int startInstruction = loadedGCode.GetFirstLayerInstruction(startLayer);
int endInstruction = loadedGCode.GetFirstLayerInstruction(endLayer);
var secondsToEndFromStart = loadedGCode.Instruction(startInstruction).secondsToEndFromHere;
var secondsToEndFromEnd = loadedGCode.Instruction(endInstruction).secondsToEndFromHere;
return SecondsToTime(secondsToEndFromStart - secondsToEndFromEnd);
@ -154,12 +154,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return "---";
}
int startInstruction = loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex);
int startInstruction = loadedGCode.GetFirstLayerInstruction(activeLayerIndex);
if(activeLayerIndex == 0)
{
startInstruction = 0;
}
int endInstruction = loadedGCode.GetInstructionIndexAtLayer(activeLayerIndex + 1);
int endInstruction = loadedGCode.GetFirstLayerInstruction(activeLayerIndex + 1);
string separator = "";
string fanSpeeds = "";

View file

@ -166,7 +166,15 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
SplitterWidth = theme.SplitterWidth,
Visible = false,
};
gcodeContainer.AddChild(gcodePanel);
gcodeContainer.Resized += (s, e) =>
{
if (printer != null)
{
printer.ViewState.SelectedObjectPanelWidth = gcodeContainer.Width;
}
};
modelViewSidePanel.BoundsChanged += (s, e) =>
{

View file

@ -151,37 +151,53 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
if (selectedItems.Count > 0)
{
// cleare the selected item
// clear the selected item
scene.SelectedItem = null;
var clonedItemsToAdd = new List<IObject3D>(selectedItems.Select((i) => i.Clone()));
Children.Modify((list) =>
{
list.Clear();
foreach (var child in clonedItemsToAdd)
{
list.Add(child);
}
});
AddMeshWrapperToAllChildren();
WrapItems(selectedItems);
scene.UndoBuffer.AddAndDo(
new ReplaceCommand(
new List<IObject3D>(selectedItems),
new List<IObject3D> { this }));
this.MakeNameNonColliding();
// and select this
scene.SelectedItem = this;
}
ResumeRebuild();
Rebuild(null);
if (!RebuildSuspended)
{
Rebuild(null);
}
}
public void WrapItems(List<IObject3D> items)
{
SuspendRebuild();
var clonedItemsToAdd = new List<IObject3D>(items.Select((i) => i.Clone()));
Children.Modify((list) =>
{
list.Clear();
foreach (var child in clonedItemsToAdd)
{
list.Add(child);
}
});
AddMeshWrapperToAllChildren();
this.MakeNameNonColliding();
ResumeRebuild();
if (!RebuildSuspended)
{
Rebuild(null);
}
}
private void AddMeshWrapperToAllChildren()

View file

@ -49,9 +49,9 @@ namespace MatterHackers.MatterControl.PartPreviewWindow.View3D
public override void OnInvalidate(InvalidateArgs invalidateType)
{
if ((invalidateType.InvalidateType == InvalidateType.Content
|| invalidateType.InvalidateType == InvalidateType.Matrix
|| invalidateType.InvalidateType == InvalidateType.Mesh)
if ((invalidateType.InvalidateType.HasFlag(InvalidateType.Content)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Matrix)
|| invalidateType.InvalidateType.HasFlag(InvalidateType.Mesh))
&& invalidateType.Source != this
&& !RebuildSuspended)
{

View file

@ -166,6 +166,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
};
modelViewSidePanel.BoundsChanged += UpdateRenderView;
modelViewSidePanel.Resized += ModelViewSidePanel_Resized;
modelViewSidePanel.AddChild(
new SectionWidget(
"Options".Localize(),
@ -226,6 +228,14 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.sceneContext.SceneLoaded += SceneContext_SceneLoaded;
}
private void ModelViewSidePanel_Resized(object sender, EventArgs e)
{
if (this.Printer !=null)
{
this.Printer.ViewState.SelectedObjectPanelWidth = selectedObjectPanel.Width;
}
}
private void RebuildTreeSection(IObject3D selection, ThemeConfig theme)
{
treeSection.CloseAllChildren();
@ -355,15 +365,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public override void OnClosed(ClosedEventArgs e)
{
if (Printer != null)
{
Printer.ViewState.SelectedObjectPanelWidth = selectedObjectPanel.Width;
}
viewControls3D.TransformStateChanged -= ViewControls3D_TransformStateChanged;
Scene.SelectionChanged -= Scene_SelectionChanged;
this.InteractionLayer.DrawGlOpaqueContent -= Draw_GlOpaqueContent;
this.sceneContext.SceneLoaded -= SceneContext_SceneLoaded;
modelViewSidePanel.Resized -= ModelViewSidePanel_Resized;
if (meshViewerWidget != null)
{
@ -1224,7 +1230,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private SelectedObjectPanel selectedObjectPanel;
internal GuiWidget modelViewSidePanel;
internal LeftResizeContainer modelViewSidePanel;
public Vector2 DragSelectionStartPosition { get; private set; }
public bool DragSelectionInProgress { get; private set; }

@ -1 +1 @@
Subproject commit eb6b68cd93c1855d9c1c73b275d63d1bce444f4d
Subproject commit 4a4d58b863ef85a41d6fe2584d8e59de306f984d

View file

@ -58,6 +58,7 @@
<Compile Include="MatterControl\InteractiveSceneTests.cs" />
<Compile Include="MatterControl\ImportSettingsTests.cs" />
<Compile Include="MatterControl\AssetManagerTests.cs" />
<Compile Include="MatterControl\MeshRebuildTests.cs" />
<Compile Include="MatterControl\MeshCsgTests.cs" />
<Compile Include="MatterControl\SliceSettingsFieldTests.cs" />
<Compile Include="MatterControl\SettingsParseTests.cs" />

View file

@ -0,0 +1,110 @@
/*
Copyright (c) 2014, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
#define DEBUG_INTO_TGAS
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.DataConverters3D;
using MatterHackers.MatterControl.DesignTools;
using MatterHackers.MatterControl.DesignTools.Operations;
using MatterHackers.MatterControl.Tests.Automation;
using MatterHackers.PolygonMesh.Csg;
using MatterHackers.PolygonMesh.Processors;
using MatterHackers.VectorMath;
using Net3dBool;
using NUnit.Framework;
namespace MatterHackers.PolygonMesh.UnitTests
{
[TestFixture, Category("Agg.PolygonMesh.Rebuild")]
public class MeshRebuildTests
{
[Test]
public void PinchChangesMesh()
{
AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
var root = new Object3D();
IObject3D cube = new CubeObject3D();
root.Children.Add(cube);
cube.Rebuild(null);
Assert.AreEqual(1, root.Descendants().Count());
// now add a pinch
var pinch1 = new PinchObject3D();
pinch1.WrapItems(new List<IObject3D>() { cube });
root.Children.Remove(cube);
root.Children.Add(pinch1);
Assert.AreEqual(3, root.Descendants().Count());
}
[Test]
public void PinchTextMaintainsWrapping()
{
AggContext.StaticData = new FileSystemStaticData(TestContext.CurrentContext.ResolveProjectPath(4, "StaticData"));
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
var root = new Object3D();
IObject3D text = new TextObject3D();
root.Children.Add(text);
text.Rebuild(null);
Assert.AreEqual(5, root.Descendants().Count());
// now add a pinch
var pinch1 = new PinchObject3D();
pinch1.WrapItems(new List<IObject3D>() { text });
root.Children.Remove(text);
root.Children.Add(pinch1);
Assert.AreEqual(10, root.Descendants().Count());
// now remove pinch
pinch1.Remove(null);
Assert.AreEqual(5, root.Descendants().Count());
Assert.AreEqual(1, root.Children.Count());
// now add it again
text = root.Children.First(); // the wrap made a copy so set text to be the current text
Assert.IsTrue(text is TextObject3D);
pinch1 = new PinchObject3D();
pinch1.WrapItems(new List<IObject3D>() { text });
root.Children.Remove(text);
root.Children.Add(pinch1);
Assert.AreEqual(10, root.Descendants().Count());
}
}
}