Пример #1
0
 private void AddPointToCurrentLayerWhenExistsInContour(PolyTree sliceContours, MagsAISurfaceIntersectionData intersectionData, float sliceHeight)
 {
     foreach (var sliceContour in sliceContours._allPolys.Where(s => !s.IsHole))
     {
         //if (ContourHelper.PointExistsInNotHolePolygon(sliceContour, intersectionData.TopPoint))
         // {
         if (!this.AddedSupportPointsByLayer[sliceHeight].ContainsKey(intersectionData.TopPoint))
         {
             this.AddedSupportPointsByLayer[sliceHeight].Add(intersectionData.TopPoint, intersectionData);
         }
         break;
         // }
     }
 }
Пример #2
0
        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);
        }