Move MatterControl source code into a subdirectory
This commit is contained in:
parent
2c6e34243a
commit
70af2d9ae8
2007 changed files with 13 additions and 8 deletions
|
|
@ -0,0 +1,71 @@
|
|||
using MatterHackers.Agg;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ColorVertexData
|
||||
{
|
||||
public byte r;
|
||||
public byte g;
|
||||
public byte b;
|
||||
public byte a;
|
||||
|
||||
public float normalX;
|
||||
public float normalY;
|
||||
public float normalZ;
|
||||
|
||||
public float positionX;
|
||||
public float positionY;
|
||||
public float positionZ;
|
||||
|
||||
public static readonly int Stride = Marshal.SizeOf(default(ColorVertexData));
|
||||
|
||||
public ColorVertexData(Vector3 position, Vector3 normal, Color color)
|
||||
{
|
||||
r = (byte)color.Red0To255;
|
||||
g = (byte)color.Green0To255;
|
||||
b = (byte)color.Blue0To255;
|
||||
a = (byte)color.Alpha0To255;
|
||||
|
||||
normalX = (float)normal.X;
|
||||
normalY = (float)normal.Y;
|
||||
normalZ = (float)normal.Z;
|
||||
|
||||
positionX = (float)position.X;
|
||||
positionY = (float)position.Y;
|
||||
positionZ = (float)position.Z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Copyright (c) 2018, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MatterHackers.Agg;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class ExtrusionColors
|
||||
{
|
||||
private Dictionary<float, Color> speedColors = new Dictionary<float, Color>();
|
||||
|
||||
private double startColor = 223.0 / 360.0;
|
||||
private double endColor = 5.0 / 360.0;
|
||||
private double range;
|
||||
private double delta;
|
||||
private float min;
|
||||
private float max;
|
||||
|
||||
public ExtrusionColors(HashSet<float> speeds)
|
||||
{
|
||||
if (speeds.Any())
|
||||
{
|
||||
min = speeds.Min();
|
||||
max = speeds.Max();
|
||||
}
|
||||
else
|
||||
{
|
||||
min = 0;
|
||||
max = 1;
|
||||
}
|
||||
range = max - min;
|
||||
delta = startColor - endColor;
|
||||
|
||||
foreach (var speed in speeds)
|
||||
{
|
||||
speedColors[speed] = this.ComputeColor(speed);
|
||||
}
|
||||
}
|
||||
|
||||
public Color GetColorForSpeed(float speed)
|
||||
{
|
||||
if (speedColors.TryGetValue(speed, out Color color))
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
// Compute value if missing from dictionary (legend uses non-existing speeds)
|
||||
return this.ComputeColor(speed);
|
||||
}
|
||||
|
||||
private Color ComputeColor(float speed)
|
||||
{
|
||||
var rangedValue = speed - min;
|
||||
var factor = range == 0 ? 1 : rangedValue / range;
|
||||
|
||||
double offset = factor * delta;
|
||||
double fixedColor = startColor - offset;
|
||||
|
||||
return ColorF.FromHSL(fixedColor, .99, .49).ToColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.Transform;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class GCodeRenderInfo
|
||||
{
|
||||
public Func<int, Color> GetMaterialColor { get; }
|
||||
|
||||
public int StartLayerIndex { get; set; }
|
||||
|
||||
public int EndLayerIndex { get; set; }
|
||||
|
||||
public Affine Transform { get; }
|
||||
|
||||
public double LayerScale { get; }
|
||||
|
||||
public RenderType CurrentRenderType { get; private set; }
|
||||
|
||||
public double FeatureToStartOnRatio0To1 { get; set; }
|
||||
|
||||
public double FeatureToEndOnRatio0To1 { get; set; }
|
||||
|
||||
public Func<RenderType> GetRenderType { get; }
|
||||
|
||||
public GCodeRenderInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public GCodeRenderInfo(int startLayerIndex, int endLayerIndex,
|
||||
Affine transform, double layerScale,
|
||||
double featureToStartOnRatio0To1, double featureToEndOnRatio0To1,
|
||||
Func<RenderType> getRenderType,
|
||||
Func<int, Color> getMaterialColor)
|
||||
{
|
||||
this.GetMaterialColor = getMaterialColor;
|
||||
this.StartLayerIndex = startLayerIndex;
|
||||
this.EndLayerIndex = endLayerIndex;
|
||||
this.Transform = transform;
|
||||
this.LayerScale = layerScale;
|
||||
|
||||
// Store delegate
|
||||
this.GetRenderType = getRenderType;
|
||||
|
||||
// Invoke delegate
|
||||
this.CurrentRenderType = this.GetRenderType();
|
||||
|
||||
this.FeatureToStartOnRatio0To1 = featureToStartOnRatio0To1;
|
||||
this.FeatureToEndOnRatio0To1 = featureToEndOnRatio0To1;
|
||||
}
|
||||
|
||||
public void RefreshRenderType()
|
||||
{
|
||||
this.CurrentRenderType = this.GetRenderType();
|
||||
}
|
||||
}
|
||||
}
|
||||
457
original/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs
Normal file
457
original/MatterControl.OpenGL/GCodeRenderer/GCodeRenderer.cs
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
Copyright (c) 2017, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MatterControl.Printing;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
[Flags]
|
||||
public enum RenderType
|
||||
{
|
||||
None = 0,
|
||||
Extrusions = 1,
|
||||
Moves = 2,
|
||||
Retractions = 4,
|
||||
SpeedColors = 8,
|
||||
SimulateExtrusion = 16,
|
||||
TransparentExtrusion = 64,
|
||||
GrayColors = 128
|
||||
};
|
||||
|
||||
public class GCodeRenderer : IDisposable
|
||||
{
|
||||
public static double ExtruderWidth { get; set; } = .4;
|
||||
|
||||
public static Color TravelColor = Color.Green;
|
||||
public static Color RetractionColor = Color.FireEngineRed;
|
||||
|
||||
internal class Layer
|
||||
{
|
||||
internal List<int> startIndices = new List<int>();
|
||||
internal List<int> endIndices = new List<int>();
|
||||
internal List<RenderFeatureBase> features = new List<RenderFeatureBase>();
|
||||
}
|
||||
|
||||
internal class FeatureSet
|
||||
{
|
||||
internal List<Layer> layers = new List<Layer>();
|
||||
}
|
||||
|
||||
private FeatureSet all = new FeatureSet();
|
||||
|
||||
private List<GCodeVertexBuffer> layerVertexBuffer;
|
||||
private RenderType lastRenderType = RenderType.None;
|
||||
private GCodeFile gCodeFileToDraw;
|
||||
|
||||
public GCodeRenderer(GCodeFile gCodeFileToDraw)
|
||||
{
|
||||
if (gCodeFileToDraw != null)
|
||||
{
|
||||
this.gCodeFileToDraw = gCodeFileToDraw;
|
||||
|
||||
if (gCodeFileToDraw is GCodeMemoryFile memoryFile)
|
||||
{
|
||||
this.ExtrusionColors = new ExtrusionColors(memoryFile.Speeds);
|
||||
}
|
||||
|
||||
for (int i = 0; i < gCodeFileToDraw.LayerCount; i++)
|
||||
{
|
||||
all.layers.Add(new Layer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public GCodeFile GCodeFileToDraw => gCodeFileToDraw;
|
||||
|
||||
public ExtrusionColors ExtrusionColors { get; } = null;
|
||||
|
||||
public Color Gray { get; set; }
|
||||
|
||||
public void CreateFeaturesForLayerIfRequired(int layerToCreate)
|
||||
{
|
||||
if (all.layers.Count == 0
|
||||
|| all.layers[layerToCreate].features.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<RenderFeatureBase> renderFeaturesForLayer = all.layers[layerToCreate].features;
|
||||
|
||||
int startRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate);
|
||||
int endRenderIndex = gCodeFileToDraw.LineCount - 1;
|
||||
if (layerToCreate < gCodeFileToDraw.LayerCount - 1)
|
||||
{
|
||||
endRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate + 1);
|
||||
}
|
||||
|
||||
for (int instructionIndex = startRenderIndex; instructionIndex < endRenderIndex; instructionIndex++)
|
||||
{
|
||||
PrinterMachineInstruction currentInstruction = gCodeFileToDraw.Instruction(instructionIndex);
|
||||
PrinterMachineInstruction previousInstruction = currentInstruction;
|
||||
if (instructionIndex > 0)
|
||||
{
|
||||
previousInstruction = gCodeFileToDraw.Instruction(instructionIndex - 1);
|
||||
}
|
||||
|
||||
if (currentInstruction.Position == previousInstruction.Position)
|
||||
{
|
||||
double eMovement = 0;
|
||||
if (currentInstruction.PositionSet != PositionSet.E)
|
||||
{
|
||||
eMovement = currentInstruction.EPosition - previousInstruction.EPosition;
|
||||
}
|
||||
|
||||
if (Math.Abs(eMovement) > 0)
|
||||
{
|
||||
// this is a retraction
|
||||
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, eMovement, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
||||
}
|
||||
|
||||
if (currentInstruction.Line.StartsWith("G10"))
|
||||
{
|
||||
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, -1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
||||
}
|
||||
else if (currentInstruction.Line.StartsWith("G11"))
|
||||
{
|
||||
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, 1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var extrusionAmount = currentInstruction.EPosition - previousInstruction.EPosition;
|
||||
var filamentDiameterMm = gCodeFileToDraw.GetFilamentDiameter();
|
||||
|
||||
if (gCodeFileToDraw.IsExtruding(instructionIndex))
|
||||
{
|
||||
double layerThickness = gCodeFileToDraw.GetLayerHeight(layerToCreate);
|
||||
|
||||
Color extrusionColor = ExtrusionColors.GetColorForSpeed((float)currentInstruction.FeedRate);
|
||||
renderFeaturesForLayer.Add(
|
||||
new RenderFeatureExtrusion(
|
||||
instructionIndex,
|
||||
previousInstruction.Position,
|
||||
currentInstruction.Position,
|
||||
currentInstruction.ToolIndex,
|
||||
currentInstruction.FeedRate,
|
||||
extrusionAmount,
|
||||
filamentDiameterMm,
|
||||
layerThickness,
|
||||
extrusionColor,
|
||||
this.Gray));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extrusionAmount < 0)
|
||||
{
|
||||
double moveLength = (currentInstruction.Position - previousInstruction.Position).Length;
|
||||
double filamentRadius = filamentDiameterMm / 2;
|
||||
double areaSquareMm = (filamentRadius * filamentRadius) * Math.PI;
|
||||
|
||||
var extrusionVolumeMm3 = (float)(areaSquareMm * extrusionAmount);
|
||||
var area = extrusionVolumeMm3 / moveLength;
|
||||
}
|
||||
|
||||
renderFeaturesForLayer.Add(
|
||||
new RenderFeatureTravel(
|
||||
instructionIndex,
|
||||
previousInstruction.Position,
|
||||
currentInstruction.Position,
|
||||
currentInstruction.ToolIndex,
|
||||
currentInstruction.FeedRate,
|
||||
extrusionAmount < 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int GetNumFeatures(int layerToCountFeaturesOn)
|
||||
{
|
||||
CreateFeaturesForLayerIfRequired(layerToCountFeaturesOn);
|
||||
return all.layers[layerToCountFeaturesOn].features.Count;
|
||||
}
|
||||
|
||||
public RenderFeatureBase this[int layerIndex, int featureIndex]
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var features = all.layers[layerIndex].features;
|
||||
|
||||
if (featureIndex < features.Count)
|
||||
{
|
||||
return features[featureIndex];
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
// Callers should test for non-null values
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool GCodeInspector { get; set; } = false;
|
||||
|
||||
public void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo)
|
||||
{
|
||||
if (all.layers.Count > 0)
|
||||
{
|
||||
CreateFeaturesForLayerIfRequired(renderInfo.EndLayerIndex);
|
||||
|
||||
int featuresOnLayer = all.layers[renderInfo.EndLayerIndex].features.Count;
|
||||
int endFeature = (int)(featuresOnLayer * renderInfo.FeatureToEndOnRatio0To1 + .5);
|
||||
endFeature = Math.Max(0, Math.Min(endFeature, featuresOnLayer));
|
||||
|
||||
int startFeature = (int)(featuresOnLayer * renderInfo.FeatureToStartOnRatio0To1 + .5);
|
||||
startFeature = Math.Max(0, Math.Min(startFeature, featuresOnLayer));
|
||||
|
||||
// try to make sure we always draw at least one feature
|
||||
if (endFeature <= startFeature)
|
||||
{
|
||||
endFeature = Math.Min(startFeature + 1, featuresOnLayer);
|
||||
}
|
||||
if (startFeature >= endFeature)
|
||||
{
|
||||
// This can only happen if the start and end are set to the last feature
|
||||
// Try to set the start feature to one from the end
|
||||
startFeature = Math.Max(endFeature - 1, 0);
|
||||
}
|
||||
|
||||
var graphics2DGl = graphics2D as Graphics2DOpenGL;
|
||||
if (graphics2DGl != null)
|
||||
{
|
||||
graphics2DGl.PreRender(Color.White);
|
||||
GL.Begin(BeginMode.Triangles);
|
||||
|
||||
int lastFeature = endFeature - 1;
|
||||
for (int i = startFeature; i < endFeature; i++)
|
||||
{
|
||||
RenderFeatureBase feature = all.layers[renderInfo.EndLayerIndex].features[i];
|
||||
if (feature != null)
|
||||
{
|
||||
feature.Render(graphics2DGl, renderInfo, highlightFeature: this.GCodeInspector && i == lastFeature);
|
||||
}
|
||||
}
|
||||
GL.End();
|
||||
graphics2DGl.PopOrthoProjection();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = startFeature; i < endFeature; i++)
|
||||
{
|
||||
RenderFeatureBase feature = all.layers[renderInfo.EndLayerIndex].features[i];
|
||||
if (feature != null)
|
||||
{
|
||||
feature.Render(graphics2D, renderInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GCodeVertexBuffer Create3DDataForLayer(int layerIndex, GCodeRenderInfo renderInfo)
|
||||
{
|
||||
var colorVertexData = new VectorPOD<ColorVertexData>();
|
||||
var vertexIndexArray = new VectorPOD<int>();
|
||||
|
||||
var layer = all.layers[layerIndex];
|
||||
layer.startIndices.Clear();
|
||||
layer.endIndices.Clear();
|
||||
|
||||
for (int i = 0; i < layer.features.Count; i++)
|
||||
{
|
||||
layer.startIndices.Add(vertexIndexArray.Count);
|
||||
|
||||
RenderFeatureBase feature = layer.features[i];
|
||||
|
||||
if (feature != null)
|
||||
{
|
||||
// Build the color and index data for the feature
|
||||
feature.CreateRender3DData(colorVertexData, vertexIndexArray, renderInfo);
|
||||
}
|
||||
|
||||
layer.endIndices.Add(vertexIndexArray.Count);
|
||||
}
|
||||
|
||||
// Construct and return the new VertexBuffer object with all color/index data
|
||||
return new GCodeVertexBuffer(vertexIndexArray.Array, vertexIndexArray.Count, colorVertexData.Array);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Clear3DGCode();
|
||||
}
|
||||
|
||||
public void Clear3DGCode()
|
||||
{
|
||||
if (layerVertexBuffer != null)
|
||||
{
|
||||
for (int i = 0; i < layerVertexBuffer.Count; i++)
|
||||
{
|
||||
if (layerVertexBuffer[i] != null)
|
||||
{
|
||||
layerVertexBuffer[i].Dispose();
|
||||
layerVertexBuffer[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool PrepareForGeometryGeneration(GCodeRenderInfo renderInfo)
|
||||
{
|
||||
if (renderInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (layerVertexBuffer == null)
|
||||
{
|
||||
layerVertexBuffer = new List<GCodeVertexBuffer>(gCodeFileToDraw.LayerCount);
|
||||
for (int layerIndex = 0; layerIndex < gCodeFileToDraw.LayerCount; layerIndex++)
|
||||
{
|
||||
layerVertexBuffer.Add(null);
|
||||
all.layers.Add(new Layer());
|
||||
}
|
||||
}
|
||||
|
||||
for (int layerIndex = 0; layerIndex < gCodeFileToDraw.LayerCount; layerIndex++)
|
||||
{
|
||||
CreateFeaturesForLayerIfRequired(layerIndex);
|
||||
}
|
||||
|
||||
if (lastRenderType != renderInfo.CurrentRenderType)
|
||||
{
|
||||
Clear3DGCode();
|
||||
lastRenderType = renderInfo.CurrentRenderType;
|
||||
}
|
||||
|
||||
return all.layers.Count > 0;
|
||||
}
|
||||
|
||||
public void Render3D(GCodeRenderInfo renderInfo, DrawEventArgs e)
|
||||
{
|
||||
if (PrepareForGeometryGeneration(renderInfo))
|
||||
{
|
||||
for (int i = renderInfo.EndLayerIndex - 1; i >= renderInfo.StartLayerIndex; i--)
|
||||
{
|
||||
// If its the first render or we change what we are trying to render then create vertex data.
|
||||
if (layerVertexBuffer.Count > i
|
||||
&& layerVertexBuffer[i] == null)
|
||||
{
|
||||
layerVertexBuffer[i] = Create3DDataForLayer(i, renderInfo);
|
||||
}
|
||||
}
|
||||
|
||||
GL.Disable(EnableCap.Texture2D);
|
||||
GL.PushAttrib(AttribMask.EnableBit);
|
||||
GL.DisableClientState(ArrayCap.TextureCoordArray);
|
||||
GL.Enable(EnableCap.PolygonSmooth);
|
||||
|
||||
if (renderInfo.EndLayerIndex - 1 > renderInfo.StartLayerIndex)
|
||||
{
|
||||
for (int i = renderInfo.StartLayerIndex; i < renderInfo.EndLayerIndex - 1; i++)
|
||||
{
|
||||
var layer = all.layers[i];
|
||||
int featuresOnLayer = layer.features.Count;
|
||||
if (featuresOnLayer > 1
|
||||
&& layerVertexBuffer[i] != null)
|
||||
{
|
||||
layerVertexBuffer[i].RenderRange(0, layer.endIndices[featuresOnLayer - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the partial layer of end-1 from startRatio to endRatio
|
||||
{
|
||||
int layerIndex = renderInfo.EndLayerIndex - 1;
|
||||
var layer = all.layers[layerIndex];
|
||||
int featuresOnLayer = layer.features.Count;
|
||||
int startFeature = (int)(featuresOnLayer * renderInfo.FeatureToStartOnRatio0To1 + .5);
|
||||
startFeature = Math.Max(0, Math.Min(startFeature, featuresOnLayer));
|
||||
|
||||
int endFeature = (int)(featuresOnLayer * renderInfo.FeatureToEndOnRatio0To1 + .5);
|
||||
endFeature = Math.Max(0, Math.Min(endFeature, featuresOnLayer));
|
||||
|
||||
// try to make sure we always draw at least one feature
|
||||
if (endFeature <= startFeature)
|
||||
{
|
||||
endFeature = Math.Min(startFeature + 1, featuresOnLayer);
|
||||
}
|
||||
|
||||
if (startFeature >= endFeature)
|
||||
{
|
||||
// This can only happen if the start and end are set to the last feature
|
||||
// Try to set the start feature to one from the end
|
||||
startFeature = Math.Max(endFeature - 1, 0);
|
||||
}
|
||||
|
||||
if (endFeature > startFeature
|
||||
&& layerVertexBuffer[layerIndex] != null)
|
||||
{
|
||||
int ellementCount = layer.endIndices[endFeature - 1] - layer.startIndices[startFeature];
|
||||
|
||||
layerVertexBuffer[layerIndex].RenderRange(layer.startIndices[startFeature], ellementCount);
|
||||
}
|
||||
}
|
||||
GL.PopAttrib();
|
||||
}
|
||||
}
|
||||
|
||||
public AxisAlignedBoundingBox GetAabbOfRender3D(GCodeRenderInfo renderInfo)
|
||||
{
|
||||
var box = AxisAlignedBoundingBox.Empty();
|
||||
|
||||
if (PrepareForGeometryGeneration(renderInfo))
|
||||
{
|
||||
for (int i = renderInfo.EndLayerIndex - 1; i >= renderInfo.StartLayerIndex; i--)
|
||||
{
|
||||
if (i < layerVertexBuffer.Count)
|
||||
{
|
||||
if (layerVertexBuffer[i] == null)
|
||||
{
|
||||
layerVertexBuffer[i] = Create3DDataForLayer(i, renderInfo);
|
||||
}
|
||||
|
||||
box = AxisAlignedBoundingBox.Union(box, layerVertexBuffer[i].BoundingBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
}
|
||||
}
|
||||
240
original/MatterControl.OpenGL/GCodeRenderer/GCodeVertexBuffer.cs
Normal file
240
original/MatterControl.OpenGL/GCodeRenderer/GCodeVertexBuffer.cs
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
Copyright (c) 2018, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.RenderOpenGl.OpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class GCodeVertexBuffer : IDisposable
|
||||
{
|
||||
private int indexID;
|
||||
private int indexLength;
|
||||
private BeginMode pointMode = BeginMode.Triangles;
|
||||
private bool disposed = false;
|
||||
|
||||
private int vertexID;
|
||||
private int vertexLength;
|
||||
|
||||
private ColorVertexData[] colorVertexData;
|
||||
|
||||
private AxisAlignedBoundingBox boundingBox = AxisAlignedBoundingBox.Empty();
|
||||
|
||||
public AxisAlignedBoundingBox BoundingBox { get { return new AxisAlignedBoundingBox(boundingBox.MinXYZ, boundingBox.MaxXYZ); } }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new VertexBuffer
|
||||
/// </summary>
|
||||
/// <param name="indexData">The array containing the vertex indices.</param>
|
||||
/// <param name="vertexCount">The number of vertices to read from the indexData.</param>
|
||||
/// <param name="colorData">The array containing the colorData.</param>
|
||||
public GCodeVertexBuffer(int[] indexData, int vertexCount, ColorVertexData[] colorData)
|
||||
{
|
||||
try
|
||||
{
|
||||
vertexID = GL.GenBuffer();
|
||||
indexID = GL.GenBuffer();
|
||||
SetBufferData(ref indexData, ref colorData);
|
||||
}
|
||||
catch
|
||||
{
|
||||
var triangleData = new List<ColorVertexData>();
|
||||
for (int i = 0; i < vertexCount; i += 3)
|
||||
{
|
||||
triangleData.Add(colorData[indexData[i]]);
|
||||
triangleData.Add(colorData[indexData[i + 1]]);
|
||||
triangleData.Add(colorData[indexData[i + 2]]);
|
||||
}
|
||||
|
||||
this.colorVertexData = triangleData.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTriangles(int offset, int count)
|
||||
{
|
||||
GL.EnableClientState(ArrayCap.ColorArray);
|
||||
GL.EnableClientState(ArrayCap.NormalArray);
|
||||
GL.EnableClientState(ArrayCap.VertexArray);
|
||||
GL.DisableClientState(ArrayCap.TextureCoordArray);
|
||||
GL.Disable(EnableCap.Texture2D);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (ColorVertexData* pFixedColorData = colorVertexData)
|
||||
{
|
||||
byte* pColorData = (byte*)(pFixedColorData + offset);
|
||||
byte* pNormalData = pColorData + 4;
|
||||
byte* pPosition = pNormalData + 12;
|
||||
GL.VertexPointer(3, VertexPointerType.Float, ColorVertexData.Stride, new IntPtr(pPosition));
|
||||
GL.NormalPointer(NormalPointerType.Float, ColorVertexData.Stride, new IntPtr(pNormalData));
|
||||
GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertexData.Stride, new IntPtr(pColorData));
|
||||
GL.DrawArrays(BeginMode.Triangles, ColorVertexData.Stride, Math.Min(colorVertexData.Length, count));
|
||||
}
|
||||
}
|
||||
|
||||
GL.DisableClientState(ArrayCap.NormalArray);
|
||||
GL.DisableClientState(ArrayCap.VertexArray);
|
||||
GL.DisableClientState(ArrayCap.ColorArray);
|
||||
|
||||
GL.ColorPointer(4, ColorPointerType.UnsignedByte, 0, new IntPtr(0));
|
||||
GL.NormalPointer(NormalPointerType.Float, 0, new IntPtr(0));
|
||||
GL.VertexPointer(3, VertexPointerType.Float, 0, new IntPtr(0));
|
||||
}
|
||||
|
||||
private void SetBufferData(ref int[] indexData, ref ColorVertexData[] colorData)
|
||||
{
|
||||
// Set vertex data
|
||||
vertexLength = colorData.Length;
|
||||
if (vertexLength > 0)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexID);
|
||||
unsafe
|
||||
{
|
||||
fixed (ColorVertexData* dataPointer = colorData)
|
||||
{
|
||||
GL.BufferData(BufferTarget.ArrayBuffer, colorData.Length * ColorVertexData.Stride, (IntPtr)dataPointer, BufferUsageHint.StaticDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set index data
|
||||
indexLength = indexData.Length;
|
||||
if (indexLength > 0)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexID);
|
||||
unsafe
|
||||
{
|
||||
fixed (int* dataPointer = indexData)
|
||||
{
|
||||
GL.BufferData(BufferTarget.ElementArrayBuffer, indexData.Length * sizeof(int), (IntPtr)dataPointer, BufferUsageHint.StaticDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boundingBox = AxisAlignedBoundingBox.Empty();
|
||||
foreach (int i in indexData)
|
||||
{
|
||||
var v = colorData[i];
|
||||
boundingBox.ExpandToInclude(new Vector3Float(v.positionX, v.positionY, v.positionZ));
|
||||
}
|
||||
}
|
||||
|
||||
public void RenderRange(int offset, int count)
|
||||
{
|
||||
if (vertexID == 0)
|
||||
{
|
||||
// not allocated don't render
|
||||
RenderTriangles(offset, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderBufferData(offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderBufferData(int offset, int count)
|
||||
{
|
||||
GL.EnableClientState(ArrayCap.ColorArray);
|
||||
GL.EnableClientState(ArrayCap.NormalArray);
|
||||
GL.EnableClientState(ArrayCap.VertexArray);
|
||||
GL.DisableClientState(ArrayCap.TextureCoordArray);
|
||||
GL.Disable(EnableCap.Texture2D);
|
||||
|
||||
GL.EnableClientState(ArrayCap.IndexArray);
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexID);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexID);
|
||||
|
||||
GL.ColorPointer(4, ColorPointerType.UnsignedByte, ColorVertexData.Stride, new IntPtr(0));
|
||||
GL.NormalPointer(NormalPointerType.Float, ColorVertexData.Stride, new IntPtr(4));
|
||||
GL.VertexPointer(3, VertexPointerType.Float, ColorVertexData.Stride, new IntPtr(4 + 3 * 4));
|
||||
|
||||
// ** Draw **
|
||||
GL.DrawRangeElements(
|
||||
pointMode,
|
||||
0,
|
||||
indexLength,
|
||||
count,
|
||||
DrawElementsType.UnsignedInt,
|
||||
new IntPtr(offset * 4));
|
||||
|
||||
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
|
||||
|
||||
GL.DisableClientState(ArrayCap.IndexArray);
|
||||
|
||||
GL.DisableClientState(ArrayCap.VertexArray);
|
||||
GL.DisableClientState(ArrayCap.NormalArray);
|
||||
GL.DisableClientState(ArrayCap.ColorArray);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (vertexID == 0)
|
||||
{
|
||||
// not allocated don't dispose
|
||||
return;
|
||||
}
|
||||
|
||||
// release unmanaged resources
|
||||
if (!disposed)
|
||||
{
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
GL.DeleteBuffer(vertexID);
|
||||
GL.DeleteBuffer(indexID);
|
||||
});
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
// release other Managed objects
|
||||
// if (resource!= null) resource.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~GCodeVertexBuffer()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public abstract class RenderFeatureBase
|
||||
{
|
||||
protected int toolIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The actual gcode line in the source gcode file
|
||||
/// </summary>
|
||||
public int InstructionIndex { get; private set; }
|
||||
public static Color HighlightColor { get; set; } = new Color("#D0F476");
|
||||
|
||||
public static Color StartColor { get; set; } = Color.Red;
|
||||
|
||||
public static Color EndColor { get; set; } = new Color("#008000");
|
||||
|
||||
public abstract void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo, bool highlightFeature = false);
|
||||
|
||||
public abstract void CreateRender3DData(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, GCodeRenderInfo renderInfo);
|
||||
|
||||
protected RenderFeatureBase(int instructionIndex, int toolIndex)
|
||||
{
|
||||
this.toolIndex = toolIndex;
|
||||
this.InstructionIndex = instructionIndex;
|
||||
}
|
||||
|
||||
static public void CreateCylinder(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, Vector3 startPos, Vector3 endPos, double radius, int steps, Color color, double layerHeight)
|
||||
{
|
||||
var direction = endPos - startPos;
|
||||
var directionNormal = direction.GetNormal();
|
||||
var startSweepDirection = Vector3.GetPerpendicular(startPos, endPos).GetNormal();
|
||||
|
||||
int[] tubeStartIndices = new int[steps];
|
||||
int[] tubeEndIndices = new int[steps];
|
||||
|
||||
int[] capStartIndices = new int[steps];
|
||||
int[] capEndIndices = new int[steps];
|
||||
|
||||
double halfHeight = layerHeight / 2 + (layerHeight * .1);
|
||||
double halfWidth = radius;
|
||||
double zScale = halfHeight / radius;
|
||||
double xScale = halfWidth / radius;
|
||||
|
||||
// Adjust start/end positions to be centered on Z for the given layer height
|
||||
startPos.Z -= halfHeight;
|
||||
endPos.Z -= halfHeight;
|
||||
|
||||
var scale = new Vector3(xScale, xScale, zScale);
|
||||
var rotateAngle = Vector3Ex.Cross(startSweepDirection, direction);
|
||||
var startCapStartNormal = Vector3Ex.Transform(startSweepDirection, Matrix4X4.CreateRotation(rotateAngle, MathHelper.Tau / 8));
|
||||
var startCapEndNormal = Vector3Ex.Transform(startSweepDirection, Matrix4X4.CreateRotation(-rotateAngle, MathHelper.Tau / 8));
|
||||
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
var rotationMatrix = Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i);
|
||||
// create tube ends verts
|
||||
var tubeNormal = Vector3Ex.Transform(startSweepDirection, rotationMatrix);
|
||||
var offset = Vector3Ex.Transform(startSweepDirection * radius, rotationMatrix) * scale;
|
||||
|
||||
var tubeStart = startPos + offset;
|
||||
tubeStartIndices[i] = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(tubeStart, tubeNormal, color));
|
||||
|
||||
var tubeEnd = endPos + offset;
|
||||
tubeEndIndices[i] = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(tubeEnd, tubeNormal, color));
|
||||
|
||||
// create cap verts
|
||||
var capStartNormal = Vector3Ex.Transform(startCapStartNormal, rotationMatrix);
|
||||
capStartNormal = (capStartNormal * scale).GetNormal();
|
||||
var capStartOffset = capStartNormal * radius * scale;
|
||||
var capStart = startPos + capStartOffset;
|
||||
capStartIndices[i] = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(capStart, capStartNormal, color));
|
||||
|
||||
var capEndNormal = Vector3Ex.Transform(startCapEndNormal, rotationMatrix);
|
||||
capEndNormal = (capEndNormal * scale).GetNormal();
|
||||
var capEndOffset = capEndNormal * radius * scale;
|
||||
var capEnd = endPos + capEndOffset;
|
||||
capEndIndices[i] = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(capEnd, capEndNormal, color));
|
||||
}
|
||||
|
||||
int tipStartIndex = colorVertexData.Count;
|
||||
var tipOffset = directionNormal * radius;
|
||||
tipOffset *= scale;
|
||||
colorVertexData.Add(new ColorVertexData(startPos - tipOffset, -directionNormal, color));
|
||||
int tipEndIndex = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(endPos + tipOffset, directionNormal, color));
|
||||
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
// create tube polys
|
||||
indexData.Add(tubeStartIndices[i]);
|
||||
indexData.Add(tubeEndIndices[i]);
|
||||
indexData.Add(tubeEndIndices[(i + 1) % steps]);
|
||||
|
||||
indexData.Add(tubeStartIndices[i]);
|
||||
indexData.Add(tubeEndIndices[(i + 1) % steps]);
|
||||
indexData.Add(tubeStartIndices[(i + 1) % steps]);
|
||||
|
||||
// create start cap polys
|
||||
indexData.Add(tubeStartIndices[i]);
|
||||
indexData.Add(capStartIndices[i]);
|
||||
indexData.Add(capStartIndices[(i + 1) % steps]);
|
||||
|
||||
indexData.Add(tubeStartIndices[i]);
|
||||
indexData.Add(capStartIndices[(i + 1) % steps]);
|
||||
indexData.Add(tubeStartIndices[(i + 1) % steps]);
|
||||
|
||||
// create end cap polys
|
||||
indexData.Add(tubeEndIndices[i]);
|
||||
indexData.Add(capEndIndices[i]);
|
||||
indexData.Add(capEndIndices[(i + 1) % steps]);
|
||||
|
||||
indexData.Add(tubeEndIndices[i]);
|
||||
indexData.Add(capEndIndices[(i + 1) % steps]);
|
||||
indexData.Add(tubeEndIndices[(i + 1) % steps]);
|
||||
|
||||
// create start tip polys
|
||||
indexData.Add(tipStartIndex);
|
||||
indexData.Add(capStartIndices[i]);
|
||||
indexData.Add(capStartIndices[(i + 1) % steps]);
|
||||
|
||||
// create end tip polys
|
||||
indexData.Add(tipEndIndex);
|
||||
indexData.Add(capEndIndices[i]);
|
||||
indexData.Add(capEndIndices[(i + 1) % steps]);
|
||||
}
|
||||
}
|
||||
|
||||
static public void CreatePointer(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, Vector3 startPos, Vector3 endPos, double radius, int steps, Color color)
|
||||
{
|
||||
var direction = endPos - startPos;
|
||||
var directionNormal = direction.GetNormal();
|
||||
var startSweepDirection = Vector3.GetPerpendicular(startPos, endPos).GetNormal();
|
||||
|
||||
int[] tubeStartIndices = new int[steps];
|
||||
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
var rotationMatrix = Matrix4X4.CreateRotation(direction, MathHelper.Tau / (steps * 2) + MathHelper.Tau / (steps) * i);
|
||||
|
||||
// create tube ends verts
|
||||
var tubeNormal = Vector3Ex.Transform(startSweepDirection, rotationMatrix);
|
||||
var offset = Vector3Ex.Transform(startSweepDirection * radius, rotationMatrix);
|
||||
var tubeStart = startPos + offset;
|
||||
tubeStartIndices[i] = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(tubeStart, tubeNormal, color));
|
||||
}
|
||||
|
||||
int tipEndIndex = colorVertexData.Count;
|
||||
colorVertexData.Add(new ColorVertexData(endPos, directionNormal, color));
|
||||
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
// create tube polys
|
||||
indexData.Add(tubeStartIndices[i]);
|
||||
indexData.Add(tubeStartIndices[(i + 1) % steps]);
|
||||
|
||||
indexData.Add(tipEndIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.VertexSource;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class RenderFeatureExtrusion : RenderFeatureTravel
|
||||
{
|
||||
private float extrusionVolumeMm3;
|
||||
private float layerHeight;
|
||||
private Color color;
|
||||
private Color gray;
|
||||
|
||||
public RenderFeatureExtrusion(int instructionIndex, Vector3 start, Vector3 end, int toolIndex, double travelSpeed, double totalExtrusionMm, double filamentDiameterMm, double layerHeight, Color color, Color gray)
|
||||
: base(instructionIndex, start, end, toolIndex, travelSpeed, false)
|
||||
{
|
||||
this.color = color;
|
||||
this.gray = gray;
|
||||
double filamentRadius = filamentDiameterMm / 2;
|
||||
double areaSquareMm = (filamentRadius * filamentRadius) * Math.PI;
|
||||
|
||||
this.extrusionVolumeMm3 = (float)(areaSquareMm * totalExtrusionMm);
|
||||
this.layerHeight = (float)layerHeight;
|
||||
}
|
||||
|
||||
private double GetRadius(RenderType renderType)
|
||||
{
|
||||
return GetExtrusionWidth(renderType) / 2;
|
||||
}
|
||||
|
||||
private double GetExtrusionWidth(RenderType renderType)
|
||||
{
|
||||
double width = GCodeRenderer.ExtruderWidth;
|
||||
if ((renderType & RenderType.SimulateExtrusion) == RenderType.SimulateExtrusion)
|
||||
{
|
||||
double moveLength = (end - start).Length;
|
||||
|
||||
if (moveLength > .1) // we get truncation errors from the slice engine when the length is very small, so don't do them
|
||||
{
|
||||
double area = extrusionVolumeMm3 / moveLength;
|
||||
width = area / layerHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: adjust line render to reduce the height of the line as well
|
||||
//
|
||||
// Force line width to 0.1 when SimulateExtrusion is disabled, to produce a visualization of the toolpath rather than the extrudate
|
||||
width = 0.1;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
public override void CreateRender3DData(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, GCodeRenderInfo renderInfo)
|
||||
{
|
||||
if ((renderInfo.CurrentRenderType & RenderType.Extrusions) == RenderType.Extrusions)
|
||||
{
|
||||
double radius = GetRadius(renderInfo.CurrentRenderType);
|
||||
|
||||
Color lineColor;
|
||||
|
||||
if (renderInfo.CurrentRenderType.HasFlag(RenderType.SpeedColors))
|
||||
{
|
||||
lineColor = color;
|
||||
}
|
||||
else if (renderInfo.CurrentRenderType.HasFlag(RenderType.GrayColors))
|
||||
{
|
||||
lineColor = this.gray;
|
||||
}
|
||||
else
|
||||
{
|
||||
lineColor = renderInfo.GetMaterialColor(toolIndex);
|
||||
}
|
||||
|
||||
CreateCylinder(colorVertexData, indexData, new Vector3(start), new Vector3(end), radius, 6, lineColor, layerHeight);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo, bool highlightFeature = false)
|
||||
{
|
||||
if (renderInfo.CurrentRenderType.HasFlag(RenderType.Extrusions))
|
||||
{
|
||||
double extrusionLineWidths = GetExtrusionWidth(renderInfo.CurrentRenderType) * 2 * renderInfo.LayerScale;
|
||||
|
||||
Color extrusionColor = Color.Black;
|
||||
|
||||
if (highlightFeature)
|
||||
{
|
||||
extrusionColor = RenderFeatureBase.HighlightColor;
|
||||
}
|
||||
else if (renderInfo.CurrentRenderType.HasFlag(RenderType.SpeedColors))
|
||||
{
|
||||
extrusionColor = color;
|
||||
}
|
||||
else if (renderInfo.CurrentRenderType.HasFlag(RenderType.GrayColors))
|
||||
{
|
||||
extrusionColor = Color.Gray;
|
||||
}
|
||||
else
|
||||
{
|
||||
extrusionColor = renderInfo.GetMaterialColor(toolIndex);
|
||||
}
|
||||
|
||||
if (renderInfo.CurrentRenderType.HasFlag(RenderType.TransparentExtrusion))
|
||||
{
|
||||
extrusionColor = new Color(extrusionColor, 200);
|
||||
}
|
||||
|
||||
if (graphics2D is Graphics2DOpenGL graphics2DGl)
|
||||
{
|
||||
// render using opengl
|
||||
var startPoint = new Vector2(start.X, start.Y);
|
||||
renderInfo.Transform.transform(ref startPoint);
|
||||
|
||||
var endPoint = new Vector2(end.X, end.Y);
|
||||
renderInfo.Transform.transform(ref endPoint);
|
||||
|
||||
var eWidth = extrusionLineWidths / 2;
|
||||
|
||||
graphics2DGl.DrawAALineRounded(startPoint, endPoint, eWidth, extrusionColor);
|
||||
|
||||
if (highlightFeature)
|
||||
{
|
||||
Render3DStartEndMarkers(graphics2DGl, eWidth / 2, startPoint, endPoint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// render using agg
|
||||
var pathStorage = new VertexStorage();
|
||||
var transformedPathStorage = new VertexSourceApplyTransform(pathStorage, renderInfo.Transform);
|
||||
var stroke = new Stroke(transformedPathStorage, extrusionLineWidths / 2)
|
||||
{
|
||||
LineCap = LineCap.Round,
|
||||
LineJoin = LineJoin.Round
|
||||
};
|
||||
|
||||
pathStorage.Add(start.X, start.Y, FlagsAndCommand.MoveTo);
|
||||
pathStorage.Add(end.X, end.Y, FlagsAndCommand.LineTo);
|
||||
|
||||
graphics2D.Render(stroke, extrusionColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.VertexSource;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class RenderFeatureRetract : RenderFeatureBase
|
||||
{
|
||||
public static double RetractionDrawRadius = 1;
|
||||
|
||||
private float extrusionAmount;
|
||||
private float mmPerSecond;
|
||||
private Vector3Float position;
|
||||
|
||||
public RenderFeatureRetract(int instructionIndex, Vector3 position, double extrusionAmount, int extruderIndex, double mmPerSecond)
|
||||
: base(instructionIndex, extruderIndex)
|
||||
{
|
||||
this.extrusionAmount = (float)extrusionAmount;
|
||||
this.mmPerSecond = (float)mmPerSecond;
|
||||
|
||||
this.position = new Vector3Float(position);
|
||||
}
|
||||
|
||||
private double Radius(double layerScale)
|
||||
{
|
||||
double radius = RetractionDrawRadius * layerScale;
|
||||
double area = Math.PI * radius * radius;
|
||||
area *= Math.Abs(extrusionAmount);
|
||||
radius = Math.Sqrt(area / Math.PI);
|
||||
return radius;
|
||||
}
|
||||
|
||||
public override void CreateRender3DData(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, GCodeRenderInfo renderInfo)
|
||||
{
|
||||
if ((renderInfo.CurrentRenderType & RenderType.Retractions) == RenderType.Retractions)
|
||||
{
|
||||
var position = new Vector3(this.position);
|
||||
|
||||
// retract and unretract are the extruder color
|
||||
Color color = renderInfo.GetMaterialColor(toolIndex);
|
||||
// except for extruder 0 where they are the red and blue we are familiar with
|
||||
if (toolIndex == 0)
|
||||
{
|
||||
if (extrusionAmount > 0)
|
||||
{
|
||||
color = Color.Blue;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = Color.Red;
|
||||
}
|
||||
}
|
||||
if (extrusionAmount > 0)
|
||||
{
|
||||
// unretraction
|
||||
CreatePointer(colorVertexData, indexData, position + new Vector3(0, 0, 1.3), position + new Vector3(0, 0, .3), Radius(1), 5, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// retraction
|
||||
CreatePointer(colorVertexData, indexData, position + new Vector3(0, 0, .3), position + new Vector3(0, 0, 1.3), Radius(1), 5, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo, bool highlightFeature = false)
|
||||
{
|
||||
if ((renderInfo.CurrentRenderType & RenderType.Retractions) == RenderType.Retractions)
|
||||
{
|
||||
double radius = Radius(renderInfo.LayerScale);
|
||||
|
||||
var position = new Vector2(this.position.X, this.position.Y);
|
||||
renderInfo.Transform.transform(ref position);
|
||||
|
||||
var retractionColor = new Color(Color.Red, 200);
|
||||
if (highlightFeature)
|
||||
{
|
||||
retractionColor = RenderFeatureBase.HighlightColor;
|
||||
}
|
||||
else if (extrusionAmount > 0)
|
||||
{
|
||||
// unretraction
|
||||
retractionColor = Color.Blue.WithAlpha(120);
|
||||
}
|
||||
|
||||
if (graphics2D is Graphics2DOpenGL graphics2DGl)
|
||||
{
|
||||
// render using opengl
|
||||
graphics2DGl.DrawAACircle(position, radius, retractionColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// render using agg
|
||||
graphics2D.Render(
|
||||
new Ellipse(position, radius),
|
||||
retractionColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright (c) 2019, Lars Brubaker, John Lewin
|
||||
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.
|
||||
*/
|
||||
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.Agg.VertexSource;
|
||||
using MatterHackers.RenderOpenGl;
|
||||
using MatterHackers.VectorMath;
|
||||
|
||||
namespace MatterHackers.GCodeVisualizer
|
||||
{
|
||||
public class RenderFeatureTravel : RenderFeatureBase
|
||||
{
|
||||
protected Vector3Float start;
|
||||
protected Vector3Float end;
|
||||
|
||||
protected float travelSpeed;
|
||||
private bool retractionTravel;
|
||||
|
||||
public Vector3Float Start => start;
|
||||
|
||||
public Vector3Float End => end;
|
||||
|
||||
public RenderFeatureTravel(int instructionIndex, Vector3 start, Vector3 end, int toolIndex, double travelSpeed, bool retractionTravel)
|
||||
: base(instructionIndex, toolIndex)
|
||||
{
|
||||
this.toolIndex = toolIndex;
|
||||
this.start = new Vector3Float(start);
|
||||
this.end = new Vector3Float(end);
|
||||
this.travelSpeed = (float)travelSpeed;
|
||||
this.retractionTravel = retractionTravel;
|
||||
}
|
||||
|
||||
public override void CreateRender3DData(VectorPOD<ColorVertexData> colorVertexData, VectorPOD<int> indexData, GCodeRenderInfo renderInfo)
|
||||
{
|
||||
if ((renderInfo.CurrentRenderType & RenderType.Moves) == RenderType.Moves)
|
||||
{
|
||||
CreateCylinder(colorVertexData, indexData, new Vector3(start), new Vector3(end), .1, 6, retractionTravel ? GCodeRenderer.RetractionColor : GCodeRenderer.TravelColor, .2);
|
||||
}
|
||||
}
|
||||
|
||||
protected void Render3DStartEndMarkers(Graphics2DOpenGL graphics2DGl, double radius, Vector2 startPoint, Vector2 endPoint)
|
||||
{
|
||||
graphics2DGl.DrawAACircle(startPoint, radius, RenderFeatureBase.StartColor);
|
||||
graphics2DGl.DrawAACircle(endPoint, radius, RenderFeatureBase.EndColor);
|
||||
}
|
||||
|
||||
public override void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo, bool highlightFeature = false)
|
||||
{
|
||||
if ((renderInfo.CurrentRenderType & RenderType.Moves) == RenderType.Moves)
|
||||
{
|
||||
double movementLineWidth = 0.2 * renderInfo.LayerScale;
|
||||
Color movementColor = (highlightFeature) ? RenderFeatureBase.HighlightColor : new Color(10, 190, 15);
|
||||
|
||||
if (graphics2D is Graphics2DOpenGL graphics2DGl)
|
||||
{
|
||||
// render using opengl
|
||||
var startPoint = new Vector2(start.X, start.Y);
|
||||
renderInfo.Transform.transform(ref startPoint);
|
||||
|
||||
var endPoint = new Vector2(end.X, end.Y);
|
||||
renderInfo.Transform.transform(ref endPoint);
|
||||
|
||||
if (retractionTravel)
|
||||
{
|
||||
movementColor = GCodeRenderer.RetractionColor;
|
||||
}
|
||||
|
||||
if (renderInfo.CurrentRenderType.HasFlag(RenderType.TransparentExtrusion))
|
||||
{
|
||||
movementColor = movementColor.WithAlpha(120);
|
||||
}
|
||||
|
||||
graphics2DGl.DrawAALineRounded(startPoint, endPoint, movementLineWidth, movementColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
// render using agg
|
||||
var pathStorage = new VertexStorage();
|
||||
var transformedPathStorage = new VertexSourceApplyTransform(pathStorage, renderInfo.Transform);
|
||||
var stroke = new Stroke(transformedPathStorage, movementLineWidth)
|
||||
{
|
||||
LineCap = LineCap.Round,
|
||||
LineJoin = LineJoin.Round
|
||||
};
|
||||
|
||||
pathStorage.Add(start.X, start.Y, FlagsAndCommand.MoveTo);
|
||||
if (end.X != start.X || end.Y != start.Y)
|
||||
{
|
||||
pathStorage.Add(end.X, end.Y, FlagsAndCommand.LineTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
pathStorage.Add(end.X + .01, end.Y, FlagsAndCommand.LineTo);
|
||||
}
|
||||
|
||||
graphics2D.Render(stroke, movementColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue