Exemplo n.º 1
0
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public Result calculatePointMap(List <Circle> circleList)
        {
            pointMap = new PointMap();

            this.PunchingToolList[0].X = circleList[0].Diameter;

            // Create the pointMap
            foreach (Circle circle in circleList)
            {
                pointMap.AddPoint(new PunchingPoint(circle.Center));
            }

            SortedDictionary <int, PunchingPoint> xDict0 = null;
            SortedDictionary <int, PunchingPoint> xDict1 = null;

            if (pointMap.Count > 0)
            {
                xDict0 = pointMap.getXDictionary(0);
            }

            if (pointMap.Count > 1)
            {
                xDict1 = pointMap.getXDictionary(1);
            }

            if (xDict0.Count > 2)
            {
                XSpacing = Math.Abs(xDict0.ElementAt(1).Value.Point.X - xDict0.ElementAt(0).Value.Point.X);
            }

            if (xDict0.Count > 1 && xDict1.Count > 1)
            {
                YSpacing = Math.Abs(xDict1.ElementAt(0).Value.Point.Y - xDict0.ElementAt(0).Value.Point.Y);
            }

            return(Result.Success);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            List <PointMap> pointMapList  = new List <PointMap>();
            PointMap        pointMapTool1 = new PointMap();
            PointMap        pointMapTool2 = new PointMap();
            PointMap        pointMapTool3 = new PointMap();

            pointMapList.Add(pointMapTool1);

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            double gap = XSpacing - punchingToolList[0].X;

            int punchQtyX = ((int)((spanX - punchingToolList[0].X - gap) / XSpacing)) + 1;

            double marginX = (spanX - (((punchQtyX - 1) * XSpacing) - gap)) / 2;

            // Debug purpose
            // marginX = 0;

            double YSpacing = XSpacing;

            int    punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX + gap;
            double   firstY = min.Y + marginY;

            // Set the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            doc.Layers.SetCurrentLayerIndex(currentLayer, false);
            // We don't use cluster tool so just perf it onto Tool Hit layer

            //if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer")){
            //    RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //}else{
            //    RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //}
            double runningX = firstX - punchingToolList[0].X / 2;

            double twoToolTest;
            double threeToolTest;
            Random random             = new Random();
            int    roundToolCounter   = 0;
            int    slotToolCounter    = 0;
            int    tool0Counter       = 0;
            int    tool1Counter       = 0;
            int    tool2Counter       = 0;
            bool   isToolHit          = false;
            int    toolMissingCounter = 0;

            // Generate the pattern
            for (int y = 0; y < punchQtyY; y++)
            {
                // For even rows

                if (random.NextDouble() < randomness || toolMissingCounter > 0)
                {
                    isToolHit          = true;
                    toolMissingCounter = 0;
                }
                else
                {
                    isToolHit = false;
                    toolMissingCounter++;
                }


                if (y % 2 == 0)
                {
                    // firstX = min.X + marginX + gap;
                    runningX    = min.X + gap;
                    twoToolTest = random.Next(42);

                    // Small slot
                    if (twoToolTest < 14)
                    {
                        point = new Point3d(runningX + punchingToolList[1].X / 2, firstY + y * YSpacing, 0);
                        pointMapTool2.AddPoint(new PunchingPoint(point));

                        runningX = runningX + punchingToolList[1].X + gap;

                        punchingToolList[1].drawTool(point);

                        if (isToolHit)
                        {
                            slotToolCounter = 1;
                            tool1Counter++;
                        }
                    }
                    else // Big slot
                    {
                        point = new Point3d(runningX + punchingToolList[2].X / 2, firstY + y * YSpacing, 0);
                        pointMapTool3.AddPoint(new PunchingPoint(point));

                        runningX = runningX + punchingToolList[2].X + gap;

                        slotToolCounter = 1;

                        if (isToolHit)
                        {
                            tool2Counter++;
                            punchingToolList[2].drawTool(point);
                        }
                    }
                }
                else
                {
                    //firstX = min.X + marginX;
                    //runningX = firstX - punchingToolList[0].X / 2;
                    runningX = min.X;
                    point    = new Point3d(runningX + punchingToolList[0].X / 2, firstY + y * YSpacing, 0);
                    pointMapTool1.AddPoint(new PunchingPoint(point));

                    runningX = runningX + punchingToolList[0].X + gap;

                    roundToolCounter = 1;

                    if (isToolHit)
                    {
                        tool0Counter++;
                        punchingToolList[0].drawTool(point);
                    }
                }

                //
                for (int x = 0; x < punchQtyX; x++)
                {
                    // Skip if the point already taken up by the tool
                    if (runningX > firstX + x * XSpacing)
                    {
                        continue;
                    }

                    if (random.NextDouble() < randomness || toolMissingCounter > 0)
                    {
                        isToolHit          = true;
                        toolMissingCounter = 0;
                    }
                    else
                    {
                        isToolHit = false;
                        toolMissingCounter++;
                    }

                    threeToolTest = random.Next(100);

                    if (threeToolTest < 16 && slotToolCounter < 2)
                    {
                        point = new Point3d(runningX + punchingToolList[1].X / 2, firstY + y * YSpacing, 0);
                        pointMapTool2.AddPoint(new PunchingPoint(point));

                        runningX = runningX + punchingToolList[1].X + gap;

                        roundToolCounter = 0;
                        slotToolCounter++;

                        if (isToolHit)
                        {
                            tool1Counter++;
                            punchingToolList[1].drawTool(point);
                        }
                    }
                    else if (threeToolTest < 47 && slotToolCounter < 2)
                    {
                        point = new Point3d(runningX + punchingToolList[2].X / 2, firstY + y * YSpacing, 0);
                        pointMapTool3.AddPoint(new PunchingPoint(point));

                        runningX = runningX + punchingToolList[2].X + gap;



                        roundToolCounter = 0;
                        slotToolCounter++;
                        if (isToolHit)
                        {
                            tool2Counter++;
                            punchingToolList[2].drawTool(point);
                        }
                    }
                    else if (threeToolTest >= 47 && roundToolCounter < 4)
                    {
                        point = new Point3d(runningX + punchingToolList[0].X / 2, firstY + y * YSpacing, 0);
                        pointMapTool1.AddPoint(new PunchingPoint(point));

                        runningX = runningX + punchingToolList[0].X + gap;

                        roundToolCounter++;
                        slotToolCounter = 0;

                        if (isToolHit)
                        {
                            tool0Counter++;
                            punchingToolList[0].drawTool(point);
                        }
                    }
                    else
                    {
                        x--;
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double tool0Area     = punchingToolList[0].getArea() * tool0Counter;
            double tool1Area     = punchingToolList[1].getArea() * tool1Counter;
            double tool2Area     = punchingToolList[2].getArea() * tool2Counter;
            double totalToolArea = tool0Area + tool1Area + tool2Area;

            RhinoApp.WriteLine("Tool 1 area: {0} mm^2", tool0Area.ToString("#.##"));
            RhinoApp.WriteLine("Tool 2 area: {0} mm^2", tool1Area.ToString("#.##"));
            RhinoApp.WriteLine("Tool 3 area: {0} mm^2", tool2Area.ToString("#.##"));

            double openArea = (totalToolArea * 100) / area.Area;

            RhinoApp.WriteLine("Open area: {0} %", openArea.ToString("#.##"));

            //int testResult;
            //int slotNumber = 1;

            //PunchingTools.Obround threeHoleSlot = new PunchingTools.Obround();
            //threeHoleSlot.X = 2*this.XSpacing + punchingToolList[0].X;
            //threeHoleSlot.Y = punchingToolList[0].X;

            //PunchingTools.Obround fiveHoleSlot = new PunchingTools.Obround();
            //fiveHoleSlot.X = 4 * this.XSpacing + punchingToolList[0].X;
            //fiveHoleSlot.Y = punchingToolList[0].X;

            //int chanceForHoles = 60;
            //int chanceForMidSlot = 86;
            //int chanceForLargeSlot = 100;

            //int holeCounter = 0;
            //int midSlotCounter = 0;
            //int largeSlotCounter = 0;

            //double toolArea = 0;

            // // Go through each point in the point Map list to determine whether it is a hole or a slot.
            //for (int i = 0; i < pointMapTool1.YCount; i++)
            //{
            //   SortedDictionary<int, PunchingPoint> xDict = pointMapTool1.getXDictionary(i);

            //   chanceForHoles = 60;
            //   chanceForMidSlot = 86;
            //   chanceForLargeSlot = 100;

            //   for (int j = 0; j < xDict.Count; j = j + slotNumber)
            //   {
            //      if (xDict.Count - j > 4)
            //      {
            //         // Generate whether the current hole
            //         testResult = random.Next(1, chanceForLargeSlot);
            //      }
            //      else if (xDict.Count - j > 2)
            //      {
            //         chanceForHoles = 30;
            //         chanceForMidSlot = 66;
            //         chanceForLargeSlot = 100;
            //         // Generate whether the current slot
            //         testResult = random.Next(1, chanceForMidSlot);
            //      }
            //      else
            //      {
            //         chanceForHoles = 30;
            //         chanceForMidSlot = 66;
            //         chanceForLargeSlot = 100;
            //         // Generate whether the current large slot
            //         testResult = random.Next(1, chanceForHoles);
            //      }

            //      if (testResult >= 1 && testResult <= chanceForHoles)
            //      {
            //         slotNumber = 1;

            //         holeCounter++;
            //         midSlotCounter = 0;
            //         largeSlotCounter = 0;

            //         if (holeCounter == 1)
            //         {
            //            chanceForHoles = 60;
            //            chanceForMidSlot = 86;
            //            chanceForLargeSlot = 100;
            //         }
            //         else if(holeCounter == 2)
            //         {
            //            chanceForHoles = 30;
            //            chanceForMidSlot = 66;
            //            chanceForLargeSlot = 100;
            //         }
            //         else if(holeCounter > 2)
            //         {
            //            chanceForHoles = 10;
            //            chanceForMidSlot = 53;
            //            chanceForLargeSlot = 100;
            //         }

            //         // Draw circle
            //         punchingToolList[0].drawTool(xDict.ElementAt(j).Value.Point);

            //         toolArea += punchingToolList[0].getArea();

            //      }
            //      else if (testResult > chanceForHoles && testResult <= chanceForMidSlot)
            //      {
            //         slotNumber = 3;

            //         holeCounter = 0;
            //         midSlotCounter++;
            //         largeSlotCounter = 0;

            //         if (midSlotCounter == 1)
            //         {
            //            chanceForHoles = 80;
            //            chanceForMidSlot = 90;
            //            chanceForLargeSlot = 100;
            //         }
            //         else if(midSlotCounter > 1)
            //         {
            //            chanceForHoles = 85;
            //            chanceForMidSlot = 93;
            //            chanceForLargeSlot = 100;
            //         }

            //         // Draw slot that span over 3 holes
            //         threeHoleSlot.drawTool(xDict.ElementAt(j + 1).Value.Point);

            //         toolArea += threeHoleSlot.getArea();
            //      }
            //      else if (testResult > chanceForMidSlot && testResult <= chanceForLargeSlot)
            //      {
            //         slotNumber = 5;

            //         holeCounter = 0;
            //         midSlotCounter = 0;
            //         largeSlotCounter++;

            //         if(largeSlotCounter >= 1)
            //         {
            //            chanceForHoles = 80;
            //            chanceForMidSlot = 100;
            //            chanceForLargeSlot = 100;
            //         }

            //         // Draw slot that span over 5 holes
            //         fiveHoleSlot.drawTool(xDict.ElementAt(j + 2).Value.Point);

            //         toolArea += fiveHoleSlot.getArea();
            //      }
            //   }
            //}

            // Display the open area calculation
            //AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            //RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            //  RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            // openArea = toolArea * 100 / area.Area;

            // RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            //for (int y = 0; y < punchQtyY; y++)
            //{
            //   for (int x = 0; x < punchQtyX; x++)
            //   {
            //      point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

            //      if (punchingToolList[0].isInside(boundaryCurve, point) == true)
            //      {
            //         pointMap.AddPoint(new PunchingPoint(point));
            //         punchingToolList[0].drawTool(point);
            //      }

            //      if(random.NextDouble() < randomness)
            //      {
            //         if (punchingToolList[1].isInside(boundaryCurve, point) == true)
            //         {
            //            doc.Layers.SetCurrentLayerIndex(brailleLayerIndex, true);
            //            punchingToolList[1].drawTool(point);
            //            doc.Layers.SetCurrentLayerIndex(perforationlayerIndex, true);
            //         }
            //      }
            //   }
            //}

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            PointMap pointMap = new PointMap();

            int[] toolHitArray = Enumerable.Repeat(0, 3).ToArray();

            double marginX;

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;

            double secondRowOffset = pitch * Math.Cos(Math.PI * 60 / 180);

            if (spanX >= ((punchQtyX - 1) * XSpacing + secondRowOffset + punchingToolList[0].X))
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing) - secondRowOffset) / 2;
            }
            else
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            }

            int punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;

            double marginY = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d point;

            RhinoDoc doc = RhinoDoc.ActiveDoc;

            double firstX = min.X + marginX;
            double firstY = min.Y + marginY;

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Set the layer to perforation
            //if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //{
            //    RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //}
            //else
            //{
            //    RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //}
            // Random Engine
            RandomTiler randomTileEngine = new RandomTiler();

            int totalQty = punchQtyX * punchQtyY;
            // except the last tool percentage will be total - all tool hit
            List <double> toolHitPercentage = new List <double>(3);

            toolHitPercentage.Add(0.368);
            toolHitPercentage.Add(0.177);

            // Create randomness for tool count
            random = new Random();

            int toolHitCount = 0;

            // Create tile counts
            List <int> tileCounts = new List <int>();

            foreach (double pc in toolHitPercentage)
            {
                int toolHitQty = (int)(totalQty * pc);
                tileCounts.Add(toolHitQty);
                toolHitCount = toolHitCount + toolHitQty;
            }

            tileCounts.Add(totalQty - toolHitCount);

            randomTileEngine.Weight = new int[5, 5]
            {
                { 1, 1, 2, 1, 1 },
                { 1, 2, 3, 2, 1 },
                { 2, 3, 0, 3, 2 },
                { 1, 2, 3, 2, 1 },
                { 1, 1, 2, 1, 1 }
            };



            int[,] tileMap = randomTileEngine.GetTileMap(tileCounts, punchQtyX, punchQtyY);
            int[] toolHitCounter = new int[3];

            for (int y = 0; y < punchQtyY; y++)
            {
                if (y % 2 == 0) // even rows
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                        if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                        {
                            pointMap.AddPoint(new PunchingPoint(point));
                            punchingToolList[tileMap[x, y] - 1].drawTool(point);
                            toolHitArray[tileMap[x, y] - 1]++;
                        }
                    }
                }
                else // odd rows
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        point = new Point3d(firstX + secondRowOffset + (x * XSpacing), firstY + y * YSpacing, 0);

                        if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                        {
                            pointMap.AddPoint(new PunchingPoint(point));
                            punchingToolList[tileMap[x, y] - 1].drawTool(point);
                            toolHitArray[tileMap[x, y] - 1]++;
                        }
                    }
                }
            }

            //for (int y = 0; y < punchQtyY; y++)
            //{
            //   for (int x = 0; x < punchQtyX; x++)
            //   {
            //      point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

            //      if (punchingToolList[0].isInside(boundaryCurve, point) == true)
            //      {
            //         pointMap.AddPoint(new PunchingPoint(point));
            //         punchingToolList[tileMap[x, y]-1].drawTool(point);
            //         toolHitArray[tileMap[x, y]-1]++;
            //      }
            //   }
            //}

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double toolArea      = 0;
            double totalToolArea = 0;

            for (int i = 0; i < 3; i++)
            {
                toolArea      = punchingToolList[i].getArea() * toolHitArray[i];
                totalToolArea = totalToolArea + toolArea;
                RhinoApp.WriteLine("Tool area{0}: {1} mm^2", i, toolArea.ToString("#.##"));
            }

            openArea = totalToolArea * 100 / area.Area;
            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));


            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMap, punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            PointMap pointMap = new PointMap();
            Random   random   = new Random();

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int    punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;
            double marginX   = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            double YSpacing  = XSpacing;

            int    punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create Perforation Layer
            // if (punchingToolList[0].ClusterTool.Enable == true)
            {
                doc.Layers.SetCurrentLayerIndex(currentLayer, true);
                //RhinoUtilities.SetActiveLayer(Properties.Settings.Default.PerforationLayerName, System.Drawing.Color.Green);
            }
            //else
            //{
            //    if (MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //    {
            //        RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //    }
            //    else
            //    {
            //        RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //    }
            //}

            for (int y = 0; y < punchQtyY; y++)
            {
                for (int x = 0; x < punchQtyX; x++)
                {
                    point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                    if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                    {
                        if (random.NextDouble() < randomness)
                        {
                            pointMap.AddPoint(new PunchingPoint(point));
                            punchingToolList[0].drawTool(point);
                        }
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double toolArea = punchingToolList[0].getArea() * pointMap.Count;

            RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            openArea = toolArea * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));


            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMap, punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            // Set the active layer back to where it was
            doc.Layers.SetCurrentLayerIndex(currentLayer, true);

            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            List <PointMap> pointMapList  = new List <PointMap>();
            Random          random        = new Random();
            PointMap        pointMapTool1 = new PointMap();

            pointMapList.Add(pointMapTool1);

            double marginX;

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;

            double secondRowOffset = pitch * Math.Cos(Math.PI * 60 / 180);

            if (spanX >= ((punchQtyX - 1) * XSpacing + secondRowOffset + punchingToolList[0].X))
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing) - secondRowOffset) / 2;
            }
            else
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            }

            int punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;

            double marginY = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d point;

            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create Perforation Layer
            //  if (punchingToolList[0].ClusterTool.Enable == true)
            {
                // RhinoUtilities.SetActiveLayer(Properties.Settings.Default.PerforationLayerName, System.Drawing.Color.Green);
                doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            }
            //else
            //{
            //    if (MetrixUtilities.IsLayerFound("PerfTemporaryLayer"))
            //    {
            //        RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //    }
            //    else
            //    {
            //        RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //    }
            //}
            bool drawSimpleToolHit = true;

            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawSimpleToolHit = false;
                    break;
                }
            }
            if (drawSimpleToolHit)
            {
                int currentlayer = doc.Layers.Find("Tool Hit", true);
                if (currentlayer < 0)
                {
                    currentlayer = doc.Layers.Add("Tool Hit", System.Drawing.Color.Black);
                }
                doc.Layers.SetCurrentLayerIndex(currentlayer, true);
                for (int y = 0; y < punchQtyY; y++)
                {
                    if (y % 2 == 0) // even rows
                    {
                        for (int x = 0; x < punchQtyX; x++)
                        {
                            point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                            {
                                if (random.NextDouble() < randomness)
                                {
                                    pointMapTool1.AddPoint(new PunchingPoint(point));

                                    punchingToolList[0].drawTool(point);
                                }
                            }
                        }
                    }
                    else // odd rows
                    {
                        for (int x = 0; x < punchQtyX; x++)
                        {
                            point = new Point3d(firstX + secondRowOffset + (x * XSpacing), firstY + y * YSpacing, 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                            {
                                if (random.NextDouble() < randomness)
                                {
                                    pointMapTool1.AddPoint(new PunchingPoint(point));
                                    punchingToolList[0].drawTool(point);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                for (int y = 0; y < punchQtyY; y++)
                {
                    if (y % 2 == 0) // even rows
                    {
                        for (int x = 0; x < punchQtyX; x++)
                        {
                            point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                            {
                                if (random.NextDouble() < randomness)
                                {
                                    pointMapTool1.AddPoint(new PunchingPoint(point));
                                    if (PunchingToolList[0].Perforation)
                                    {
                                        punchingToolList[0].drawTool(point);
                                    }
                                }
                            }
                        }
                    }
                    else // odd rows
                    {
                        for (int x = 0; x < punchQtyX; x++)
                        {
                            point = new Point3d(firstX + secondRowOffset + (x * XSpacing), firstY + y * YSpacing, 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                            {
                                if (random.NextDouble() < randomness)
                                {
                                    pointMapTool1.AddPoint(new PunchingPoint(point));
                                    if (PunchingToolList[0].Perforation)
                                    {
                                        punchingToolList[0].drawTool(point);
                                    }
                                }
                            }
                        }
                    }
                }
            }



            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double toolArea = punchingToolList[0].getArea() * pointMapTool1.Count;

            RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            openArea = toolArea * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMapList[i], punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            List <PointMap> pointMapList  = new List <PointMap>();
            PointMap        pointMapTool1 = new PointMap();

            pointMapList.Add(pointMapTool1);

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int    punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;
            double marginX   = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            double YSpacing  = XSpacing;

            int    punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Set the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            doc.Layers.SetCurrentLayerIndex(currentLayer, false);
            // We don't use cluster tool so just perf it onto Tool Hit layer
            //if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //{
            //    RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //}
            //else
            //{
            //    RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //}
            // Generate the point map first
            for (int y = 0; y < punchQtyY; y++)
            {
                for (int x = 0; x < punchQtyX; x++)
                {
                    point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                    if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                    {
                        pointMapTool1.AddPoint(new PunchingPoint(point));
                    }
                }
            }

            Random random = new Random();
            int    testResult;
            int    slotNumber = 1;

            PunchingTools.Obround threeHoleSlot = new PunchingTools.Obround();
            threeHoleSlot.X = 2 * this.XSpacing + punchingToolList[0].X;
            threeHoleSlot.Y = punchingToolList[0].X;

            PunchingTools.Obround fiveHoleSlot = new PunchingTools.Obround();
            fiveHoleSlot.X = 4 * this.XSpacing + punchingToolList[0].X;
            fiveHoleSlot.Y = punchingToolList[0].X;

            int chanceForHoles     = 60;
            int chanceForMidSlot   = 86;
            int chanceForLargeSlot = 100;

            int holeCounter      = 0;
            int midSlotCounter   = 0;
            int largeSlotCounter = 0;

            double toolArea = 0;

            // Go through each point in the point Map list to determine whether it is a hole or a slot.
            for (int i = 0; i < pointMapTool1.YCount; i++)
            {
                SortedDictionary <int, PunchingPoint> xDict = pointMapTool1.getXDictionary(i);

                chanceForHoles     = 60;
                chanceForMidSlot   = 86;
                chanceForLargeSlot = 100;

                for (int j = 0; j < xDict.Count; j = j + slotNumber)
                {
                    if (xDict.Count - j > 4)
                    {
                        // Generate whether the current hole
                        testResult = random.Next(1, chanceForLargeSlot);
                    }
                    else if (xDict.Count - j > 2)
                    {
                        chanceForHoles     = 30;
                        chanceForMidSlot   = 66;
                        chanceForLargeSlot = 100;
                        // Generate whether the current slot
                        testResult = random.Next(1, chanceForMidSlot);
                    }
                    else
                    {
                        chanceForHoles     = 30;
                        chanceForMidSlot   = 66;
                        chanceForLargeSlot = 100;
                        // Generate whether the current large slot
                        testResult = random.Next(1, chanceForHoles);
                    }

                    if (testResult >= 1 && testResult <= chanceForHoles)
                    {
                        slotNumber = 1;

                        holeCounter++;
                        midSlotCounter   = 0;
                        largeSlotCounter = 0;

                        if (holeCounter == 1)
                        {
                            chanceForHoles     = 60;
                            chanceForMidSlot   = 86;
                            chanceForLargeSlot = 100;
                        }
                        else if (holeCounter == 2)
                        {
                            chanceForHoles     = 30;
                            chanceForMidSlot   = 66;
                            chanceForLargeSlot = 100;
                        }
                        else if (holeCounter > 2)
                        {
                            chanceForHoles     = 10;
                            chanceForMidSlot   = 53;
                            chanceForLargeSlot = 100;
                        }

                        // Draw circle
                        punchingToolList[0].drawTool(xDict.ElementAt(j).Value.Point);

                        toolArea += punchingToolList[0].getArea();
                    }
                    else if (testResult > chanceForHoles && testResult <= chanceForMidSlot)
                    {
                        slotNumber = 3;

                        holeCounter = 0;
                        midSlotCounter++;
                        largeSlotCounter = 0;

                        if (midSlotCounter == 1)
                        {
                            chanceForHoles     = 80;
                            chanceForMidSlot   = 90;
                            chanceForLargeSlot = 100;
                        }
                        else if (midSlotCounter > 1)
                        {
                            chanceForHoles     = 85;
                            chanceForMidSlot   = 93;
                            chanceForLargeSlot = 100;
                        }

                        // Draw slot that span over 3 holes
                        threeHoleSlot.drawTool(xDict.ElementAt(j + 1).Value.Point);

                        toolArea += threeHoleSlot.getArea();
                    }
                    else if (testResult > chanceForMidSlot && testResult <= chanceForLargeSlot)
                    {
                        slotNumber = 5;

                        holeCounter    = 0;
                        midSlotCounter = 0;
                        largeSlotCounter++;

                        if (largeSlotCounter >= 1)
                        {
                            chanceForHoles     = 80;
                            chanceForMidSlot   = 100;
                            chanceForLargeSlot = 100;
                        }

                        // Draw slot that span over 5 holes
                        fiveHoleSlot.drawTool(xDict.ElementAt(j + 2).Value.Point);

                        toolArea += fiveHoleSlot.getArea();
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            openArea = toolArea * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            //for (int y = 0; y < punchQtyY; y++)
            //{
            //   for (int x = 0; x < punchQtyX; x++)
            //   {
            //      point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

            //      if (punchingToolList[0].isInside(boundaryCurve, point) == true)
            //      {
            //         pointMap.AddPoint(new PunchingPoint(point));
            //         punchingToolList[0].drawTool(point);
            //      }

            //      if(random.NextDouble() < randomness)
            //      {
            //         if (punchingToolList[1].isInside(boundaryCurve, point) == true)
            //         {
            //            doc.Layers.SetCurrentLayerIndex(brailleLayerIndex, true);
            //            punchingToolList[1].drawTool(point);
            //            doc.Layers.SetCurrentLayerIndex(perforationlayerIndex, true);
            //         }
            //      }
            //   }
            //}

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            List <PointMap> pointMapList = new List <PointMap>();

            Random random = new Random();

            PointMap pointMapTool1 = new PointMap();
            PointMap pointMapTool2 = new PointMap();

            pointMapList.Add(pointMapTool1);

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            // Span are the total length of the area
            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            // Number of holes that can be punch in X.
            int punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;

            double secondRowOffset = XSpacing / 2;

            // Calculate the margin - is the distance from the left border
            double marginX;

            if (spanX >= ((punchQtyX - 1) * XSpacing + secondRowOffset + (punchingToolList[0].X / 2) + (punchingToolList[2].X / 2)))
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing) - secondRowOffset - ((punchingToolList[0].X / 2) + (punchingToolList[2].X / 2))) / 2 + (punchingToolList[0].X / 2);
            }
            else
            {
                marginX = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            }

            int    punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;
            double marginY   = 0;

            if (punchQtyY % 2 == 0) // Even
            {
                // Make sure the Tool can fit if the row is even row
                punchQtyY = ((int)((spanY - (punchingToolList[0].Y / 2) - (punchingToolList[2].Y / 2)) / YSpacing)) + 1;
            }

            if (punchQtyY % 2 == 0) // Even Row
            {
                marginY = (spanY - ((punchQtyY - 1) * YSpacing) - (punchingToolList[0].Y / 2) - (punchingToolList[2].Y / 2)) / 2 + (punchingToolList[0].Y / 2);
            }
            else
            {
                marginY = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;
            }

            Point3d point;

            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create Perforation Layer
            //    if (punchingToolList[0].ClusterTool.Enable == true)
            {
                doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            }
            //else
            //{
            //    if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //    {
            //        RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //    }
            //    else
            //    {
            //        RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //    }
            //}

            for (int y = 0; y < punchQtyY; y++)
            {
                if (y % 2 == 0) // even rows
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                        if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                        {
                            if (random.NextDouble() < randomness)
                            {
                                pointMapTool1.AddPoint(new PunchingPoint(point));
                                punchingToolList[0].drawTool(point);
                            }
                        }
                    }
                }
                else // odd rows
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        point = new Point3d(firstX + (x * XSpacing) + secondRowOffset, firstY + y * YSpacing, 0);

                        if (punchingToolList[2].isInside(boundaryCurve, point) == true)
                        {
                            if (random.NextDouble() < randomness)
                            {
                                pointMapTool2.AddPoint(new PunchingPoint(point));
                                punchingToolList[1].drawTool(point);
                                punchingToolList[2].drawTool(point);
                            }
                        }
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double tool1Area = punchingToolList[0].getArea() * pointMapTool1.Count;

            RhinoApp.WriteLine("Tool 1 area: {0} mm^2", tool1Area.ToString("#.##"));

            double tool2Area = punchingToolList[1].getArea() * pointMapTool2.Count;

            RhinoApp.WriteLine("Tool 2 area: {0} mm^2", tool2Area.ToString("#.##"));

            openArea = (tool1Area + tool2Area) * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            doc.Views.Redraw();

            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMapList[i], punchingToolList[i]);
                }
            }

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);

            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <param name="boundaryCurve">The boundary curve.</param>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            List <PointMap> pointMapList  = new List <PointMap>();
            Random          random        = new Random();
            PointMap        pointMapTool1 = new PointMap();
            int             tool0count    = 0;
            int             tool1count    = 0;
            int             tool2count    = 0;
            double          marginX;

            pointMapList.Add(pointMapTool1);

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            double gap = xSpacing - punchingToolList[2].X;

            // Maximum punching qty
            int punchQtyX = ((int)((spanX - punchingToolList[2].X) / XSpacing)) + 1;

            // PunchQty need to add 1 if the last bit can fit the small rectangle
            if (spanX - (punchingToolList[2].X * punchQtyX) > (punchingToolList[0].X + gap))
            {
                punchQtyX = punchQtyX + 1;
            }

            // Find the location of the first punch
            if (spanX >= ((punchQtyX - 1) * XSpacing + punchingToolList[2].X))
            {
                marginX = (spanX - ((punchQtyX - 2) * XSpacing) - (punchingToolList[2].X) - gap) / 2;
            }
            else if (spanX >= ((punchQtyX - 1) * XSpacing + punchingToolList[1].X))
            {
                marginX = (spanX - ((punchQtyX - 2) * XSpacing) - (punchingToolList[1].X) - gap) / 2;
            }
            else
            {
                marginX = (spanX - ((punchQtyX - 2) * XSpacing) - (punchingToolList[0].X) - gap) / 2;
            }

            int punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;

            double marginY = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d point;

            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create Perforation Layer
            //if (punchingToolList[0].ClusterTool.Enable == true)
            {
                doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            }
            //else
            //{
            //    if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //    {
            //        RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //    }
            //    else
            //    {
            //        RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //    }
            //}

            // Random Engine

            RandomTiler randomTileEngine = new RandomTiler();

            int totalQty   = (punchQtyX + 1) * punchQtyY;
            int toolHitQty = (int)(totalQty * randomness);
            int blankQty   = totalQty - toolHitQty;

            List <int> tileCounts = new List <int>();

            tileCounts.Add(toolHitQty);
            tileCounts.Add(blankQty);
            int[,] tileMap = randomTileEngine.GetTileMap(tileCounts, punchQtyX + 1, punchQtyY);

            Point3d pointMedL;
            Point3d pointMedR;
            Point3d pointShortL;
            Point3d pointShortR;
            Point3d pointLeft, pointRight, pointTop, pointBottom;
            double  toolOffset = XSpacing / 6;
            double  rowOffset  = XSpacing / 3;


            for (int y = 0; y < punchQtyY; y++)
            {
                if (y % 3 == 0) // Long tool row
                {
                    // first X
                    firstX = min.X + marginX;
                }
                else if (y % 3 == 1) // Med tool row
                {
                    firstX = min.X + marginX - rowOffset;
                }
                else // short tool rows
                {
                    firstX = min.X + marginX - (2 * rowOffset);
                }

                bool isBorderPunch = false;

                for (int x = 0; x < punchQtyX + 1; x++)
                {
                    point       = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);
                    pointMedL   = new Point3d(firstX + x * XSpacing - toolOffset, firstY + y * YSpacing, 0);
                    pointMedR   = new Point3d(firstX + x * XSpacing + toolOffset, firstY + y * YSpacing, 0);
                    pointShortL = new Point3d(firstX + x * XSpacing - 2 * toolOffset, firstY + y * YSpacing, 0);
                    pointShortR = new Point3d(firstX + x * XSpacing + 2 * toolOffset, firstY + y * YSpacing, 0);

                    pointLeft   = new Point3d(firstX + (x - 1) * XSpacing, firstY + y * YSpacing, 0);
                    pointRight  = new Point3d(firstX + (x + 1) * XSpacing, firstY + y * YSpacing, 0);
                    pointTop    = new Point3d(firstX + x * XSpacing, firstY + (y + 1) * YSpacing, 0);
                    pointBottom = new Point3d(firstX + (x + 1) * XSpacing, firstY + (y - 1) * YSpacing, 0);

                    // Test if the current punch is close to border
                    isBorderPunch = false;

                    if (punchingToolList[0].isInside(boundaryCurve, pointLeft) == false)
                    {
                        isBorderPunch = true;
                    }

                    if (punchingToolList[0].isInside(boundaryCurve, pointRight) == false)
                    {
                        isBorderPunch = true;
                    }

                    if (punchingToolList[0].isInside(boundaryCurve, pointTop) == false)
                    {
                        isBorderPunch = true;
                    }

                    if (punchingToolList[0].isInside(boundaryCurve, pointBottom) == false)
                    {
                        isBorderPunch = true;
                    }

                    if (isBorderPunch == true || tileMap[x, y] == 1)
                    {
                        if (punchingToolList[2].isInside(boundaryCurve, point) == true)
                        {
                            pointMapTool1.AddPoint(new PunchingPoint(point));
                            punchingToolList[2].drawTool(point);
                            tool2count++;
                        }
                        else if (punchingToolList[1].isInside(boundaryCurve, pointMedL) == true)
                        {
                            pointMapTool1.AddPoint(new PunchingPoint(pointMedL));
                            punchingToolList[1].drawTool(pointMedL);
                            tool1count++;
                        }
                        else if (punchingToolList[1].isInside(boundaryCurve, pointMedR) == true)
                        {
                            pointMapTool1.AddPoint(new PunchingPoint(pointMedR));
                            punchingToolList[1].drawTool(pointMedR);
                            tool1count++;
                        }
                        else if (punchingToolList[0].isInside(boundaryCurve, pointShortL) == true)
                        {
                            pointMapTool1.AddPoint(new PunchingPoint(pointShortL));
                            punchingToolList[0].drawTool(pointShortL);
                            tool0count++;
                        }
                        else if (punchingToolList[0].isInside(boundaryCurve, pointShortR) == true)
                        {
                            pointMapTool1.AddPoint(new PunchingPoint(pointShortR));
                            punchingToolList[0].drawTool(pointShortR);
                            tool0count++;
                        }
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double tool0Area = punchingToolList[0].getArea() * tool0count;
            double tool1Area = punchingToolList[1].getArea() * tool1count;
            double tool2Area = punchingToolList[2].getArea() * tool2count;

            RhinoApp.WriteLine("Tool 1 area: {0} mm^2", tool0Area.ToString("#.##"));



            RhinoApp.WriteLine("Tool 2 area: {0} mm^2", tool1Area.ToString("#.##"));


            RhinoApp.WriteLine("Tool 3 area: {0} mm^2", tool2Area.ToString("#.##"));

            openArea = (tool0Area + tool1Area + tool2Area) * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMapList[i], punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            PointMap pointMap = new PointMap();

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;


            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int    punchQtyX = ((int)((spanX - punchingToolList[0].X) / XSpacing)) + 1;
            double marginX   = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;

            int    punchQtyY = ((int)((spanY - punchingToolList[0].Y) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc = RhinoDoc.ActiveDoc;

            double  firstX = min.X + marginX;
            double  firstY = min.Y + marginY;
            Point3d origin = new Point3d(firstX, firstY, 0);

            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create the grid
            Point3d?[,] grid = new Point3d?[punchQtyX, punchQtyY];

            // Active points
            List <Point3d> activePointsList = new List <Point3d>();

            // Point list
            List <Point3d> pointsList = new List <Point3d>();

            //doc.Layers.SetCurrentLayerIndex(layerIndex, true);

            // Add first point
            random = new Random();

            for (int y = 0; y < punchQtyY; y++)
            {
                for (int x = 0; x < punchQtyX; x++)
                {
                    point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                    if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                    {
                        if (!grid[x, y].HasValue)
                        {
                            pointMap.AddPoint(new PunchingPoint(point));
                            punchingToolList[0].drawTool(point);
                        }
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double toolArea = punchingToolList[0].getArea() * pointMap.Count;

            RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            openArea = toolArea * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));


            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMap, punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            PointMap pointMap = new PointMap();

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int    punchQtyX = ((int)((spanX - punchingToolList[1].X) / XSpacing)) + 1;
            double marginX   = (spanX - ((punchQtyX - 1) * XSpacing)) / 2;
            double YSpacing  = XSpacing;

            int    punchQtyY = ((int)((spanY - punchingToolList[1].Y) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc    = RhinoDoc.ActiveDoc;
            double   firstX = min.X + marginX;
            double   firstY = min.Y + marginY;

            // Record current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            int tool0Count = 0;

            for (int y = 0; y < punchQtyY; y++)
            {
                for (int x = 0; x < punchQtyX; x++)
                {
                    point = new Point3d(firstX + x * XSpacing, firstY + y * YSpacing, 0);

                    if (punchingToolList[0].isInside(boundaryCurve, point) == true)
                    {
                        pointMap.AddPoint(new PunchingPoint(point));
                        // punchingToolList[0].drawTool(point);
                        tool0Count++;
                    }
                    else
                    {
                        punchingToolList[0].drawTool(point);
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double tool0Area = punchingToolList[0].getArea() * tool0Count;

            RhinoApp.WriteLine("Tool 1 area: {0} mm^2", tool0Area.ToString("#.##"));

            //double tool1Area = punchingToolList[1].getArea() * tool1Count;

            //RhinoApp.WriteLine("Tool 2 area: {0} mm^2", tool1Area.ToString("#.##"));

            //double openArea = (tool0Area + tool1Area) * 100 / area.Area;

            // RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(0);
        }
        /// <summary>
        /// Draws the perforation.
        /// </summary>
        /// <returns></returns>
        public override double drawPerforation(Curve boundaryCurve)
        {
            PointMap pointMap = new PointMap();

            // Find the boundary
            BoundingBox boundingBox = boundaryCurve.GetBoundingBox(Plane.WorldXY);
            Point3d     min         = boundingBox.Min;
            Point3d     max         = boundingBox.Max;

            double d         = Math.Tan(Math.PI / 6) * (XSpacing - punchingToolList[0].X) / 2;
            double rowHeight = (Math.Sqrt(3) * punchingToolList[0].X / 2) + d;
            double h         = (Math.Sqrt(3) * punchingToolList[0].X / 2);
            double g         = d / Math.Sin(Math.PI / 6);

            YSpacing = rowHeight + g;

            double spanX = max.X - min.X;
            double spanY = max.Y - min.Y;

            int    punchQtyX = ((int)((spanX - punchingToolList[0].X) / (XSpacing / 2))) + 1;
            double marginX   = (spanX - ((punchQtyX - 1) * (XSpacing / 2))) / 2;

            int    punchQtyY = ((int)((spanY - rowHeight) / YSpacing)) + 1;
            double marginY   = (spanY - ((punchQtyY - 1) * YSpacing)) / 2;

            Point3d  point;
            RhinoDoc doc = RhinoDoc.ActiveDoc;

            double  firstX = min.X + marginX;
            double  firstY = min.Y + marginY;
            Point3d origin = new Point3d(firstX, firstY, 0);

            // Record the current layer
            int currentLayer = doc.Layers.CurrentLayerIndex;

            // Create Perforation Layer
            //   if (punchingToolList[0].ClusterTool.Enable == true)
            {
                doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            }
            //else
            //{
            //    if (!MetrixUtilities.IsLayerFound("TemporaryPerfLayer"))
            //    {
            //        RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
            //    }
            //    else
            //    {
            //        RhinoUtilities.SetActiveLayer("TemporaryToolHit", System.Drawing.Color.Black);
            //    }
            //}

            for (int y = 0; y < punchQtyY; y++)
            {
                if (y % 2 == 0) // even rows
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        if (x % 2 == 0) // even location
                        {
                            point = new Point3d(firstX + x * (XSpacing / 2), firstY + y * YSpacing - (rowHeight / 2) + (h / 3), 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point, 0) == true)
                            {
                                pointMap.AddPoint(new PunchingPoint(point));
                                punchingToolList[0].drawTool(point, 0);
                            }
                        }
                        else
                        {
                            point = new Point3d(firstX + x * (XSpacing / 2), firstY + y * YSpacing + (rowHeight / 2) - (h / 3), 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point, Math.PI) == true)
                            {
                                pointMap.AddPoint(new PunchingPoint(point));
                                punchingToolList[0].drawTool(point, Math.PI);
                            }
                        }
                    }
                }
                else
                {
                    for (int x = 0; x < punchQtyX; x++)
                    {
                        if (x % 2 == 0) // even location
                        {
                            point = new Point3d(firstX + x * (XSpacing / 2), firstY + y * YSpacing + (rowHeight / 2) - (h / 3), 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point, Math.PI) == true)
                            {
                                pointMap.AddPoint(new PunchingPoint(point));
                                punchingToolList[0].drawTool(point, Math.PI);
                            }
                        }
                        else
                        {
                            point = new Point3d(firstX + x * (XSpacing / 2), firstY + y * YSpacing - (rowHeight / 2) + (h / 3), 0);

                            if (punchingToolList[0].isInside(boundaryCurve, point, 0) == true)
                            {
                                pointMap.AddPoint(new PunchingPoint(point));
                                punchingToolList[0].drawTool(point, 0);
                            }
                        }
                    }
                }
            }

            // Display the open area calculation
            AreaMassProperties area = AreaMassProperties.Compute(boundaryCurve);

            RhinoApp.WriteLine("Total area: {0} mm^2", area.Area.ToString("#.##"));

            double toolArea = punchingToolList[0].getArea() * pointMap.Count;

            RhinoApp.WriteLine("Tool area: {0} mm^2", toolArea.ToString("#.##"));

            openArea = toolArea * 100 / area.Area;

            RhinoApp.WriteLine("Open area: {0}%", openArea.ToString("#."));

            // Draw the cluster for each tool
            for (int i = 0; i < punchingToolList.Count; i++)
            {
                // Only draw cluster tool if it is enable
                if (punchingToolList[i].ClusterTool.Enable == true)
                {
                    // Draw the cluster tool
                    drawCluster(pointMap, punchingToolList[i]);
                }
            }

            doc.Views.Redraw();

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);
            return(openArea);
        }