Ejemplo n.º 1
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // Check the selected curve
            GetObject go = new GetObject();

            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;
            go.EnableSelPrevious(true);
            go.EnablePreSelect(true, false);
            go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve;

            GetResult result = go.Get();

            if (go.CommandResult() != Rhino.Commands.Result.Success)
            {
                return(go.CommandResult());
            }

            if (go.ObjectCount != 1)
            {
                RhinoApp.WriteLine("Error: {0} curve is selected.", go.ObjectCount);
                return(Rhino.Commands.Result.Failure);
            }

            RhinoApp.WriteLine("{0} curve is selected.", go.ObjectCount);

            Curve curve = go.Object(0).Curve();

            // If curve is null
            if (curve == null)
            {
                return(Rhino.Commands.Result.Failure);
            }

            // If curve is Closed Curve Orientation
            if (curve.IsClosed == false)
            {
                RhinoApp.WriteLine("The curve is open");
                return(Rhino.Commands.Result.Failure);
            }
            RhinoUtilities.SetActiveLayer(Properties.Settings.Default.PerforationLayerName, System.Drawing.Color.Green);
            PerforationForm perforationForm = new PerforationForm(curve);

            perforationForm.ShowDialog(RhinoApp.MainWindow());
            RhinoDoc.ActiveDoc.Views.Redraw();
            return(Result.Success);
        }
        /// <summary>
        /// Draws the panel.
        /// </summary>
        /// <param name="xLowerBound">The x lower bound.</param>
        /// <param name="xUpperBound">The x upper bound.</param>
        /// <param name="yLowerBound">The y lower bound.</param>
        /// <param name="yUpperBound">The y upper bound.</param>
        /// <param name="panel">The panel.</param>
        /// <param name="para">The para.</param>
        public static void drawPanel(double xLowerBound, double xUpperBound, double yLowerBound, double yUpperBound, PerforationPanel panel, bool fixingHolesManipulated, bool enablePerf)
        {
            RhinoDoc    doc        = RhinoDoc.ActiveDoc;
            List <Guid> guidList   = new List <Guid>();
            string      layerName  = null;                       //name of layers
            int         layerIndex = 0;                          //index of layers

            Rhino.DocObjects.Layer parent_layer_Approval = null; //create variable to hold approval layer
            Rhino.DocObjects.Layer parent_layer_Nesting  = null; //create variable to hold nesting layer
                                                                 //Rhino.DocObjects.Layer childlayer = null; //Create a variable to hold child layers
            string       text   = "";
            double       height = panel.labelHeight / 3;
            const string font   = "Arial";
            Guid         burrLeader;
            RhinoObject  labelText;

            Rhino.Geometry.Point3d pt    = new Rhino.Geometry.Point3d(0, 0, 0);
            Rhino.Geometry.Plane   plane = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();

            //start
            //Creating layer called "Layers for Approval Drawings" to make it a parent layer
            layerName = "LAYERS FOR APPROVAL DRAWINGS";
            // Does a layer with the same name already exist?
            layerIndex = doc.Layers.Find(layerName, true);

            // If layer does not exist
            if (layerIndex == -1)
            {
                // Add a new layer to the document
                layerIndex            = doc.Layers.Add(layerName, System.Drawing.Color.Black);
                parent_layer_Approval = doc.Layers[layerIndex]; //set the layer as parent layer
            }
            else
            {
                parent_layer_Approval = doc.Layers[layerIndex];
            }

            layerName = "LAYERS FOR NESTING";

            // Does a layer with the same name already exist?
            layerIndex = doc.Layers.Find(layerName, true);

            // If layer does not exist
            if (layerIndex == -1)
            {
                // Add a new layer to the document
                layerIndex           = doc.Layers.Add(layerName, System.Drawing.Color.Black);
                parent_layer_Nesting = doc.Layers[layerIndex];
            }
            else
            {
                parent_layer_Nesting = doc.Layers[layerIndex];
            }


            // Create a new layer called Perimeter
            layerName = "PANEL PERIMETER";

            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Black, parent_layer_Nesting); //make Nesting layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);

            //Bottom and left justified the panels in the grid (panel x0,x1,y0,y1 - refers to the folds edg (folds layer)
            double panelX0 = xLowerBound;
            double panelX1 = panelX0 + panel.X;
            double panelY0 = yUpperBound;
            double panelY1 = panelY0 + panel.Y;

            List <Point3d> list = new List <Point3d>();

            panel.Perimeter = doc.Objects.AddLine(new Point3d(panelX0, panelY1, 0), new Point3d(panelX1, panelY1, 0));
            guidList.Add(panel.Perimeter);

            panel.Perimeter = doc.Objects.AddLine(new Point3d(panelX0, panelY0, 0), new Point3d(panelX0, panelY1, 0));
            guidList.Add(panel.Perimeter);

            panel.Perimeter = doc.Objects.AddLine(new Point3d(panelX0, panelY0, 0), new Point3d(panelX1, panelY0, 0));
            guidList.Add(panel.Perimeter);

            panel.Perimeter = doc.Objects.AddLine(new Point3d(panelX1, panelY0, 0), new Point3d(panelX1, panelY1, 0));
            guidList.Add(panel.Perimeter);

            //MetrixUtilities.joinCurves(doc.Layers.Find("PANEL PERIMETER", true)); //join the closed curves using the method


            //Calculating the borders
            double borderX0 = panelX0 + panel.LeftBorder;  //refers to the borders corners
            double borderY0 = panelY0 + panel.BottomBorder;
            double borderX1 = panelX1 - panel.RightBorder;
            double borderY1 = panelY1 - panel.TopBorder;

            BoundingBox    panelBox          = new BoundingBox(borderX0, borderY0, 0, borderX1, borderY1, 0);
            List <Point3d> rectangle_corners = panelBox.GetCorners().Distinct().ToList();

            // add 1st point at last to close the loop
            rectangle_corners.Add(rectangle_corners[0]);
            // Create a new layer called Border

            layerName  = "BORDERS";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Purple, parent_layer_Approval); //pass to the method, make Approval layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);
            //Add the borders only if the panel is not solid
            if (panel.DrawPerf != 3)
            {
                //Create a bounding box for the borders
                panel.Border = doc.Objects.AddPolyline(rectangle_corners);
                guidList.Add(panel.Border);
            }

            // Create a new layer called LABELS
            layerName  = "LABELS";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Red, parent_layer_Nesting); //pass to the method, make Nesting layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);
            text         = panel.PartName;
            height       = panel.labelHeight;
            pt           = new Rhino.Geometry.Point3d(borderX0, borderY0 + 4 + height, 0);
            plane        = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();
            plane.Origin = pt;
            panel.Label  = doc.Objects.AddText(text, plane, height, font, false, false);
            guidList.Add(panel.Label);

            RhinoApp.RunScript("SelNone", true);
            labelText = doc.Objects.Find(panel.Label);
            labelText.Select(true);
            BoundingBox bbox = labelText.Geometry.GetBoundingBox(true);
            double      minX = bbox.Corner(true, true, true).X;
            double      maxX = bbox.Corner(false, true, true).X;
            double      minY = bbox.Corner(true, true, true).Y;
            double      maxY = bbox.Corner(true, false, true).Y;

            if (maxX - minX >= panel.X - panel.LeftBorder - panel.RightBorder)
            {
                double ratio = 1;
                labelText.Select(true);
                if (panel.Y > panel.X)
                {
                    RhinoApp.RunScript("_-rotate " + bbox.Center.X + "," + bbox.Center.Y + " " + "90", true);
                }

                if (maxY - minY + 4 >= panel.X - panel.LeftBorder - panel.RightBorder)
                {
                    ratio = (panel.X - panel.LeftBorder - panel.RightBorder) / (2 * (maxY - minY));
                    if (ratio * (maxX - minX) >= (panel.Y - panel.TopBorder - panel.BottomBorder))
                    {
                        ratio = ratio * (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * ratio * (maxX - minX));
                    }
                }
                else if (maxX - minX >= panel.Y - panel.TopBorder - panel.BottomBorder)
                {
                    ratio = (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * (maxX - minX));
                }
                RhinoApp.RunScript("_-Scale " + bbox.Center.X + "," + bbox.Center.Y + " " + ratio, true);
                BoundingBox bbox3     = labelText.Geometry.GetBoundingBox(true);
                double      distance1 = borderX0 + ratio * (bbox3.Max.X - bbox3.Min.X) / 2;
                double      distance2 = borderY0 + ratio * (bbox3.Max.Y - bbox3.Min.Y) / 2;
                if (panel.Y > panel.X)
                {
                    distance1 = borderX0 + ratio * (bbox3.Max.Y - bbox3.Min.Y) / 2;
                    distance2 = borderY0 + ratio * (bbox3.Max.X - bbox3.Min.X) / 2;
                }

                RhinoApp.WriteLine(bbox3.Center.ToString());
                RhinoApp.RunScript("_-Move " + bbox3.Center.X + "," + bbox3.Center.Y + ",0 " + distance1 + "," + distance2 + ",0", true);
            }
            else if (maxY - minY >= panel.Y - panel.TopBorder - panel.BottomBorder)
            {
                double ratio = (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * (maxY - minY));
                labelText.Select(true);
                RhinoApp.RunScript("_-Scale " + bbox.Center.X + "," + bbox.Center.Y + " " + ratio, true);
                BoundingBox bbox2     = labelText.Geometry.GetBoundingBox(true);
                double      distanceX = borderX0 + ratio * (bbox2.Center.X - bbox2.Min.X) / 2;
                double      distanceY = panelBox.Min.Y + ratio * (bbox2.Center.Y - bbox.Min.Y) / 2;

                RhinoApp.WriteLine(bbox2.Center.ToString());
                RhinoApp.RunScript("_-Move " + bbox2.Center.X + "," + bbox2.Center.Y + ",0 " + distanceX + "," + distanceY + ",0", true);
            }
            labelText.Select(false);

            // If dotFontLabel is more than 0 draw the dot font text on the panel, else skip
            // if (para.DotFont == 1)
            if (panel.DotFontLabel > 0)
            {
                // Create a new layer called DOT SCRIBE LABEL
                layerName = "DOT SCRIBE LABEL";

                layerIndex = createSubLayers.createSubLayer(layerName,
                                                            System.Drawing.Color.Black, parent_layer_Nesting); //make Nesting layer the parent layer


                doc.Layers.SetCurrentLayerIndex(layerIndex, true);

                // Put in the Dot Matrix Label
                // Draw at the right side of the border aand 10mm from the bottom and 100mm from the left edge
                double panelOffset = 0;
                if (panel.BottomBorder - 8.7 <= 6)
                {
                    panelOffset = (panel.BottomBorder - 8.7) / 2;
                }
                else
                {
                    panelOffset = 3.1;
                }
                if (panel.X < 160)
                {
                    pt = new Point3d(1 * (panelX0 + panelX1) / 2, panelY0 + panelOffset + 8.7, 0);
                }
                else
                {
                    pt = new Point3d(panelX1 - 100, panelY0 + panelOffset + 8.7, 0);
                }
                if (panel.DotFontLabellerSide.Equals("Rear"))
                {
                    DotMatrixLabellerCommand.Instance.drawDotMatrix(pt, panel.PartName, 8.7, panel.X); //set the size of dotfont
                }
                else //If not revered use front labeller
                {
                    DotMatrixFrontLabellerCommand.Instance.drawDotMatrix(pt, panel.PartName, 8.7);
                }
            }
            //checks whether the perforation layers exists, if not create layer and make Approval layer the parent layer
            //If exists, make Approval layer the parent layer
            layerName  = "PERFORATION";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Green, parent_layer_Approval);

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

            //Create Temporary Layer

            if (panel.DrawPerf == 1)
            {
                RhinoUtilities.SetActiveLayer("TemporaryPerfLayer", System.Drawing.Color.Green);
                doc.Views.Redraw();

                RhinoApp.RunScript("SelAll", true);
                RhinoApp.RunScript("-_Rotate 0,0,0 -" + panel.patternDirection, true);
                PerforationForm perforationForm = new PerforationForm(new Rhino.DocObjects.ObjRef(panel.Border).Curve());
                perforationForm.enablePerforation = enablePerf;
                perforationForm.drawPerforationDesign(panel.PatternName, true, enablePerf);
                RhinoApp.RunScript("SelAll", true);
                RhinoApp.RunScript("-_Rotate 0,0,0 " + panel.patternDirection, true);
                RhinoApp.RunScript("SelNone", true);

                var rhinoObjects        = doc.Objects.FindByLayer("TemporaryPerfLayer");
                var toolHitObjects      = doc.Objects.FindByLayer("TemporaryToolHit");
                var temporaryTool2Layer = doc.Objects.FindByLayer("TemporaryTool2Layer");

                //Perf objects
                if (rhinoObjects != null && rhinoObjects.Length > 1)
                {
                    foreach (var rhinObj in rhinoObjects)
                    {
                        rhinObj.Select(true);
                    }
                    if (panel.patternDirection == 1)
                    {
                        RhinoApp.RunScript("-_Rotate 0,0,0 -90", true);
                        RhinoApp.RunScript("-_Rotate 0,0,0 90", true);
                    }

                    RhinoUtilities.SetActiveLayer(Properties.Settings.Default.PerforationLayerName, System.Drawing.Color.Green);
                    RhinoApp.RunScript("-_ChangeLayer PERFORATION", true);
                    int index = doc.Layers.Find("TemporaryPerfLayer", true);
                    doc.Layers.Delete(index, true);
                }

                //tool hit objects
                if (toolHitObjects != null && toolHitObjects.Length > 1)
                {
                    foreach (var toolhitObj in toolHitObjects)
                    {
                        toolhitObj.Select(true);
                    }

                    if (panel.patternDirection == 1)
                    {
                        RhinoApp.RunScript("-_Rotate 0,0,0 -90", true);
                        RhinoApp.RunScript("-_Rotate 0,0,0 90", true);
                    }
                    RhinoUtilities.SetActiveLayer(Properties.Settings.Default.ToolHitLayerName, System.Drawing.Color.Black);
                    RhinoApp.RunScript("-_ChangeLayer TOOL HIT", true);
                    int index = doc.Layers.Find("TemporaryToolHit", true);
                    doc.Layers.Delete(index, true);
                }

                //Tool 2 objects
                if (temporaryTool2Layer != null && temporaryTool2Layer.Length > 1)
                {
                    foreach (var tool2Objs in temporaryTool2Layer)
                    {
                        tool2Objs.Select(true);
                    }
                    if (panel.patternDirection == 1)
                    {
                        RhinoApp.RunScript("-_Rotate 0,0,0 -90", true);
                        RhinoApp.RunScript("-_Rotate 0,0,0 90", true);
                    }

                    RhinoUtilities.SetActiveLayer("Tool 2 Layer", System.Drawing.Color.Yellow);
                    RhinoApp.RunScript("-_ChangeLayer Tool 2 Layer", true);
                    int index = doc.Layers.Find("TemporaryTool2Layer", true);
                    doc.Layers.Delete(index, true);
                }
                doc.Views.Redraw();
            }


            DimensionStyle dimStyle = MetrixUtilities.createMetrixRealDimension(); //sets the metrix real dimension

            Point3d         origin = new Point3d(0, 0, 0);
            Point3d         offset = new Point3d(0, 0, 0);
            Point2d         ext1;
            Point2d         ext2;
            Point2d         linePt;
            LinearDimension dimension;
            Guid            dimGuid = new Guid();
            double          u, v;


            // Create a new layer called DIMENSIONS BLACK
            layerName  = "DIMENSIONS BLACK";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Black, parent_layer_Approval); //pass to the method, make Approval layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);

            // Add the word perforated area to the panel
            if (panel.DrawPerf != 3) //Add the text only if the panel is not a solid panel
            {
                //pt = new Rhino.Geometry.Point3d(((borderX1 + borderX0) / 2) - 117.5, ((borderY1 + borderY0) / 2) + 33, 0);
                text         = System.Text.RegularExpressions.Regex.Unescape(panel.PerfText);
                height       = panel.labelHeight / 2;
                pt           = new Rhino.Geometry.Point3d(((borderX1 + borderX0) / 2) - 117.5, ((borderY1 + borderY0) / 2) + 10 + height, 0);
                plane.Origin = pt;
                Guid perforatedAreaLabel = doc.Objects.AddText(text, plane, height, font, false, false);
                guidList.Add(perforatedAreaLabel);

                double ratio = 1;

                if (panel.X - panel.LeftBorder - panel.RightBorder < 230)
                {
                    RhinoApp.RunScript("SelNone", true);
                    labelText = doc.Objects.Find(perforatedAreaLabel);
                    labelText.Select(true);
                    bbox = labelText.Geometry.GetBoundingBox(true);
                    if (panel.Y > panel.X)
                    {
                        RhinoApp.RunScript("_-rotate " + bbox.Center.X + "," + bbox.Center.Y + " " + "90", true);
                    }

                    minX = bbox.Corner(true, true, true).X;
                    maxX = bbox.Corner(false, true, true).X;
                    minY = bbox.Corner(true, true, true).Y;
                    maxY = bbox.Corner(true, false, true).Y;

                    if (maxY - minY > panel.X - panel.LeftBorder - panel.RightBorder)
                    {
                        ratio = (panel.X - panel.LeftBorder - panel.RightBorder) / (2 * (maxY - minY));
                        if (ratio * (maxX - minX) > (panel.Y - panel.TopBorder - panel.BottomBorder))
                        {
                            ratio = ratio * (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * ratio * (maxX - minX));
                        }
                    }
                    else if (maxX - minX >= panel.Y - panel.TopBorder - panel.BottomBorder)
                    {
                        ratio = (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * (maxX - minX));
                    }
                    labelText.Select(true);
                    RhinoApp.RunScript("_-Scale " + bbox.Center.X + "," + bbox.Center.Y + " " + ratio, true);
                    BoundingBox bbox2     = labelText.Geometry.GetBoundingBox(true);
                    double      distanceX = (borderX0 + borderX1) / 2;
                    double      distanceY = (borderY0 + borderY1) / 2;

                    RhinoApp.WriteLine(bbox2.Center.ToString());
                    RhinoApp.RunScript("_-Move " + bbox2.Center.X + "," + bbox2.Center.Y + ",0 " + distanceX + "," + distanceY + ",0", true);
                }
                else
                {
                    RhinoApp.RunScript("SelNone", true);
                    labelText = doc.Objects.Find(perforatedAreaLabel);
                    labelText.Select(true);
                    bbox = labelText.Geometry.GetBoundingBox(true);
                    minX = bbox.Corner(true, true, true).X;
                    maxX = bbox.Corner(false, true, true).X;
                    minY = bbox.Corner(true, true, true).Y;
                    maxY = bbox.Corner(true, false, true).Y;

                    if (maxX - minX > panel.Y - panel.TopBorder - panel.BottomBorder)
                    {
                        ratio = (panel.Y - panel.TopBorder - panel.BottomBorder) / (2 * (maxY - minY));
                        labelText.Select(true);
                        RhinoApp.RunScript("_-Scale " + bbox.Center.X + "," + bbox.Center.Y + " " + ratio, true);
                    }
                    BoundingBox bbox2     = labelText.Geometry.GetBoundingBox(true);
                    double      distanceX = (borderX0 + borderX1) / 2;
                    double      distanceY = (borderY0 + borderY1) / 2;

                    RhinoApp.WriteLine(bbox2.Center.ToString());
                    RhinoApp.RunScript("_-Move " + bbox2.Center.X + "," + bbox2.Center.Y + ",0 " + distanceX + "," + distanceY + ",0", true);
                }
            }

            // Add horizontal dimension
            origin = new Point3d(panelX1, panelY0 - 50, 0);
            offset = new Point3d(panelX0, panelY0 - 50, 0);
            pt     = new Point3d((offset.X - origin.X) / 2, panelY0 - 100, 0);

            plane        = Plane.WorldXY;
            plane.Origin = origin;

            //double u, v;
            plane.ClosestParameter(origin, out u, out v);
            ext1 = new Point2d(u, v);

            plane.ClosestParameter(offset, out u, out v);
            ext2 = new Point2d(u, v);

            plane.ClosestParameter(pt, out u, out v);
            linePt = new Point2d(u, v);


            dimension = new LinearDimension(plane, ext1, ext2, linePt);
            dimGuid   = doc.Objects.AddLinearDimension(dimension);       //add the bottom dimension(vertical line)
            guidList.Add(dimGuid);

            // Add vertical dimension for panel

            origin = new Point3d(panelX0 - 20, panelY0, 0);
            offset = new Point3d(panelX0 - 20, panelY1, 0);
            pt     = new Point3d(panelX0 - 100, (offset.Y - origin.Y) / 2, 0);

            plane        = Plane.WorldXY;
            plane.XAxis  = new Vector3d(0, -1, 0);
            plane.YAxis  = new Vector3d(-1, 0, 0);
            plane.ZAxis  = new Vector3d(0, 0, -1);
            plane.Origin = origin;

            plane.ClosestParameter(origin, out u, out v);
            ext1 = new Point2d(u, v);

            plane.ClosestParameter(offset, out u, out v);
            ext2 = new Point2d(u, v);

            plane.ClosestParameter(pt, out u, out v);
            linePt = new Point2d(u, v);

            dimension = new LinearDimension(plane, ext1, ext2, linePt);
            dimGuid   = doc.Objects.AddLinearDimension(dimension); //adds the left dimension

            guidList.Add(dimGuid);


            MetrixUtilities.createMetrixBordersDimension(); //sets the dimension style for borders

            // Draw Border dimension on BORDERS layer
            if (panel.DrawPerf != 3) ///Add only if the panel is not a solid panel
            {
                layerName  = "BORDERS";
                layerIndex = doc.Layers.Find(layerName, true);
                doc.Layers.SetCurrentLayerIndex(layerIndex, true);

                // Add horizontal borders dimension
                origin = new Point3d(panelX1, (panelY0 + panelY1) / 2, 0);
                offset = new Point3d(borderX1, (panelY0 + panelY1) / 2, 0);
                pt     = new Point3d((offset.X - origin.X) / 2, (borderY0 + borderY1) / 2, 0);

                plane        = Plane.WorldXY;
                plane.Origin = origin;

                plane.ClosestParameter(origin, out u, out v);
                ext1 = new Point2d(u, v);

                plane.ClosestParameter(offset, out u, out v);
                ext2 = new Point2d(u, v);

                plane.ClosestParameter(pt, out u, out v);
                linePt = new Point2d(u, v);

                dimension = new LinearDimension(plane, ext1, ext2, linePt);
                dimGuid   = doc.Objects.AddLinearDimension(dimension);

                guidList.Add(dimGuid);

                // Add horizontal borders dimension
                origin = new Point3d(panelX0, (panelY0 + panelY1) / 2, 0);
                offset = new Point3d(borderX0, (panelY0 + panelY1) / 2, 0);
                pt     = new Point3d((offset.X - origin.X) / 2, (borderY0 + borderY1) / 2, 0);


                plane.ClosestParameter(origin, out u, out v);
                ext1 = new Point2d(u, v);

                plane.ClosestParameter(offset, out u, out v);
                ext2 = new Point2d(u, v);

                plane.ClosestParameter(pt, out u, out v);
                linePt = new Point2d(u, v);

                dimension = new LinearDimension(plane, ext1, ext2, linePt);
                dimGuid   = doc.Objects.AddLinearDimension(dimension);

                guidList.Add(dimGuid);

                // Add vertical border dimension for panel

                origin = new Point3d((panelX0 + panelX1) / 2, panelY0, 0);
                offset = new Point3d((panelX0 + panelX1) / 2, borderY0, 0);
                pt     = new Point3d((borderX0 + borderX1) / 2, (offset.Y - origin.Y) / 2, 0);

                plane        = Plane.WorldXY;
                plane.XAxis  = new Vector3d(0, -1, 0);
                plane.YAxis  = new Vector3d(-1, 0, 0);
                plane.ZAxis  = new Vector3d(0, 0, -1);
                plane.Origin = origin;

                plane.ClosestParameter(origin, out u, out v);
                ext1 = new Point2d(u, v);

                plane.ClosestParameter(offset, out u, out v);
                ext2 = new Point2d(u, v);

                plane.ClosestParameter(pt, out u, out v);
                linePt = new Point2d(u, v);

                dimension = new LinearDimension(plane, ext1, ext2, linePt);
                dimGuid   = doc.Objects.AddLinearDimension(dimension);

                guidList.Add(dimGuid);

                origin = new Point3d((panelX0 + panelX1) / 2, panelY1, 0);
                offset = new Point3d((panelX0 + panelX1) / 2, borderY1, 0);
                pt     = new Point3d((borderX0 + borderX1) / 2, (offset.Y - origin.Y) / 2, 0);

                plane.ClosestParameter(origin, out u, out v);
                ext1 = new Point2d(u, v);

                plane.ClosestParameter(offset, out u, out v);
                ext2 = new Point2d(u, v);

                plane.ClosestParameter(pt, out u, out v);
                linePt = new Point2d(u, v);

                dimension = new LinearDimension(plane, ext1, ext2, linePt);
                dimGuid   = doc.Objects.AddLinearDimension(dimension);

                guidList.Add(dimGuid);
            }

            MetrixUtilities.createMetrixRealDimension(); //sets the default dimension style
            layerName  = "VIEWPORT";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Black, parent_layer_Approval); //pass to the method, make Approval layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);



            Rhino.DocObjects.RhinoObject label = doc.Objects.Find(panel.Label);
            string exportFileName = "1";

            if (label != null)
            {
                label.Select(true);
                Rhino.Geometry.TextEntity textentity = label.Geometry as Rhino.Geometry.TextEntity;
                exportFileName = textentity.Text + ".dxf";
            }


            /**
             * Checks if the dxf files are required by the user, if yes check whether the panel is perforated
             * using the drawPerf property in the panel. If it is a perforated panel then check if the directory
             * for perforated panels dxf files already exists, if does not exist create directory and run command.
             * If panel is not perforated, create directory to save not perforated panels dxf files if the directory
             * does not exist. Then run the dxf file create command.
             * */
            if (panel.DXFFilesRequired.Equals("Yes"))
            {
                String path;
                String immediateFolderName = Path.GetFileName(Path.GetDirectoryName(doc.Path)); //get the immediate foldername which the file is located in
                                                                                                //split the path to get the parent folder.
                String[] newPath = MetrixUtilities.splitString(Path.GetDirectoryName(doc.Path), immediateFolderName);
                if (panel.DrawPerf == 1)                                                        //checks if panel is perforated
                {
                    path = newPath[0] + ("5TRUMPF") + ("\\WITH PERF");                          //merge path for perforated files
                    if (!Directory.Exists(path))                                                //check if directory already exists
                    {
                        System.IO.Directory.CreateDirectory(path);                              //create directory if not exist
                    }
                }
                else
                {
                    path = newPath[0] + ("5TRUMPF") + ("\\NO PERF"); //merge path for not perforated files
                    if (!Directory.Exists(path))                     //check if directory already exists
                    {
                        System.IO.Directory.CreateDirectory(path);   //create directory if not exist
                    }
                }
                string command = string.Format("-_Export \"" + path + @"\" + exportFileName + "\"  Scheme \"R12 Lines & Arcs\" Enter");
                // Export the selected curves
                RhinoApp.RunScript(command, true);
            }
            // Unselect all objects
            doc.Objects.UnselectAll();

            // Default layer index
            int defaultLayerIndex = doc.Layers.Find("Default", true);

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);

            ////if draw perf is false, turnoff the toolhit layer
            //if (Convert.ToBoolean(panel.DrawPerf) != true)
            //{
            //   layerName = "Tool Hit";
            //   layerIndex = doc.Layers.Find(layerName, true);
            //   doc.Layers[layerIndex].IsVisible = false;
            //}



            MetrixUtilities.joinCurves(doc.Layers.Find("PANEL PERIMETER", true));
            if (panel.FixingHoles == "1")
            {
                //if fixing holes are not manipulated, recalculate distances
                if (!fixingHolesManipulated)
                {
                    //panel = reCalculateDistances(panel);

                    //Below method is if fixing holes are automated
                    guidList = FixingHoles.drawFixingFoles(panel, null, false, 0, 0, panelY0, panelY1, dimStyle, guidList, panelX0, panelX1, 0, 0, 0, 0, 0); //add fixing holes
                }
                else
                {
                    //Below method is if fixing holes  have been manipulated
                    guidList = CustomFixingHoles.drawFixingFoles(panel, null, false, 0, 0, panelY0, panelY1, dimStyle, guidList, panelX0, panelX1, 0, 0, 0, 0, 0); //add fixing holes
                }
            }
            layerName  = "VIEWPORT";
            layerIndex = createSubLayers.createSubLayer(layerName,
                                                        System.Drawing.Color.Black, parent_layer_Approval); //pass to the method, make Approval layer the parent layer

            doc.Layers.SetCurrentLayerIndex(layerIndex, true);

            foreach (Guid g in guidList)
            {
                int idx = RhinoDoc.ActiveDoc.Groups.Find(panel.PartName, false);

                if (idx < 0)
                {
                    idx = RhinoDoc.ActiveDoc.Groups.Add(panel.PartName);
                }

                RhinoDoc.ActiveDoc.Groups.AddToGroup(idx, g);
            }

            //end
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            string selectedLayer;
            Color  selectedColour;

            // For this example we will use a GetPoint class, but all of the custom
            // "Get" classes support command line options.
            Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("Select panels to create borders");

            double border = Properties.Settings.Default.PanelBorderDefault; // Default borderSize is 50

            // set up the options
            Rhino.Input.Custom.OptionDouble borderSizeOption = new Rhino.Input.Custom.OptionDouble(border);

            go.AddOptionDouble("Borders", ref borderSizeOption);
            go.AcceptNumber(true, true);
            go.GeometryFilter  = Rhino.DocObjects.ObjectType.Curve;
            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;
            go.EnableSelPrevious(true);
            go.EnablePreSelect(true, false);

            go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve;


            RequiredLayer getRequiredLayer = new RequiredLayer();

            getRequiredLayer.ShowDialog();
            selectedLayer  = getRequiredLayer.getLayerName();
            selectedColour = getRequiredLayer.getSelectedColor();
            while (true)
            {
                go.ClearCommandOptions();
                borderSizeOption = new Rhino.Input.Custom.OptionDouble(border);
                go.AddOptionDouble("Borders", ref borderSizeOption);
                // perform the get operation. This will prompt the user to select the list of curves, but also
                // allow for command line options defined above
                GetResult result = go.GetMultiple(1, 0);

                if (result == GetResult.Option)
                {
                    border = borderSizeOption.CurrentValue;
                    go.EnablePreSelect(false, true);
                    continue;
                }
                else if (result == GetResult.Number)
                {
                    border = go.Number();
                    continue;
                }
                else if (result != GetResult.Object)
                {
                    return(Result.Cancel);
                }

                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            int objecTCount = go.ObjectCount;

            border = borderSizeOption.CurrentValue;

            foreach (ObjRef objRef in go.Objects())
            {
                Curve curve = objRef.Curve();

                // If curve is null, means objRef is not a curve
                if (curve == null)
                {
                    continue;
                }

                // If curve is not Closed Curve
                if (curve.IsClosed == false)
                {
                    RhinoApp.WriteLine(objRef.ToString() + " curve is open");
                    continue;
                }

                if (curve.IsPlanar() == false)
                {
                    RhinoApp.WriteLine(objRef.ToString() + " curve is not planar");
                    continue;
                }

                // Process the curve
                Plane   plane = Rhino.Geometry.Plane.WorldXY;
                Curve[] offsetCurves;

                int layerIndex = doc.Layers.CurrentLayerIndex;
                RhinoUtilities.SetActiveLayer(selectedLayer, selectedColour);

                //if (curve.TryGetPlane(out plane))
                //{
                if (border < 0) //If the border is negative, it means the border should be drawn outside the perimeter
                {
                    plane.XAxis = -plane.XAxis;
                    plane.YAxis = -plane.YAxis;
                    plane.ZAxis = -plane.ZAxis;

                    offsetCurves = curve.Offset(plane, border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp);
                }
                else
                {
                    offsetCurves = curve.Offset(plane, -border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp);
                }

                //Check if the curve is outside border and border is a positive
                if (curve.Contains(offsetCurves[0].PointAtStart, Plane.WorldXY, 0) == PointContainment.Outside && border > 0)
                {
                    offsetCurves = curve.Offset(plane, border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp); //if true, then try to set the curve to be within the border
                }

                //Check if the curve is within the border and border is a negative
                if (curve.Contains(offsetCurves[0].PointAtStart, Plane.WorldXY, 0) == PointContainment.Inside && border < 0)
                {
                    offsetCurves = curve.Offset(plane, -border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp); //if true, then try to set the curve to be outside the border
                }

                foreach (Curve c in offsetCurves)
                {
                    doc.Objects.AddCurve(c);
                }


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

            doc.Views.Redraw();

            Properties.Settings.Default.PanelBorderDefault = border;
            Properties.Settings.Default.Save();

            return(Result.Success);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // For this example we will use a GetPoint class, but all of the custom
            // "Get" classes support command line options.
            Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("Select panels to create fixing holes");
            //get the default values for the properties
            double holeSize   = Properties.Settings.Default.FixingHoleSize;
            double offsetX    = Properties.Settings.Default.FixingHoleOffsetX;
            double offsetY    = Properties.Settings.Default.FixingHoleOffsetY;
            double spacing    = Properties.Settings.Default.FixingHoleSpacing;
            double minSpacing = Properties.Settings.Default.FixingHoleMinimum;

            // set up the options
            Rhino.Input.Custom.OptionDouble holeSizeOption   = new Rhino.Input.Custom.OptionDouble(holeSize);
            Rhino.Input.Custom.OptionDouble offsetXOption    = new Rhino.Input.Custom.OptionDouble(offsetX);
            Rhino.Input.Custom.OptionDouble offsetYOption    = new Rhino.Input.Custom.OptionDouble(offsetY);
            Rhino.Input.Custom.OptionDouble spacingOption    = new Rhino.Input.Custom.OptionDouble(spacing);
            Rhino.Input.Custom.OptionDouble minSpacingOption = new Rhino.Input.Custom.OptionDouble(minSpacing);


            //using option to get values and save automatically(only if user enters)
            go.AddOptionDouble("HoleSize", ref holeSizeOption);
            go.AddOptionDouble("OffsetX", ref offsetXOption);
            go.AddOptionDouble("OffsetY", ref offsetYOption);
            go.AddOptionDouble("Spacing", ref spacingOption);
            go.AddOptionDouble("MinSpacing", ref minSpacingOption);

            go.AcceptNumber(true, true);
            go.GeometryFilter  = Rhino.DocObjects.ObjectType.Curve;
            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;
            go.EnableSelPrevious(true);
            go.EnablePreSelect(true, false);

            go.GeometryFilter = Rhino.DocObjects.ObjectType.Curve;

            while (true)
            {
                go.ClearCommandOptions();
                holeSizeOption   = new Rhino.Input.Custom.OptionDouble(holeSize);
                offsetXOption    = new Rhino.Input.Custom.OptionDouble(offsetX);
                offsetYOption    = new Rhino.Input.Custom.OptionDouble(offsetY);
                spacingOption    = new Rhino.Input.Custom.OptionDouble(spacing);
                minSpacingOption = new Rhino.Input.Custom.OptionDouble(minSpacing);

                go.AddOptionDouble("HoleSize", ref holeSizeOption);
                go.AddOptionDouble("OffsetX", ref offsetXOption);
                go.AddOptionDouble("OffsetY", ref offsetYOption);
                go.AddOptionDouble("Spacing", ref spacingOption);
                go.AddOptionDouble("MinSpacing", ref minSpacingOption);
                // perform the get operation. This will prompt the user to select the list of curves, but also
                // allow for command line options defined above
                GetResult result = go.GetMultiple(1, 0);

                if (result == GetResult.Option)
                {
                    holeSize   = holeSizeOption.CurrentValue;
                    offsetX    = offsetXOption.CurrentValue;
                    offsetY    = offsetYOption.CurrentValue;
                    spacing    = spacingOption.CurrentValue;
                    minSpacing = minSpacingOption.CurrentValue;
                    go.EnablePreSelect(false, true);
                    continue;
                }
                //else if (result == GetResult.Number)
                //{
                //   border = go.Number();
                //   continue;
                //}
                else if (result != GetResult.Object)
                {
                    return(Result.Cancel);
                }

                if (go.ObjectsWerePreselected)
                {
                    go.EnablePreSelect(false, true);
                    continue;
                }

                break;
            }

            int objecTCount = go.ObjectCount;

            foreach (ObjRef objRef in go.Objects())
            {
                Curve curve = objRef.Curve();

                // If curve is null, means objRef is not a curve
                if (curve == null)
                {
                    continue;
                }

                // If curve is not Closed Curve
                if (curve.IsClosed == false)
                {
                    RhinoApp.WriteLine(objRef.ToString() + " curve is open");
                    continue;
                }

                if (curve.IsPlanar() == false)
                {
                    RhinoApp.WriteLine(objRef.ToString() + " curve is not planar");
                    continue;
                }


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

                List <Point3d> pointsList = new List <Point3d> ();

                // Calculate top and bottom fixing holes
                double runningX = min.X + offsetX; //25
                double runningY = max.Y - offsetY; //-626.5

                Point3d point;

                while (runningX < (max.X - offsetX) - minSpacing)
                {
                    point = new Point3d(runningX, runningY, 0);
                    pointsList.Add(point);

                    point = new Point3d(runningX, min.Y + offsetY, 0);
                    pointsList.Add(point);

                    runningX = runningX + spacing;
                }

                point = new Point3d(max.X - offsetX, runningY, 0); //adds the top right fixing hole
                pointsList.Add(point);

                point = new Point3d(max.X - offsetX, min.Y + offsetY, 0); //adds the bottom right fixing hole
                pointsList.Add(point);

                runningY = runningY - spacing;

                // Calculate the sides
                while (runningY > (min.Y - offsetY) + minSpacing)
                {
                    point = new Point3d(min.X + offsetX, runningY, 0); //adds the left fixing holes
                    pointsList.Add(point);

                    point = new Point3d(max.X - offsetX, runningY, 0); //adds the right fixing hole
                    pointsList.Add(point);

                    runningY = runningY - spacing;
                }

                // Process the curve
                Plane plane = Rhino.Geometry.Plane.WorldXY;

                int layerIndex = doc.Layers.CurrentLayerIndex;

                RhinoUtilities.SetActiveLayer("Fixing Holes", System.Drawing.Color.Black);

                // Draw all the holes
                Round round = new Round();
                round.X = holeSize;


                foreach (Point3d p in pointsList)
                {
                    round.drawTool(p);
                }

                //Round round = new Round();
                //round.X = holeSize;
                //round.drawTool(point);


                //offsetCurves = curve.Offset(plane, -border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp);

                //if (curve.Contains(offsetCurves[0].PointAtStart, Plane.WorldXY, 0) == PointContainment.Outside)
                //{
                //   offsetCurves = curve.Offset(plane, border, 0.1, Rhino.Geometry.CurveOffsetCornerStyle.Sharp);
                //}


                //foreach (Curve c in offsetCurves)
                //{
                //   doc.Objects.AddCurve(c);
                //}
                //// }

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

            doc.Views.Redraw();

            Properties.Settings.Default.FixingHoleSize    = holeSize;
            Properties.Settings.Default.FixingHoleOffsetX = offsetX;
            Properties.Settings.Default.FixingHoleOffsetY = offsetY;
            Properties.Settings.Default.FixingHoleSpacing = spacing;
            Properties.Settings.Default.FixingHoleMinimum = minSpacing;
            Properties.Settings.Default.Save();

            return(Result.Success);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            string fontName = "Dot-Matrix";
            float  fontSize = 12;

            using (System.Drawing.Font fontTester = new System.Drawing.Font(fontName, fontSize))
            {
                if (fontTester.Name == fontName)
                {
                    // Font exists do nothing
                }
                else
                {
                    RhinoApp.WriteLine("Dot Matrix Font does not exist, press install to install the font. Restart Rhino after installation.");

                    string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

                    Process.Start(assemblyFolder + @"\Fonts\dotmat_0.ttf");

                    return(Rhino.Commands.Result.Failure);
                }
            }

            // Check the selected dot
            GetObject go = new GetObject();

            go.GroupSelect     = true;
            go.SubObjectSelect = false;
            go.EnableClearObjectsOnEntry(false);
            go.EnableUnselectObjectsOnExit(false);
            go.DeselectAllBeforePostSelect = false;
            go.EnableSelPrevious(true);
            go.EnablePreSelect(true, false);
            go.GeometryFilter = Rhino.DocObjects.ObjectType.Point | Rhino.DocObjects.ObjectType.Annotation;

            go.SetCommandPrompt("Select Label and a point:");
            GetResult result = go.GetMultiple(2, -1);

            if (go.CommandResult() != Rhino.Commands.Result.Success)
            {
                return(go.CommandResult());
            }

            RhinoApp.WriteLine("Object selection counter = {0}", go.ObjectCount);

            Point      pt           = null;
            TextEntity textEntity   = null;
            int        pointCounter = 0;
            int        textCounter  = 0;


            // Loop through all the objects to find Text
            for (int i = 0; i < go.ObjectCount; i++)
            {
                RhinoObject rhinoObject = go.Object(i).Object();

                if (rhinoObject.ObjectType == ObjectType.Annotation)
                {
                    textEntity = rhinoObject.Geometry as TextEntity;

                    if (textEntity != null && textCounter == 0)
                    {
                        textCounter++;
                    }
                }
                else if (rhinoObject.ObjectType == ObjectType.Point)
                {
                    pt = rhinoObject.Geometry as Point;

                    if (pt != null && pointCounter == 0)
                    {
                        pointCounter++;
                    }
                }
            }



            //if (go.Object(0).Point() != null && go.Object(1).TextEntity() != null)
            //{
            //   pt = go.Object(0).Point();
            //   textEntity = go.Object(1).TextEntity();
            //}
            //else if (go.Object(1).Point() != null && go.Object(0).TextEntity() != null)
            //{
            //   pt = go.Object(1).Point();
            //   textEntity = go.Object(0).TextEntity();
            //}
            //else
            //{
            //   RhinoApp.WriteLine("Two of the same objects are selected.");
            //   return Result.Failure;
            //}

            if (textCounter > 1)
            {
                RhinoApp.WriteLine("More than one text has been selected.");
            }

            if (pointCounter > 1)
            {
                RhinoApp.WriteLine("More than one point has been selected.");
            }


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

            // Set the layer to perforation
            RhinoUtilities.SetActiveLayer(Properties.Settings.Default.DotFontLayerName, System.Drawing.Color.Black);

            if (pt != null && textEntity != null)
            {
                drawDotMatrix(pt.Location, textEntity.Text, Properties.Settings.Default.DotMatrixHeight, 80);
            }

            doc.Layers.SetCurrentLayerIndex(currentLayer, true);

            doc.Views.Redraw();

            return(Result.Success);
        }
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // Open file dialog
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.InitialDirectory = doc.Path;
            openFileDialog.Filter           = "3dm files (*.3dm)|*.3dm| dxf files (*.dxf)|*.dxf|All files (*.*)|*.*";
            openFileDialog.FilterIndex      = 2;
            openFileDialog.RestoreDirectory = true;
            openFileDialog.Multiselect      = true;
            openFileDialog.Title            = "CAD files to merge";

            DialogResult dr = openFileDialog.ShowDialog();
            uint         firstSN, lastSN;
            string       sScript;
            BoundingBox  bbox;
            string       panelDetails = "";

            double             importMinX, importMinY;
            double             importMaxX, importMaxY;
            double             globalMinX, globalMinY;
            double             globalMaxX, globalMaxY;
            double             gap          = 500;
            Boolean            executedOnce = false;
            double             commonminY   = 0;
            double             commonminX   = 0;
            double             commonmaxY   = 0;
            List <RhinoObject> imported     = new List <RhinoObject>(); //holds the imported rhino obects (all objects)
            List <RhinoObject> oldObjs      = new List <RhinoObject>(); //holds the old objects in the document
            List <RhinoObject> newObjs      = new List <RhinoObject>(); //holds the new objects in the document
            Boolean            newObjFound  = false;

            if (dr == System.Windows.Forms.DialogResult.OK)
            {
                //Select direction and angle
                double            rotationAngle = 0;
                bool              anticlockwise = true;
                MessageBoxButtons buttons       = MessageBoxButtons.YesNo;

                DialogResult result = MessageBox.Show("Do you want to rotate each dxf imported by 90°?", "DXF rotation", buttons);
                if (result == DialogResult.Yes)
                {
                    rotationAngle = 90;
                    result        = MessageBox.Show("Select the rotation direction: 'Yes' for 'Anti-clockwise' and 'No' for 'Clockwise'.", "Rotation Direction", buttons);
                    if (result == DialogResult.No)
                    {
                        rotationAngle = -90;
                        anticlockwise = false;
                    }
                }



                // Read the files
                foreach (String file in openFileDialog.FileNames)
                {
                    importMinX = Double.MaxValue;
                    importMinY = Double.MaxValue;
                    importMaxX = Double.MinValue;
                    importMaxY = Double.MinValue;
                    globalMinX = Double.MaxValue;
                    globalMinY = Double.MaxValue;
                    globalMaxX = Double.MinValue;
                    globalMaxY = Double.MinValue;

                    // Import each file
                    try
                    {
                        sScript = String.Format("! _-Import \"{0}\" _Enter", file);

                        firstSN = RhinoObject.NextRuntimeSerialNumber;
                        RhinoApp.RunScript(sScript, false);
                        lastSN = RhinoObject.NextRuntimeSerialNumber; //Investigate later
                        List <Guid> ids = new List <Guid>();
                        imported = new List <RhinoObject>();
                        newObjs  = new List <RhinoObject>();
                        foreach (RhinoObject obj in doc.Objects)
                        {
                            if (obj.RuntimeSerialNumber >= firstSN && obj.RuntimeSerialNumber < lastSN)
                            {
                                imported.Add(obj);
                                ids.Add(obj.Id);

                                bbox = obj.Geometry.GetBoundingBox(Plane.WorldXY);

                                if (importMaxX < bbox.Max.X)
                                {
                                    importMaxX = bbox.Max.X;
                                }

                                if (importMaxY < bbox.Max.Y)
                                {
                                    importMaxY = bbox.Max.Y;
                                }

                                if (importMinX > bbox.Min.X)
                                {
                                    importMinX = bbox.Min.X;
                                }

                                if (importMinY > bbox.Min.Y)
                                {
                                    importMinY = bbox.Min.Y;
                                }
                            }
                            else
                            {
                                //Global
                                bbox = obj.Geometry.GetBoundingBox(Plane.WorldXY);

                                if (globalMaxX < bbox.Max.X)
                                {
                                    globalMaxX = bbox.Max.X;
                                }

                                if (globalMaxY < bbox.Max.Y)
                                {
                                    globalMaxY = bbox.Max.Y;
                                }

                                if (globalMinX > bbox.Min.X)
                                {
                                    globalMinX = bbox.Min.X;
                                }

                                if (globalMinY > bbox.Min.Y)
                                {
                                    globalMinY = bbox.Min.Y;
                                }
                            }
                        }

                        if (!executedOnce) //execute this only once
                        {
                            commonminY = importMinY;
                            commonminX = importMinX;
                            commonmaxY = importMaxY;
                        }

                        var startPoint = new Point3d(importMinX, importMinY, 0);

                        if (globalMaxX == Double.MinValue)
                        {
                            globalMaxX = 0;
                        }
                        if (globalMaxY == Double.MinValue)
                        {
                            globalMaxY = 0;
                        }
                        if (globalMinX == Double.MaxValue)
                        {
                            globalMinX = 0;
                        }
                        if (globalMinY == Double.MaxValue)
                        {
                            globalMinY = 0;
                        }


                        var endPoint = new Point3d(globalMaxX + gap, commonminY, 0);

                        List <string> names = new List <string>();
                        //find which type of perimeter
                        for (int i = 0; i < 100; i++)
                        {
                            if (doc.Layers.FindIndex(i) != null)
                            {
                                names.Add(doc.Layers.FindIndex(i).Name);
                            }
                            else
                            {
                                break;
                            }
                        }

                        /*
                         * String perimeterName = "Default";
                         * //Get the correct perimeter name
                         * if (doc.Layers.Find("LAYERS_FOR_NESTING$PANEL_P", true) >= 0)
                         * {
                         *  perimeterName = "LAYERS_FOR_NESTING$PANEL_P";
                         * }
                         *
                         * if (doc.Layers.Find("Panel_Perimeter", true) >= 0)
                         * {
                         *  perimeterName = "Panel_Perimeter";
                         * }  */

                        int layer_index = doc.Layers.Find("PANEL PERIMETER", true);
                        if (layer_index < 0)
                        {
                            // Add a new layer to the document
                            layer_index = doc.Layers.Add("PANEL PERIMETER", System.Drawing.Color.Black);
                        }


                        foreach (string perimeterName in names)
                        {
                            foreach (RhinoObject obj in doc.Objects.FindByLayer(perimeterName))
                            {
                                ObjRef objR = new ObjRef(obj);
                                if (objR.Curve() == null)
                                {
                                    continue;
                                }
                                //loop through the old objects array to find if the object is found in the array
                                foreach (RhinoObject rhinObj in oldObjs)
                                {
                                    if (rhinObj.Id.Equals(obj.Id)) //if the ids are equals it means the object belongs to a panel which has already been rotated
                                    {
                                        newObjFound = true;        //set to true
                                        break;                     //exit from this second loop
                                    }
                                }
                                if (!newObjFound)     //go in only if the newObjectfound is false
                                {
                                    newObjs.Add(obj); //add the new object to the array
                                }
                                newObjFound = false;  //set the variable back to false
                            }
                        }



                        // Move all the objects
                        var xform = Transform.Translation(endPoint - startPoint);
                        foreach (var objRef in imported)
                        {
                            doc.Objects.Transform(objRef, xform, true);
                        }

                        executedOnce = true;

                        Rhino.Geometry.Point3d pt    = new Rhino.Geometry.Point3d(globalMaxX + gap, (commonminY + commonmaxY) / 2, 0);
                        Rhino.Geometry.Plane   plane = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();
                        plane.Origin = pt;
                        String dimension = findLeastDimension(newObjs, plane, "PANEL PERIMETER", rotationAngle); //call the method and pass the parameters to find the min X and min Y for the panel


                        // Add the file as the label

                        //The codes below are to create red labels for each panel

                        double height = (importMaxY - importMinY) * 0.1;
                        //double height = 3;
                        string label      = Path.GetFileNameWithoutExtension(file);
                        int    layerIndex = doc.Layers.CurrentLayerIndex;

                        RhinoUtilities.SetActiveLayer("LABELS", System.Drawing.Color.Red);

                        const string font = "Arial";
                        plane        = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();
                        plane.Origin = pt;
                        Guid labelGuid = doc.Objects.AddText(label, plane, height, font, false, false);

                        ids.Add(labelGuid);
                        imported.Add(doc.Objects.Find(labelGuid));

                        doc.Layers.SetCurrentLayerIndex(layerIndex, true);

                        //panelDetails = panelDetails + label + "\t" + (importMaxX - importMinX) + "\t" + (importMaxY - importMinY) + "\n";
                        panelDetails = panelDetails + label + "#" + dimension + "\n"; //set the dimension with the panel name                                                                                                                                                                                                                                                                             vv



                        //int index = doc.Groups.Add(ids);

                        oldObjs.AddRange(newObjs);
                    }
                    catch (Exception ex)
                    {
                        // Could not load the image - probably related to Windows file system permissions.
                        MessageBox.Show(ex.Message);
                    }
                }


                double labelHeight = 100;
                Rhino.Geometry.Point3d panelDetailsPt    = new Rhino.Geometry.Point3d(0, 0 + labelHeight, 0);
                const string           labelFont         = "Arial";
                Rhino.Geometry.Plane   panelDetailsPlane = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();
                panelDetailsPlane.Origin = panelDetailsPt;
                doc.Objects.AddText(panelDetails, panelDetailsPlane, labelHeight, labelFont, false, false);

                doc.Layers.Delete(doc.Layers.Find("temp", false), true);

                exportToExcel(panelDetails); //call to export panel dimensions to excel
            }

            Messages.excelOperationComplete();

            // Export the whole lot
            //string command = string.Format("-_Export \"" + Path.GetDirectoryName(doc.Path) + @"\" + labelName + "\"  Scheme \"R12 Lines & Arcs\" Enter");
            // Export the selected curves
            //RhinoApp.RunScript(command, true);
            doc.Views.Redraw();
            return(Result.Success);
        }
        public String findLeastDimension(List <RhinoObject> newObjs, Plane plane, String perimeterName, double rotationAngle)
        {
            RhinoDoc doc        = RhinoDoc.ActiveDoc;
            double   minX       = 0;
            double   minY       = 0;
            double   minArea    = double.MaxValue;
            Layer    layerIndex = doc.Layers.FindName("Default");

            RhinoUtilities.SetActiveLayer("temp", System.Drawing.Color.Black);
            //Copy Objects of current layer to temp layer
            foreach (var selected_object in newObjs)
            {
                selected_object.Attributes.LayerIndex = doc.Layers.Find("temp", false);
                selected_object.CommitChanges();
            }
            //select objects in the temporart layer and join
            RhinoApp.RunScript("SelNone", true);
            RhinoApp.RunScript("SelLayerNumber " + doc.Layers.Find("temp", true), false);
            //MetrixUtilities.joinCurves(doc.Layers.Find("temp", false));


            //plane.Rotate(i, plane.XAxis); //rotateshape with the value of i
            RhinoObject[] objs      = doc.Objects.FindByLayer("temp");
            List <Curve>  curveList = new List <Curve>();

            Curve[]     curveArray = null;
            RhinoObject obj        = objs[0];

            foreach (RhinoObject objt in objs)
            {
                curveList.Add(new ObjRef(objt).Curve());
            }
            curveArray = Curve.JoinCurves(curveList);



            obj.Attributes.ToString();
            ObjRef objR        = new ObjRef(obj);
            Curve  curve       = objR.Curve();
            double curvelength = -1;
            Curve  baseline    = null;
            double angle       = 0;

            foreach (Curve cv in curveList)
            {
                if (cv.GetLength() > curvelength)
                {
                    curvelength = cv.GetLength();
                    baseline    = cv;
                    angle       = Math.Atan(baseline.TangentAtStart.Y / baseline.TangentAtStart.X);
                }
            }

            if (curveArray != null)
            {
                double maxArea = Double.MinValue;
                foreach (Curve tempCurve in curveArray)
                {
                    BoundingBox tempBBox = tempCurve.GetBoundingBox(true);
                    if (tempBBox.Area > maxArea)
                    {
                        curve = tempCurve;
                    }
                }
            }
            BoundingBox    boundingBox    = curve.GetBoundingBox(Plane.WorldXY);
            List <Point3d> points         = new List <Point3d>();
            PolylineCurve  polyline_curve = curve as PolylineCurve;
            double         diagnal        = 0;
            bool           rectangle      = false;
            Point3d        centerC        = boundingBox.Center;

            minArea = boundingBox.Area;
            minX    = boundingBox.Max.X - boundingBox.Min.X;
            minY    = boundingBox.Max.Y - boundingBox.Min.Y;

            /*
             * if (polyline_curve != null && polyline_curve.PointCount == 5)
             * {
             *  for (int j = 0; j < polyline_curve.PointCount; j++)
             *  {
             *      points.Add(polyline_curve.Point(j));
             *  }
             *
             *  if(Math.Round(points[0].DistanceTo(points[1])) == Math.Round(points[2].DistanceTo(points[3])))
             *  {
             *      minX = points[0].DistanceTo(points[1]);
             *      minY = points[1].DistanceTo(points[2]);
             *      rectangle = true;
             *  }
             *  else
             *  {
             *      rectangle = false;
             *  }
             * }*/

            if (rectangle == false)
            {
                curve.Rotate(-angle, Plane.WorldXY.ZAxis, baseline.PointAtStart);
                boundingBox = curve.GetBoundingBox(Plane.WorldXY);
                if (boundingBox.Area < minArea)
                {
                    Point3d min = boundingBox.Min;
                    Point3d max = boundingBox.Max;
                    minX = max.X - min.X;
                    minY = max.Y - min.Y;
                }
            }


            RhinoApp.RunScript("-_Rotate " + centerC + " " + rotationAngle, false);


            //RhinoApp.RunScript("-_Rotate " + boundingBox.Center +" " + 5, false);



            //Set back the previous default layer
            RhinoUtilities.SetActiveLayer(perimeterName, System.Drawing.Color.Black);
            //Copy all object of temp layer back to the previous layer
            foreach (var selected_object in doc.Objects.FindByLayer("temp"))
            {
                selected_object.Attributes.LayerIndex = doc.Layers.FindByFullPath(perimeterName, false);
                selected_object.CommitChanges();
            }

            doc.Layers.SetCurrentLayerIndex(doc.Layers.FindByFullPath(layerIndex.Name, false), true);
            //needs to fix the tab issue
            return(String.Format("{0}#{1}", Math.Max(minX, minY), Math.Min(minX, minY))); //return the minX and minY for the panel
        }