internal void FilterSupportCones()
        {
            //find all available overhangdistancefactors
            var availableOverhangDistanceFactors = new SortedList <float, bool>();

            foreach (var surfaceIntersectionData in this.SupportCones.Keys)
            {
                if (!availableOverhangDistanceFactors.ContainsKey(surfaceIntersectionData.OverhangDistance))
                {
                    availableOverhangDistanceFactors.Add(surfaceIntersectionData.OverhangDistance, false);
                }
            }

            var currentDistanceIndex = 0;

            //find all support cones that are lower

            while (currentDistanceIndex < availableOverhangDistanceFactors.Count - 2)
            {
                var currentDistanceOverhangFactor = availableOverhangDistanceFactors.ElementAt(currentDistanceIndex).Key;
                var currentSupportConesWithSameOverhangDistance   = new Dictionary <MagsAISurfaceIntersectionData, SupportCone>();
                var currentSupportConesWithLargerOverhangDistance = new Dictionary <MagsAISurfaceIntersectionData, SupportCone>();
                foreach (var surfaceIntersectionData in this.SupportCones.Keys)
                {
                    if (surfaceIntersectionData.OverhangDistance > currentDistanceOverhangFactor && surfaceIntersectionData.Filter == typeOfAutoSupportFilter.None)
                    {
                        currentSupportConesWithLargerOverhangDistance.Add(surfaceIntersectionData, this.SupportCones[surfaceIntersectionData]);
                    }
                    else if (surfaceIntersectionData.OverhangDistance == currentDistanceOverhangFactor && surfaceIntersectionData.Filter == typeOfAutoSupportFilter.None)
                    {
                        currentSupportConesWithSameOverhangDistance.Add(surfaceIntersectionData, this.SupportCones[surfaceIntersectionData]);
                    }
                }

                //find all support cones with larger distance factor that are below current support cone and within range
                foreach (var currentSupportConeWithSameOverhangDistance in currentSupportConesWithSameOverhangDistance)
                {
                    var intersectedSupportCones = new Dictionary <MagsAISurfaceIntersectionData, SupportCone>();
                    foreach (var currentSupportConeWithLargerOverhangDistance in currentSupportConesWithLargerOverhangDistance)
                    {
                        if (currentSupportConeWithLargerOverhangDistance.Key.SliceHeight <= currentSupportConeWithSameOverhangDistance.Key.SliceHeight)
                        {
                            intersectedSupportCones.Add(currentSupportConeWithLargerOverhangDistance.Key, currentSupportConeWithLargerOverhangDistance.Value);
                        }
                    }

                    //calc support cone contour
                    var currentSupportConeWithSameOverhangDistanceContour = MagsAIEngine.ConvertSupportPointsToCircles(currentSupportConeWithSameOverhangDistance.Key.TopPoint, 5);

                    foreach (var intersectedSupportCone in intersectedSupportCones.Keys)
                    {
                        if (Clipper.PointInPolygon(intersectedSupportCone.TopPoint, currentSupportConeWithSameOverhangDistanceContour) != 0)
                        {
                            intersectedSupportCone.Filter = typeOfAutoSupportFilter.FilteredBySupportConeOverhangWithinRange; //using internal references to update this.supportcones.keys
                        }
                    }
                }
                currentDistanceIndex++;
            }
        }
Exemple #2
0
        private void TbWizard_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tbWizard.SelectedTab == this.tbMagsAIOrientation)
            {
                var stlModel = ObjectView.Objects3D[1] as STLModel3D;
                stlModel.Triangles.UpdateConnections();
                this.magsAIOrientationTabPanel1.GLControl.Render();
            }
            else if (tbWizard.SelectedTab == this.tbPreview)
            {
                this.magsAIPreview1.GLControl.Render();

                var stlModel = ObjectView.Objects3D[1] as STLModel3D;
                Task.Run(() => MagsAIEngine.Calculate(stlModel, this.magsAIMaterialTabPanel1.SelectedMaterial, this.magsAIMaterialTabPanel1.SelectedPrinter));
            }
        }
