2017-06-21 23:26:20 -07:00
|
|
|
|
/*
|
|
|
|
|
|
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;
|
2018-01-05 12:44:57 -08:00
|
|
|
|
using MatterControl.Printing;
|
2017-06-21 23:26:20 -07:00
|
|
|
|
using MatterHackers.Agg;
|
2017-08-24 13:58:06 -07:00
|
|
|
|
using MatterHackers.Agg.UI;
|
2017-06-21 23:26:20 -07:00
|
|
|
|
using MatterHackers.RenderOpenGl;
|
|
|
|
|
|
using MatterHackers.RenderOpenGl.OpenGl;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MatterHackers.GCodeVisualizer
|
|
|
|
|
|
{
|
|
|
|
|
|
[Flags]
|
|
|
|
|
|
public enum RenderType
|
|
|
|
|
|
{
|
|
|
|
|
|
None = 0,
|
|
|
|
|
|
Extrusions = 1,
|
|
|
|
|
|
Moves = 2,
|
|
|
|
|
|
Retractions = 4,
|
|
|
|
|
|
SpeedColors = 8,
|
|
|
|
|
|
SimulateExtrusion = 16,
|
2017-07-07 12:10:24 -07:00
|
|
|
|
TransparentExtrusion = 64,
|
2018-02-09 19:23:19 -08:00
|
|
|
|
GrayColors = 128
|
2017-07-07 12:10:24 -07:00
|
|
|
|
};
|
2017-06-21 23:26:20 -07:00
|
|
|
|
|
|
|
|
|
|
public class GCodeRenderer : IDisposable
|
|
|
|
|
|
{
|
|
|
|
|
|
public static double ExtruderWidth { get; set; } = .4;
|
|
|
|
|
|
|
2019-02-22 06:18:50 -08:00
|
|
|
|
public static Color TravelColor = Color.Green;
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly bool Is32Bit = IntPtr.Size == 4;
|
|
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
private List<List<int>> featureStartIndex = new List<List<int>>();
|
|
|
|
|
|
private List<List<int>> featureEndIndex = new List<List<int>>();
|
|
|
|
|
|
private List<List<RenderFeatureBase>> renderFeatures = new List<List<RenderFeatureBase>>();
|
|
|
|
|
|
|
2019-02-22 06:18:50 -08:00
|
|
|
|
private List<GCodeVertexBuffer> layerVertexBuffer;
|
|
|
|
|
|
private RenderType lastRenderType = RenderType.None;
|
|
|
|
|
|
private GCodeRenderInfo renderInfo;
|
2017-06-21 23:26:20 -07:00
|
|
|
|
private GCodeFile gCodeFileToDraw;
|
2018-10-13 17:58:54 -07:00
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
public GCodeRenderer(GCodeFile gCodeFileToDraw)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (gCodeFileToDraw != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.gCodeFileToDraw = gCodeFileToDraw;
|
|
|
|
|
|
|
2018-03-30 21:13:00 -07:00
|
|
|
|
if (gCodeFileToDraw is GCodeMemoryFile memoryFile)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.ExtrusionColors = new ExtrusionColors(memoryFile.Speeds);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-29 13:35:44 -07:00
|
|
|
|
for (int i = 0; i < gCodeFileToDraw.LayerCount; i++)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
|
|
|
|
|
renderFeatures.Add(new List<RenderFeatureBase>());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-22 06:18:50 -08:00
|
|
|
|
public GCodeFile GCodeFileToDraw => gCodeFileToDraw;
|
|
|
|
|
|
|
|
|
|
|
|
public ExtrusionColors ExtrusionColors { get; } = null;
|
|
|
|
|
|
|
|
|
|
|
|
public Color Gray { get; set; }
|
|
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
public void CreateFeaturesForLayerIfRequired(int layerToCreate)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (renderFeatures.Count == 0
|
|
|
|
|
|
|| renderFeatures[layerToCreate].Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<RenderFeatureBase> renderFeaturesForLayer = renderFeatures[layerToCreate];
|
|
|
|
|
|
|
2018-05-30 16:42:17 -07:00
|
|
|
|
int startRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
int endRenderIndex = gCodeFileToDraw.LineCount - 1;
|
2017-06-29 13:35:44 -07:00
|
|
|
|
if (layerToCreate < gCodeFileToDraw.LayerCount - 1)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
2018-05-30 16:42:17 -07:00
|
|
|
|
endRenderIndex = gCodeFileToDraw.GetFirstLayerInstruction(layerToCreate + 1);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2018-12-11 14:10:27 -08:00
|
|
|
|
double eMovement = 0;
|
|
|
|
|
|
if (currentInstruction.PositionSet != PositionSet.E)
|
|
|
|
|
|
{
|
|
|
|
|
|
eMovement = currentInstruction.EPosition - previousInstruction.EPosition;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Math.Abs(eMovement) > 0)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
|
|
|
|
|
// this is a retraction
|
2019-03-05 17:55:44 -08:00
|
|
|
|
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, eMovement, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
if (currentInstruction.Line.StartsWith("G10"))
|
|
|
|
|
|
{
|
2019-03-05 17:55:44 -08:00
|
|
|
|
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, -1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
else if (currentInstruction.Line.StartsWith("G11"))
|
|
|
|
|
|
{
|
2019-03-05 17:55:44 -08:00
|
|
|
|
renderFeaturesForLayer.Add(new RenderFeatureRetract(instructionIndex, currentInstruction.Position, 1, currentInstruction.ToolIndex, currentInstruction.FeedRate));
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (gCodeFileToDraw.IsExtruding(instructionIndex))
|
|
|
|
|
|
{
|
2018-05-08 15:19:06 -07:00
|
|
|
|
double layerThickness = gCodeFileToDraw.GetLayerHeight(layerToCreate);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
|
2018-03-30 21:13:00 -07:00
|
|
|
|
Color extrusionColor = ExtrusionColors.GetColorForSpeed((float)currentInstruction.FeedRate);
|
2018-10-13 17:58:54 -07:00
|
|
|
|
renderFeaturesForLayer.Add(
|
|
|
|
|
|
new RenderFeatureExtrusion(
|
2019-03-05 17:55:44 -08:00
|
|
|
|
instructionIndex,
|
2018-10-13 17:58:54 -07:00
|
|
|
|
previousInstruction.Position,
|
|
|
|
|
|
currentInstruction.Position,
|
2019-03-04 08:04:29 -08:00
|
|
|
|
currentInstruction.ToolIndex,
|
2018-10-13 17:58:54 -07:00
|
|
|
|
currentInstruction.FeedRate,
|
|
|
|
|
|
currentInstruction.EPosition - previousInstruction.EPosition,
|
|
|
|
|
|
gCodeFileToDraw.GetFilamentDiameter(),
|
|
|
|
|
|
layerThickness,
|
|
|
|
|
|
extrusionColor,
|
|
|
|
|
|
this.Gray));
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-10-13 17:58:54 -07:00
|
|
|
|
renderFeaturesForLayer.Add(
|
|
|
|
|
|
new RenderFeatureTravel(
|
2019-03-05 17:55:44 -08:00
|
|
|
|
instructionIndex,
|
2018-10-13 17:58:54 -07:00
|
|
|
|
previousInstruction.Position,
|
|
|
|
|
|
currentInstruction.Position,
|
2019-03-04 08:04:29 -08:00
|
|
|
|
currentInstruction.ToolIndex,
|
2018-10-13 17:58:54 -07:00
|
|
|
|
currentInstruction.FeedRate));
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public int GetNumFeatures(int layerToCountFeaturesOn)
|
|
|
|
|
|
{
|
|
|
|
|
|
CreateFeaturesForLayerIfRequired(layerToCountFeaturesOn);
|
|
|
|
|
|
return renderFeatures[layerToCountFeaturesOn].Count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-22 09:22:13 -08:00
|
|
|
|
public RenderFeatureBase this[int layerIndex, int featureIndex]
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2019-03-19 15:12:24 -07:00
|
|
|
|
var layer = renderFeatures[layerIndex];
|
|
|
|
|
|
|
|
|
|
|
|
if (featureIndex < layer.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
return layer[featureIndex];
|
|
|
|
|
|
}
|
2019-02-22 09:22:13 -08:00
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
2019-03-19 15:12:24 -07:00
|
|
|
|
|
|
|
|
|
|
// Callers should test for non-null values
|
|
|
|
|
|
return null;
|
2019-02-22 09:22:13 -08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-22 22:24:39 -08:00
|
|
|
|
public bool GCodeInspector { get; set; } = false;
|
|
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
public void Render(Graphics2D graphics2D, GCodeRenderInfo renderInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (renderFeatures.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
CreateFeaturesForLayerIfRequired(renderInfo.EndLayerIndex);
|
|
|
|
|
|
|
|
|
|
|
|
int featuresOnLayer = renderFeatures[renderInfo.EndLayerIndex].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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Graphics2DOpenGL graphics2DGl = graphics2D as Graphics2DOpenGL;
|
|
|
|
|
|
if (graphics2DGl != null)
|
|
|
|
|
|
{
|
2018-10-30 19:03:39 -07:00
|
|
|
|
graphics2DGl.PreRender(Color.White);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
GL.Begin(BeginMode.Triangles);
|
2019-02-22 07:41:14 -08:00
|
|
|
|
|
|
|
|
|
|
int lastFeature = endFeature - 1;
|
2017-06-21 23:26:20 -07:00
|
|
|
|
for (int i = startFeature; i < endFeature; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
RenderFeatureBase feature = renderFeatures[renderInfo.EndLayerIndex][i];
|
|
|
|
|
|
if (feature != null)
|
|
|
|
|
|
{
|
2019-02-22 22:24:39 -08:00
|
|
|
|
feature.Render(graphics2DGl, renderInfo, highlightFeature: this.GCodeInspector && i == lastFeature);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
GL.End();
|
|
|
|
|
|
graphics2DGl.PopOrthoProjection();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = startFeature; i < endFeature; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
RenderFeatureBase feature = renderFeatures[renderInfo.EndLayerIndex][i];
|
|
|
|
|
|
if (feature != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
feature.Render(graphics2D, renderInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-12 12:03:17 -07:00
|
|
|
|
private GCodeVertexBuffer Create3DDataForLayer(int layerIndex, GCodeRenderInfo renderInfo)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
2018-07-12 12:03:17 -07:00
|
|
|
|
var colorVertexData = new VectorPOD<ColorVertexData>();
|
|
|
|
|
|
var vertexIndexArray = new VectorPOD<int>();
|
|
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
featureStartIndex[layerIndex].Clear();
|
|
|
|
|
|
featureEndIndex[layerIndex].Clear();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < renderFeatures[layerIndex].Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
featureStartIndex[layerIndex].Add(vertexIndexArray.Count);
|
2018-07-12 12:03:17 -07:00
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
RenderFeatureBase feature = renderFeatures[layerIndex][i];
|
2018-07-12 12:03:17 -07:00
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
if (feature != null)
|
|
|
|
|
|
{
|
2018-07-12 12:03:17 -07:00
|
|
|
|
// Build the color and index data for the feature
|
2017-06-21 23:26:20 -07:00
|
|
|
|
feature.CreateRender3DData(colorVertexData, vertexIndexArray, renderInfo);
|
|
|
|
|
|
}
|
2018-07-12 12:03:17 -07:00
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
featureEndIndex[layerIndex].Add(vertexIndexArray.Count);
|
|
|
|
|
|
}
|
2018-07-12 12:03:17 -07:00
|
|
|
|
|
|
|
|
|
|
// Construct and return the new VertexBuffer object with all color/index data
|
|
|
|
|
|
return new GCodeVertexBuffer(vertexIndexArray.Array, colorVertexData.Array);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-08-24 13:58:06 -07:00
|
|
|
|
public void Render3D(GCodeRenderInfo renderInfo, DrawEventArgs e)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
2017-06-28 20:48:00 -07:00
|
|
|
|
if (renderInfo == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-21 23:26:20 -07:00
|
|
|
|
if (layerVertexBuffer == null)
|
|
|
|
|
|
{
|
2018-07-12 12:03:43 -07:00
|
|
|
|
layerVertexBuffer = new List<GCodeVertexBuffer>(gCodeFileToDraw.LayerCount);
|
2017-06-29 13:35:44 -07:00
|
|
|
|
for (int layerIndex = 0; layerIndex < gCodeFileToDraw.LayerCount; layerIndex++)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
|
|
|
|
|
layerVertexBuffer.Add(null);
|
|
|
|
|
|
featureStartIndex.Add(new List<int>());
|
|
|
|
|
|
featureEndIndex.Add(new List<int>());
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-29 13:35:44 -07:00
|
|
|
|
for (int layerIndex = 0; layerIndex < gCodeFileToDraw.LayerCount; layerIndex++)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
|
|
|
|
|
CreateFeaturesForLayerIfRequired(layerIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lastRenderType != renderInfo.CurrentRenderType)
|
|
|
|
|
|
{
|
|
|
|
|
|
Clear3DGCode();
|
|
|
|
|
|
lastRenderType = renderInfo.CurrentRenderType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (renderFeatures.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
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.
|
2019-05-24 17:35:18 -07:00
|
|
|
|
if (layerVertexBuffer.Count > i
|
|
|
|
|
|
&& layerVertexBuffer[i] == null)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
2018-07-12 12:03:17 -07:00
|
|
|
|
layerVertexBuffer[i] = Create3DDataForLayer(i, renderInfo);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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++)
|
|
|
|
|
|
{
|
|
|
|
|
|
int featuresOnLayer = renderFeatures[i].Count;
|
2018-07-18 14:59:36 -07:00
|
|
|
|
if (featuresOnLayer > 1
|
|
|
|
|
|
&& layerVertexBuffer[i] != null)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
2018-07-12 12:17:11 -07:00
|
|
|
|
layerVertexBuffer[i].RenderRange(0, featureEndIndex[i][featuresOnLayer - 1]);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// draw the partial layer of end-1 from startRatio to endRatio
|
|
|
|
|
|
{
|
|
|
|
|
|
int layerIndex = renderInfo.EndLayerIndex - 1;
|
|
|
|
|
|
int featuresOnLayer = renderFeatures[layerIndex].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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-18 14:59:36 -07:00
|
|
|
|
if (endFeature > startFeature
|
|
|
|
|
|
&& layerVertexBuffer[layerIndex] != null)
|
2017-06-21 23:26:20 -07:00
|
|
|
|
{
|
|
|
|
|
|
int ellementCount = featureEndIndex[layerIndex][endFeature - 1] - featureStartIndex[layerIndex][startFeature];
|
|
|
|
|
|
|
2018-07-12 12:17:11 -07:00
|
|
|
|
layerVertexBuffer[layerIndex].RenderRange(featureStartIndex[layerIndex][startFeature], ellementCount);
|
2017-06-21 23:26:20 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
GL.PopAttrib();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|