internal MagsAISurfaceWithOverhangSupportCones(TriangleSurfaceInfo surface)
 {
     foreach (var surfaceTriangleIndex in surface.Keys)
     {
         this.Add(surfaceTriangleIndex, false);
     }
 }
Beispiel #2
0
        internal static TypeOfSurface GetSurfaceType(STLModel3D stlModel, TriangleSurfaceInfo currentSurface)
        {
            if (stlModel != null)
            {
                foreach (var surface in stlModel.Triangles.HorizontalSurfaces)
                {
                    if (surface == currentSurface)
                    {
                        return(TypeOfSurface.Horizontal);
                    }
                }

                foreach (var surface in stlModel.Triangles.FlatSurfaces)
                {
                    if (surface == currentSurface)
                    {
                        return(TypeOfSurface.Flat);
                    }
                }
            }

            return(TypeOfSurface.Unknown);
        }
Beispiel #3
0
        public static void AddGridSupportCone(float totalHeight, float topHeight, float topRadius, float middleRadius, float bottomHeight, float bottomRadius,
                                              int slicesCount, Vector3 object3dPosition, Vector3 position, Color color, STLModel3D stlModel, Vector3 moveTranslation,
                                              float rotationAngleX, float rotationAngleZ, bool groundSupport, TriangleSurfaceInfo surface, bool useSupportPenetration = false, float supportBottomWidthCorrection = 0f)
        {
            var supportCone = new SupportCone(totalHeight, topHeight, topRadius, middleRadius, bottomHeight, bottomRadius, slicesCount, new Vector3Class(object3dPosition), color, rotationAngleX, rotationAngleZ, stlModel,
                                              groundSupport: groundSupport,
                                              useSupportPenetration: useSupportPenetration,
                                              bottomWidthCorrection: supportBottomWidthCorrection
                                              );

            supportCone.CreationBy      = SupportCone.typeCreationBy.Manual;
            supportCone.Selected        = false;
            supportCone.MoveTranslation = new Vector3Class(moveTranslation);
            supportCone.UpdateBoundries();
            lock (surface.SupportStructure)
            {
                surface.SupportStructure.Add(supportCone);
            }
        }
        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);
        }