Exemple #3
0
        private void CalcTrianglesWithinRange(Vector3Class supportPointPosition, SupportProfile selectedMaterialProfile, STLModel3D stlModel)
        {
            var boundryOffset = selectedMaterialProfile.SupportOverhangDistance;

            var modelTrianglesLeftBoundry        = supportPointPosition.X - boundryOffset;
            var modelTrianglesRightBoundry       = supportPointPosition.X + boundryOffset;
            var modelTrianglesBackBoundry        = supportPointPosition.Y - boundryOffset;
            var modelTrianglesFrontBoundry       = supportPointPosition.Y + boundryOffset;
            var currentSupportConeSupportedLayer = MagsAIEngine.ConvertSupportPointsToCircles(new IntPoint(supportPointPosition), selectedMaterialProfile.SupportOverhangDistance);

            currentSupportConeSupportedLayer.Add(new IntPoint(supportPointPosition));

            this._trianglesWithinXYRange = new STLModel3D
            {
                Triangles = stlModel.Triangles.GetTrianglesWithinXYBoundry(modelTrianglesLeftBoundry, modelTrianglesBackBoundry, modelTrianglesRightBoundry, modelTrianglesFrontBoundry)
            };
        }
Exemple #4
0
        internal void CalcPolyNode(SupportProfile selectedMaterialProfile, AtumPrinter selectedPrinter, float sliceHeight, int objectIndex)
        {
            this.PolyTree = new PolyTree();
            var polygonPoints = new List <IntPoint>();

            foreach (var polyLinePart in this)
            {
                var tStart = (polyLinePart.P1 - new Vector3Class(selectedPrinter.ProjectorResolutionX / 2, selectedPrinter.ProjectorResolutionY / 2, 0)) / 10f;
                tStart -= new Vector3Class(0.1f, 0.1f, 0);
                DebugPoints.Add(tStart);
                polygonPoints.Add(new IntPoint(tStart + new Vector3Class(0, 0, sliceHeight)));
            }

            //add the end of the line
            var tEnd = (this.Last().P2 - new Vector3Class(selectedPrinter.ProjectorResolutionX / 2, selectedPrinter.ProjectorResolutionY / 2, 0)) / 10f;

            tEnd -= new Vector3Class(0.1f, 0.1f, 0);
            polygonPoints.Add(new IntPoint(tEnd));

            //when not closed use normals to create offset points
            if (!ClosedLine)
            {
                this.Reverse();
                //  this.Reverse();
                var normalVector = new Vector3Class();
                foreach (var polyLinePart in this)
                {
                    normalVector  += polyLinePart.Normal;
                    normalVector.Z = 0;
                    normalVector.Normalize();
                    normalVector *= selectedMaterialProfile.SupportOverhangDistance / 2;

                    //do point offset
                    var tPoint = normalVector + ((polyLinePart.P1 - new Vector3Class(selectedPrinter.ProjectorResolutionX / 2, selectedPrinter.ProjectorResolutionY / 2, 0)) / 10f);
                    tPoint -= new Vector3Class(0.1f, 0.1f, 0);
                    DebugPoints.Add(tPoint + new Vector3Class(0, 0, sliceHeight));
                    polygonPoints.Add(new IntPoint(tPoint));

                    normalVector = polyLinePart.Normal;
                }

                var polyTreeOffset = new PolyTree();
                var polyNode       = new PolyNode();
                polyNode.m_polygon = polygonPoints;
                polyTreeOffset._allPolys.Add(polyNode);

                var c = new Clipper();
                c.AddPath(polyTreeOffset._allPolys[0].Contour, PolyType.ptClip, true);
                c.AddPath(new List <IntPoint>(), PolyType.ptSubject, true);

                c.Execute(ClipType.ctXor, this.PolyTree, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

                //if (sliceHeight >=13 && sliceHeight <=15f)
                // TriangleHelper.SavePolyNodesContourToPng(this.PolyTree._allPolys, sliceHeight.ToString("0.00") + "-"  + objectIndex.ToString() + "-t2");
            }
            else
            {
                var polyTreeOffset = new PolyTree();
                var polyNode       = new PolyNode();
                polyNode.m_polygon = polygonPoints;
                polyTreeOffset._allPolys.Add(polyNode);
                polyTreeOffset = MagsAIEngine.ClipperOffset(polyTreeOffset, selectedMaterialProfile.SupportOverhangDistance / 2);

                if (polyTreeOffset._allPolys.Count > 0)
                {
                    var c = new Clipper();
                    c.AddPath(polygonPoints, PolyType.ptClip, true);
                    c.AddPath(polyTreeOffset._allPolys[0].Contour, PolyType.ptClip, true);
                    c.AddPath(new List <IntPoint>(), PolyType.ptSubject, true);

                    c.Execute(ClipType.ctXor, this.PolyTree, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);
                }
            }
        }
Exemple #5
0
        internal void UpdateLastSupportedHeight(STLModel3D stlModel, SupportProfile selectedMaterialProfile, SortedDictionary <float, PolyTree> modelLayers)
        {
            //find latest supportcone supported height

            var supportPointPosition = this.TopPoint;

            supportPointPosition.Z = this.SliceHeight - 1;

            if (this._trianglesWithinXYRange == null)
            {
                CalcTrianglesWithinRange(supportPointPosition, selectedMaterialProfile, stlModel);
            }

            var trianglesAboveSupportPoint = new STLModel3D()
            {
                Triangles = new TriangleInfoList()
            };

            trianglesAboveSupportPoint.Triangles[0] = this._trianglesWithinXYRange.Triangles[0].Where(s => s.Bottom > supportPointPosition.Z && s.Normal.Z > 0).ToList();

            var maxLayerHeight = float.MinValue;
            var currentSupportConeSupportedLayer = MagsAIEngine.ConvertSupportPointsToCircles(new IntPoint(supportPointPosition), selectedMaterialProfile.SupportOverhangDistance);

            currentSupportConeSupportedLayer.Add(new IntPoint(supportPointPosition));
            foreach (var t in currentSupportConeSupportedLayer)
            {
                TriangleIntersection[] trianglesIntersected = null;
                IntersectionProvider.IntersectTriangle(t.AsVector3(), new Vector3Class(0, 0, -1), trianglesAboveSupportPoint, IntersectionProvider.typeDirection.OneWay, false, new Vector3Class(), out trianglesIntersected);

                var nearestTriangleIntersection = float.MaxValue;
                TriangleIntersection nearestIntersectionPoint = null;
                if (trianglesIntersected != null)
                {
                    foreach (var triangleIntersected in trianglesIntersected)
                    {
                        if (triangleIntersected != null)
                        {
                            if (triangleIntersected.IntersectionPoint.Z >= this.SliceHeight)
                            {
                                var distance = (new  Vector3Class(supportPointPosition.X, supportPointPosition.Y, triangleIntersected.IntersectionPoint.Z) - supportPointPosition).Length;
                                if (distance < nearestTriangleIntersection)
                                {
                                    nearestTriangleIntersection = distance;
                                    nearestIntersectionPoint    = triangleIntersected;
                                }
                            }
                        }
                    }
                }

                if (nearestIntersectionPoint != null && nearestIntersectionPoint.IntersectionPoint.Z > maxLayerHeight)
                {
                    maxLayerHeight = nearestIntersectionPoint.IntersectionPoint.Z;
                }
            }


            if (maxLayerHeight == float.MinValue)
            {
                maxLayerHeight = 10000;
            }

            this.LastSupportedSliceHeight = maxLayerHeight;
        }
        internal Dictionary <IntPoint, MagsAISurfaceIntersectionData> CalcSupportPoints(SortedDictionary <float, PolyTree> modelLayers, ConcurrentDictionary <float, ConcurrentDictionary <MagsAIIntersectionData, bool> > currentModelSupportPoints, float firstSurfaceAngleDistanceFactor, SupportProfile selectedMaterialProfile, float overhangFactor, ConcurrentDictionary <float, ConcurrentDictionary <float, ConcurrentDictionary <IntPoint, MagsAISurfaceIntersectionData> > > previousOverhangDistanceFactorBasedSupportPoints, STLModel3D stlModel, TriangleSurfaceInfo surface)
        {
            this.AddedSupportPoints        = new Dictionary <IntPoint, MagsAISurfaceIntersectionData>();
            this.AddedSupportPointsByLayer = new Dictionary <float, Dictionary <IntPoint, MagsAISurfaceIntersectionData> >();

            //create support cones that exists in each layer
            var previousSliceHeight = float.MaxValue;

            foreach (var sliceHeight in this.ModelContours.Keys.OrderBy(s => s))
            {
                var sliceContours = this.ModelContours[sliceHeight];
                sliceContours = ContourHelper.IntersectModelSliceLayer(sliceContours, modelLayers[sliceHeight]); //create contour offset using max border as model contour instead of extrude contour

                if (!this.AddedSupportPointsByLayer.ContainsKey(sliceHeight))
                {
                    this.AddedSupportPointsByLayer.Add(sliceHeight, new Dictionary <IntPoint, MagsAISurfaceIntersectionData>());
                }

                if (previousSliceHeight != float.MaxValue)
                {
                    var supportedLayerAsPolyTree = new PolyTree();
                    if (this.AddedSupportPointsByLayer.ContainsKey(previousSliceHeight))
                    {
                        foreach (var supportIntersectionData in this.AddedSupportPointsByLayer[previousSliceHeight].Values)
                        {
                            if (supportIntersectionData.UnsupportedContour)
                            {
                                this.AddedSupportPointsByLayer[sliceHeight].Add(supportIntersectionData.TopPoint, supportIntersectionData);
                            }
                        }
                    }

                    //added support circles from current diff layer with overhang distance
                    foreach (var overhangDistanceFactor in previousOverhangDistanceFactorBasedSupportPoints)
                    {
                        var previousAngleBasedSupportPointsAsCircles = new List <List <IntPoint> >();
                        if (overhangDistanceFactor.Value.ContainsKey(sliceHeight))
                        {
                            foreach (var previousAngleBasedSupportPoint in overhangDistanceFactor.Value[sliceHeight].Values)
                            {
                                AddPointToCurrentLayerWhenExistsInContour(sliceContours, previousAngleBasedSupportPoint, sliceHeight);
                            }
                        }
                    }

                    //check if supportcones where allready added using other algorithms
                    var supportSliceHeightsWithinRange = new List <float>()
                    {
                        (float)Math.Round(previousSliceHeight - (sliceHeight - previousSliceHeight), 2), sliceHeight
                    };
                    var supportSliceHeightsWithinRangeMin = supportSliceHeightsWithinRange[0];
                    var supportSliceHeightsWithinRangeMax = supportSliceHeightsWithinRange[1];
                    foreach (var supportPointIndex in currentModelSupportPoints)
                    {
                        foreach (var supportPointValue in supportPointIndex.Value.Keys)
                        {
                            if (supportPointValue.SliceHeight <= sliceHeight && supportPointValue.LastSupportSliceHeight >= supportSliceHeightsWithinRangeMin)
                            {
                                var supportSlicePointAsIntPoint = new IntPoint(supportPointValue.TopPoint);
                                if (!this.AddedSupportPointsByLayer[sliceHeight].ContainsKey(supportSlicePointAsIntPoint))
                                {
                                    var supportConePoint2 = new MagsAISurfaceIntersectionData();
                                    supportConePoint2.TopPoint               = supportSlicePointAsIntPoint;
                                    supportConePoint2.SliceHeight            = sliceHeight;
                                    supportConePoint2.OverhangDistanceFactor = firstSurfaceAngleDistanceFactor;
                                    supportConePoint2.ModelIntersection      = supportPointValue.ModelIntersection;
                                    supportConePoint2.LastSupportSliceHeight = supportPointValue.LastSupportSliceHeight;

                                    this.AddedSupportPointsByLayer[sliceHeight].Add(supportConePoint2.TopPoint, supportConePoint2);
                                }
                            }
                        }
                    }


                    //combine all previous found points
                    supportedLayerAsPolyTree = new PolyTree();
                    if (AddedSupportPointsByLayer.ContainsKey(sliceHeight))
                    {
                        var supportCircles = new List <List <IntPoint> >();
                        foreach (var addedSupportPointByLayer in AddedSupportPointsByLayer[sliceHeight].Values)
                        {
                            var outlineCirclePoints = MagsAIEngine.ConvertSupportPointsToCircles(addedSupportPointByLayer.TopPoint, selectedMaterialProfile.SupportOverhangDistance);
                            supportCircles.Add(outlineCirclePoints);
                            var outlineCirclePolygon = MagsAIEngine.MergeSupportCircles(new List <List <IntPoint> >()
                            {
                                outlineCirclePoints
                            });
                            var intersectedPolygons = ContourHelper.IntersectModelSliceLayer(ModelContours[sliceHeight], outlineCirclePolygon);

                            var intersectedPolygonFound = false;
                            foreach (var intersectedPolygon in intersectedPolygons._allPolys.Where(s => !s.IsHole))
                            {
                                if (ContourHelper.PointExistsInNotHolePolygon(intersectedPolygon, addedSupportPointByLayer.TopPoint))
                                {
                                    supportedLayerAsPolyTree._allPolys.Add(intersectedPolygon);
                                    break;
                                }
                            }

                            //check if intersected triangle is part of angle surface
                            if (!intersectedPolygonFound)
                            {
                                //check if triangle index is in surface
                                var pointFound = false;
                                foreach (var surfaceConnection in surface.Keys)
                                {
                                    if (addedSupportPointByLayer.ModelIntersection != null)
                                    {
                                        if (surfaceConnection.ArrayIndex == addedSupportPointByLayer.ModelIntersection.Index.ArrayIndex && surfaceConnection.TriangleIndex == addedSupportPointByLayer.ModelIntersection.Index.TriangleIndex)
                                        {
                                            foreach (var intersectedPolygon in intersectedPolygons._allPolys.Where(s => !s.IsHole))
                                            {
                                                supportedLayerAsPolyTree._allPolys.Add(intersectedPolygon);
                                                pointFound = true;
                                            }
                                            break;
                                        }
                                    }
                                }

                                if (!pointFound)
                                {
                                }
                            }
                        }

                        // TriangleHelper.SavePolyNodesContourToPng(ModelContours[sliceHeight]._allPolys, surface.Id.ToString("00") + "-" + sliceHeight.ToString("0.00") + "-" + overhangFactor.ToString(".00") + "-model");
//                        TriangleHelper.SavePolyNodesContourToPng(intersectedPolygons._allPolys, surface.Id.ToString("00") + "-" + sliceHeight.ToString("0.00") + "-" + overhangFactor.ToString(".00") + "-intersected");


                        //TriangleHelper.SavePolyNodesContourToPng(MagsAIEngine.MergeSupportCircles(supportCircles)._allPolys, surface.Id.ToString("00") + "-" + sliceHeight.ToString("0.00") + "-" + overhangFactor.ToString(".00") + "-supportcircles");

                        supportedLayerAsPolyTree = UnionModelSliceLayer(new PolyTree(), supportedLayerAsPolyTree);

                        //TriangleHelper.SavePolyNodesContourToPng(supportedLayerAsPolyTree._allPolys, surface.Id.ToString("00") + "-" + sliceHeight.ToString("0.00") + "-" + overhangFactor.ToString(".00") + "-supportedlayer");
                    }


                    //  this.SupportedLayers.Add(sliceHeight, supportedLayerAsPolyTree);
                    var unsupportedLayer = DifferenceModelSliceLayer(sliceContours, supportedLayerAsPolyTree);
                    ////if (sliceHeight >= 15f && sliceHeight <= 16f)
                    //    {
                    foreach (var verticalSurface in stlModel.Triangles.MagsAIVerticalSurfaces)
                    {
                        verticalSurface.UpdateBoundries(stlModel.Triangles);
                        if (verticalSurface.BottomPoint <= this.BottomPoint)
                        {
                            foreach (var workingSliceHeight in verticalSurface.VerticalSurfaceModelPolygons.Keys)
                            {
                                if (workingSliceHeight >= previousSliceHeight - 0.4f && workingSliceHeight <= sliceHeight)
                                {
                                    //TriangleHelper.SavePolyNodesContourToPng(verticalSurface.VerticalSurfaceModelPolygons[workingSliceHeight]._allPolys, sliceHeight.ToString("0.00") + "-" + workingSliceHeight + "-subtract-vertical-contour");

                                    unsupportedLayer = DifferenceModelSliceLayer(unsupportedLayer, verticalSurface.VerticalSurfaceModelPolygons[workingSliceHeight]);
                                    // TriangleHelper.SavePolyNodesContourToPng(unsupportedLayer._allPolys, sliceHeight.ToString("0.00") + "-unsupported-vertical-contour");
                                }
                            }
                        }
                    }
                    //}

                    //remove supportedLayer from current diff layer and previous found support points
                    //TriangleHelper.SavePolyNodesContourToPng(unsupportedLayer._allPolys, surface.Id.ToString("00") + "-" + sliceHeight.ToString(".00") + "-" + overhangFactor.ToString(".00") + "-surface-unsupported");
                    if (unsupportedLayer._allPolys.Count > 0)
                    {
                        while (unsupportedLayer._allPolys.Where(s => !s.IsHole).Count() > 0)
                        {
                            var skippedUnsupportedLayerPolyNodes = new List <PolyNode>();
                            foreach (var unsupportLayerHole in unsupportedLayer._allPolys.Where(s => s.IsHole))
                            {
                                skippedUnsupportedLayerPolyNodes.Add(unsupportLayerHole);
                            }

                            foreach (var areaToSmallPolygon in unsupportedLayer._allPolys.Where(s => !s.IsHole))
                            {
                                if ((Clipper.Area(areaToSmallPolygon.Contour) / (CONTOURPOINT_TO_VECTORPOINT_FACTOR * CONTOURPOINT_TO_VECTORPOINT_FACTOR)) < 2)
                                {
                                    skippedUnsupportedLayerPolyNodes.Add(areaToSmallPolygon);
                                }
                            }

                            foreach (var removePolygon in skippedUnsupportedLayerPolyNodes)
                            {
                                unsupportedLayer._allPolys.Remove(removePolygon);
                            }

                            skippedUnsupportedLayerPolyNodes.Clear();

                            foreach (var unsupportedLayerPolyNode in unsupportedLayer._allPolys)
                            {
                                var contourPolyTree = new PolyTree();
                                contourPolyTree._allPolys.Add(unsupportedLayerPolyNode);
                                //TriangleHelper.SavePolyNodesContourToPng(contourPolyTree._allPolys, "b");
                                var supportConeIntersections = MagsAIEngine.CalcContourSupportStructure(contourPolyTree, null, null, selectedMaterialProfile, sliceHeight, this, true, false);
                                if (supportConeIntersections.Count > 0)
                                {
                                    var supportConeIntersectionPolyTree = new PolyTree();
                                    foreach (var supportConeIntersection in supportConeIntersections)
                                    {
                                        if (supportConeIntersection.LowestPoints.Count == 0)
                                        {
                                            skippedUnsupportedLayerPolyNodes.Add(unsupportedLayerPolyNode);
                                        }
                                        else
                                        {
                                            var k = 0;
                                            foreach (var supportConeIntersectionPoint in supportConeIntersection.LowestPoints)
                                            {
                                                var supportConeIntersectionPointAsIntPoint = supportConeIntersectionPoint.Point;
                                                supportConeIntersectionPointAsIntPoint.Z = (int)(sliceHeight * CONTOURPOINT_TO_VECTORPOINT_FACTOR);
                                                var addedSupportPoint = new MagsAISurfaceIntersectionData()
                                                {
                                                    TopPoint = supportConeIntersectionPointAsIntPoint, SliceHeight = sliceHeight
                                                };
                                                addedSupportPoint.OverhangDistanceFactor = selectedMaterialProfile.SupportOverhangDistance * overhangFactor;
                                                var outlineCirclePoints  = MagsAIEngine.ConvertSupportPointsToCircles(supportConeIntersectionPointAsIntPoint, selectedMaterialProfile.SupportOverhangDistance * overhangFactor);
                                                var outlineCirclePolygon = MagsAIEngine.MergeSupportCircles(new List <List <IntPoint> >()
                                                {
                                                    outlineCirclePoints
                                                });


                                                var intersectedPolygons    = ContourHelper.IntersectModelSliceLayer(ModelContours[sliceHeight], outlineCirclePolygon);
                                                var intersectionPointFound = false;

                                                foreach (var intersectedPolygon in intersectedPolygons._allPolys.Where(s => !s.IsHole))
                                                {
                                                    if (ContourHelper.PointExistsInNotHolePolygon(intersectedPolygon, addedSupportPoint.TopPoint))
                                                    {
                                                        supportConeIntersectionPolyTree._allPolys.Add(intersectedPolygon);
                                                        intersectionPointFound = true;
                                                    }
                                                }

                                                if (!intersectionPointFound)
                                                {
                                                    foreach (var intersectedPolygon in intersectedPolygons._allPolys.Where(s => !s.IsHole))
                                                    {
                                                        supportConeIntersectionPolyTree._allPolys.Add(intersectedPolygon);
                                                    }
                                                }

//                                                TriangleHelper.SavePolyNodesContourToPng(outlineCirclePolygon._allPolys, sliceHeight.ToString("0.00") + "-" + k.ToString());

                                                addedSupportPoint.UpdateLastSupportedHeight(stlModel);
                                                addedSupportPoint.UpdateTriangleReference(stlModel);
                                                if (!this.AddedSupportPoints.ContainsKey(addedSupportPoint.TopPoint))
                                                {
                                                    this.AddedSupportPoints.Add(addedSupportPoint.TopPoint, addedSupportPoint);
                                                }

                                                if (!this.AddedSupportPointsByLayer[sliceHeight].ContainsKey(addedSupportPoint.TopPoint))
                                                {
                                                    addedSupportPoint.UnsupportedContour = true;
                                                    this.AddedSupportPointsByLayer[sliceHeight].Add(addedSupportPoint.TopPoint, addedSupportPoint);
                                                }


                                                k++;
                                            }
                                        }

                                        if (supportConeIntersectionPolyTree._allPolys.Count > 0)
                                        {
                                            unsupportedLayer = DifferenceModelSliceLayer(unsupportedLayer, supportConeIntersectionPolyTree);
                                            // TriangleHelper.SavePolyNodesContourToPng(unsupportedLayer._allPolys, "s");

                                            break;
                                        }
                                    }
                                }
                            }

                            if (skippedUnsupportedLayerPolyNodes.Count > 0)
                            {
                                foreach (var skippedUnsuppertedLayerPolyNode in skippedUnsupportedLayerPolyNodes)
                                {
                                    unsupportedLayer._allPolys.Remove(skippedUnsuppertedLayerPolyNode);
                                }
                            }
                        }
                    }

                    previousSliceHeight = sliceHeight;
                }


                if (previousSliceHeight == float.MaxValue)
                {
                    previousSliceHeight = sliceHeight;
                }
            }

            return(this.AddedSupportPoints);
        }
        internal void UpdateLastSupportedHeight(STLModel3D stlModel, SortedDictionary <float, PolyTree> modelAngleLayers, SupportProfile selectedMaterialProfile)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            if (this.Id == null || this.Id == Guid.Empty)
            {
                this.Id = Guid.NewGuid();
            }
            //find latest supportcone supported height
            TriangleIntersection[] trianglesIntersected = null;

            var supportPointPosition = this.TopPoint.AsVector3();

            supportPointPosition.Z = this.SliceHeight;
            var currentSupportConeSupportedLayer = MagsAIEngine.ConvertSupportPointsToCircles(this.TopPoint, this.OverhangDistance * this.SupportOverhangDistanceFactor);

            currentSupportConeSupportedLayer.Add(this.TopPoint);

            if (this._trianglesWithinXYRange == null)
            {
                CalcTrianglesWithinRange(supportPointPosition, selectedMaterialProfile, stlModel);
            }

            var trianglesAboveSupportPoint = new STLModel3D()
            {
                Triangles = new TriangleInfoList()
            };

            trianglesAboveSupportPoint.Triangles[0] = this._trianglesWithinXYRange.Triangles[0].Where(s => s.Bottom > supportPointPosition.Z && s.Normal.Z > 0).ToList();

            //IntersectionProvider.IntersectTriangle(supportPointPosition, new Vector3Class(0, 0, -1), trianglesAboveSupportPoint, IntersectionProvider.typeDirection.OneWay, false, new Vector3Class(), out trianglesIntersected);
            //if (trianglesIntersected != null)
            //{
            //    var nearestLastSupportedHeight = new Vector3Class();
            //    var nearestLastSupportedHeightDistance = float.MaxValue;
            //    foreach (var triangleIntersection in trianglesIntersected)
            //    {
            //        if (triangleIntersection != null)
            //        {

            //            var distance = (triangleIntersection.IntersectionPoint - supportPointPosition).Length;
            //            if (distance < nearestLastSupportedHeightDistance)
            //            {
            //                nearestLastSupportedHeightDistance = distance;
            //                nearestLastSupportedHeight = triangleIntersection.IntersectionPoint;
            //            }
            //        }
            //    }

            //    if (nearestLastSupportedHeight != new Vector3Class())
            //    {
            //        this.LastSupportedCenterSliceHeight = nearestLastSupportedHeight.Z;
            //    }
            //}

            ////determine the last supported slice height using the half of material overhangdistance and removing the layers above
            //if (this.LastSupportedCenterAngle == 0f)
            //{
            //    this.UpdateTriangleReference(stlModel, selectedMaterialProfile);
            //}

            var maxLayerHeight = float.MinValue;

            foreach (var t in currentSupportConeSupportedLayer)
            {
                var tAsVector = t.AsVector3();
                tAsVector.Z = 1000;
                TriangleIntersection[] trianglesIntersected2 = null;
                IntersectionProvider.IntersectTriangle(tAsVector, new Vector3Class(0, 0, -1), trianglesAboveSupportPoint, IntersectionProvider.typeDirection.OneWay, false, new Vector3Class(), out trianglesIntersected2);

                var nearestTriangleIntersection = float.MaxValue;
                TriangleIntersection nearestIntersectionPoint = null;
                if (trianglesIntersected2 != null)
                {
                    foreach (var triangleIntersected in trianglesIntersected2)
                    {
                        if (triangleIntersected != null)
                        {
                            if (triangleIntersected.IntersectionPoint.Z >= this.SliceHeight)
                            {
                                var distance = (triangleIntersected.IntersectionPoint - supportPointPosition).Length;
                                if (distance < nearestTriangleIntersection)
                                {
                                    nearestTriangleIntersection = distance;
                                    nearestIntersectionPoint    = triangleIntersected;
                                }
                            }
                        }
                    }
                }

                if (nearestIntersectionPoint != null && nearestIntersectionPoint.IntersectionPoint.Z > maxLayerHeight)
                {
                    maxLayerHeight = nearestIntersectionPoint.IntersectionPoint.Z;
                }
            }

            if (maxLayerHeight == float.MinValue)
            {
                maxLayerHeight = 10000;
            }

            this.LastSupportedSliceHeight = maxLayerHeight;

            // Console.WriteLine("SurfaceIntersectionData: Measurement 2: " + maxLayerHeight);
            // Console.WriteLine("SurfaceIntersectionData: Measurement 2: " + stopwatch.ElapsedMilliseconds + "ms");
        }