public List<string> CreateSketch(Section section, Section symmetricSection, CampaignReport campaignReport, List<SteelThicknessGaugingPoint> steelThicknessGaugingPoints, out SortedList<int, List<SteelThicknessGaugingPoint>> pointsPerSketch)
        {
            try
            {
                if (section == null)
                {
                    throw new ArgumentNullException("section");
                }

                if (symmetricSection == null)
                {
                    throw new ArgumentNullException("symmetricSection");
                }

                if (campaignReport == null)
                {
                    throw new ArgumentNullException("campaignReport");
                }

                int index = 0;
                pointsPerSketch = new SortedList<int, List<SteelThicknessGaugingPoint>>();

                if (!section.SectionType.Name.Equals("Shell") && !section.SectionType.Name.Equals("Longitudinal") &&
                    !section.SectionType.Name.Equals("LongitudinalBulkheads") && !symmetricSection.SectionType.Name.Equals("Shell") &&
                    !symmetricSection.SectionType.Name.Equals("Longitudinal") && !symmetricSection.SectionType.Name.Equals("LongitudinalBulkheads")
                    )
                {
                    return null;
                }

                string sectionDrawerCurrentViewModeName = section.SectionDrawer.CurrentViewModeName;
                section.SectionDrawer.CurrentViewModeName = "SketchFormat";

                Vessel vessel = section.Vessel;
                Document document = vessel.Document as Document;

                if (!this.sectionThumbnails.ContainsKey(vessel.GUID))
                {
                    this.sectionThumbnails.Add(vessel.GUID, new Dictionary<int, Bitmap>());
                }
                if (!this.sectionThumbnails[vessel.GUID].ContainsKey(section.ID))
                {
                    this.sectionThumbnails[vessel.GUID].Add(section.ID, null);
                }
                if (this.sectionThumbnails[vessel.GUID][section.ID] == null)
                {
                    CaptionsModel.Instance.SetCaptionPropertySelection("Plate", "IACSSketchDescription", false);

                    section.SectionDrawer.CurrentViewModeName = "Wireframe";

                    section.SectionDrawer.ConfigureView(this.glPanel, section.GetDefaultView(), true);
                    section.SectionDrawer.UpdateLastCamera(this.glPanel);

                    section.SectionDrawer.DrawAxis = false;
                    bool isWireframeVisible = ViewModesData.Instance.IsVisible(section.SectionDrawer.CurrentViewModeName, "Wireframe");
                    if (!isWireframeVisible)
                    {
                        ViewModesData.Instance.SetVisibility(section.SectionDrawer.CurrentViewModeName, "Wireframe", true, true);
                    }

                    Bitmap bitmap = section.SectionDrawer.DrawModelImmediateMode(this.glPanel);

                    if (!isWireframeVisible)
                    {
                        ViewModesData.Instance.SetVisibility(section.SectionDrawer.CurrentViewModeName, "Wireframe", false, true);
                    }

                    section.SectionDrawer.DrawAxis = true;

                    this.sectionThumbnails[vessel.GUID][section.ID] = bitmap;

                    section.SectionDrawer.CurrentViewModeName = "SketchFormat";

                    CaptionsModel.Instance.SetCaptionPropertySelection("Plate", "IACSSketchDescription", true);
                }

                Bitmap originalThumbnail = this.sectionThumbnails[vessel.GUID][section.ID];

                List<string> bitmaps = new List<string>();

                List<SteelThicknessGaugingPoint> sectionSteelThicknessGaugingPoints = new List<SteelThicknessGaugingPoint>();
                List<SteelThicknessGaugingPoint> symmetricSteelThicknessGaugingPoints = new List<SteelThicknessGaugingPoint>();

                foreach (SteelThicknessGaugingPoint steelThicknessGaugingPoint in steelThicknessGaugingPoints)
                {
                    if (steelThicknessGaugingPoint.Section.ID == section.ID)
                    {
                        sectionSteelThicknessGaugingPoints.Add(steelThicknessGaugingPoint);
                    }
                    else if (steelThicknessGaugingPoint.Section.ID == symmetricSection.ID)
                    {
                        symmetricSteelThicknessGaugingPoints.Add(steelThicknessGaugingPoint);
                    }
                }

                if (sectionSteelThicknessGaugingPoints != null || symmetricSteelThicknessGaugingPoints != null)
                {
                    #region Old Code

                    //int numberOfSketches = 9;

                    //Point3D minPoint = section.BoundingBox.MinPoint;
                    //Point3D maxPoint = section.BoundingBox.MaxPoint;

                    //double sizeX = maxPoint.X - minPoint.X;
                    //double deltaX = Math.Ceiling(sizeX / numberOfSketches);

                    //Vector3D planeNormal = new Vector3D(1, 0, 0);

                    //for (int i = 0; i < numberOfSketches; i++)
                    //{
                    //    Point3D minPlanePoint = new Point3D(minPoint.X + (i * deltaX), minPoint.Y, minPoint.Z);
                    //    Point3D maxPlanePoint = new Point3D(minPoint.X + ((i + 1) * deltaX), minPoint.Y, minPoint.Z);
                    //    Plane minPlane = new Plane(planeNormal, minPlanePoint);
                    //    Plane maxPlane = new Plane(planeNormal, maxPlanePoint);

                    #endregion

                    SortedList<float, SteelThicknessGaugingPoint> sortedSteelThicknessGaugingPoints = new SortedList<float, SteelThicknessGaugingPoint>();

                    foreach (SteelThicknessGaugingPoint steelThicknessGaugingPoint in steelThicknessGaugingPoints)
                    {
                        float x = steelThicknessGaugingPoint.PointGeometry.Position.X;
                        while (sortedSteelThicknessGaugingPoints.ContainsKey(x))
                        {
                            x += (float)Point3D.Epsilon;
                        }

                        sortedSteelThicknessGaugingPoints.Add(x, steelThicknessGaugingPoint);
                    }

                    float minKey = sortedSteelThicknessGaugingPoints.Keys[0];
                    float maxKey = sortedSteelThicknessGaugingPoints.Keys[sortedSteelThicknessGaugingPoints.Count - 1];

                    Point3D minPoint = sortedSteelThicknessGaugingPoints[minKey].PointGeometry.Position;
                    Point3D maxPoint = sortedSteelThicknessGaugingPoints[maxKey].PointGeometry.Position;

                    minPoint.Translate(-2 * Point3D.Epsilon, 0, 0);
                    maxPoint.Translate(2 * Point3D.Epsilon, 0, 0);

                    double defaultSketchSize = 40;
                    double sizeX = maxPoint.X - minPoint.X;

                    int numberOfSketches = (int)Math.Floor(sizeX / defaultSketchSize);

                    if (sizeX < defaultSketchSize)
                    {
                        defaultSketchSize = sizeX;
                        numberOfSketches = 1;
                    }
                    else
                    {
                        double mod = sizeX - (numberOfSketches * defaultSketchSize);
                        if (mod > (defaultSketchSize / 2))
                        {
                            numberOfSketches++;
                            defaultSketchSize -= (mod / numberOfSketches);
                        }
                        else
                        {
                            defaultSketchSize += (mod / numberOfSketches);
                        }
                    }

                    Vector3D planeNormal = new Vector3D(1, 0, 0);
                    for (int i = 0; i < numberOfSketches; i++)
                    {
                        Point3D minPlanePoint = new Point3D(minPoint.X + (i * defaultSketchSize), minPoint.Y, minPoint.Z);
                        Point3D maxPlanePoint = new Point3D(minPoint.X + ((i + 1) * defaultSketchSize), minPoint.Y, minPoint.Z);
                        Plane minPlane = new Plane(planeNormal, minPlanePoint);
                        Plane maxPlane = new Plane(planeNormal, maxPlanePoint);

                        List<SteelThicknessGaugingPoint> sectionGaugingPointsBySketch = (sectionSteelThicknessGaugingPoints != null) ? this.GetPointsBetweenPlanes(sectionSteelThicknessGaugingPoints, minPlane, maxPlane) : null;
                        List<SteelThicknessGaugingPoint> symmetricGaugingPointsBySketch = (symmetricSteelThicknessGaugingPoints != null) ? this.GetPointsBetweenPlanes(symmetricSteelThicknessGaugingPoints, minPlane, maxPlane) : null;

                        if ((sectionGaugingPointsBySketch == null || sectionGaugingPointsBySketch.Count == 0) &&
                            (symmetricGaugingPointsBySketch == null || symmetricGaugingPointsBySketch.Count == 0))
                        {
                            continue;
                        }

                        List<SteelThicknessGaugingPoint> gaugingPointsBySketch = new List<SteelThicknessGaugingPoint>();
                        if (sectionGaugingPointsBySketch != null && sectionGaugingPointsBySketch.Count > 0)
                        {
                            gaugingPointsBySketch.AddRange(sectionGaugingPointsBySketch);
                        }
                        if (symmetricGaugingPointsBySketch != null && symmetricGaugingPointsBySketch.Count > 0)
                        {
                            gaugingPointsBySketch.AddRange(symmetricGaugingPointsBySketch);
                        }

                        pointsPerSketch.Add(index, gaugingPointsBySketch);
                        index++;

                        #region Compute gauging points in symmetric section

                        List<SteelThicknessGaugingPoint> pointsToBeDeleted = new List<SteelThicknessGaugingPoint>();

                        if (symmetricGaugingPointsBySketch != null && symmetricGaugingPointsBySketch.Count > 0)
                        {
                            #region Clone gauging points only in SB side, to PS side to be renderized in sketch

                            #region Find center plane parallel to X and Z axis

                            BoundingBox sectionBoundingBox = new BoundingBox();
                            BoundingBox symmetricBoundingBox = new BoundingBox();

                            List<Campaign> originalCampaigns = vessel.GetOriginalCampaigns();
                            foreach (Campaign campaign in originalCampaigns)
                            {
                                IList platesInCampaign = section.GetPermanentElementsInCampaign(campaign, true, "Plate");
                                if (platesInCampaign != null && platesInCampaign.Count > 0)
                                {
                                    foreach (Plate plate in platesInCampaign)
                                    {
                                        sectionBoundingBox.Union(plate.Design.Geometry.BoundingBox);
                                    }
                                }

                                platesInCampaign = symmetricSection.GetPermanentElementsInCampaign(campaign, true, "Plate");
                                if (platesInCampaign != null && platesInCampaign.Count > 0)
                                {
                                    foreach (Plate plate in platesInCampaign)
                                    {
                                        symmetricBoundingBox.Union(plate.Design.Geometry.BoundingBox);
                                    }
                                }
                            }

                            BoundingBox boundingBox = new BoundingBox(sectionBoundingBox);
                            boundingBox.Union(symmetricBoundingBox);

                            Plane plane = new Plane(new Vector3D(0, 1, 0), boundingBox.Center);

                            #endregion

                            SortedList<int, List<SteelThicknessGaugingPoint>> sectionOrganizedGaugingPoints = this.OrganizeIACSGaugingPointsByID(sectionGaugingPointsBySketch);
                            foreach (SteelThicknessGaugingPoint symmetricGaugingPoint in symmetricGaugingPointsBySketch)
                            {
                                if (sectionOrganizedGaugingPoints.ContainsKey((int)symmetricGaugingPoint.IACSReportLocationData.ID))
                                {
                                    bool haveSymmetricPoint = false;
                                    foreach (SteelThicknessGaugingPoint symmetricOrganizedGaugingPoint in sectionOrganizedGaugingPoints[(int)symmetricGaugingPoint.IACSReportLocationData.ID])
                                    {
                                        if (symmetricOrganizedGaugingPoint.IACSReportLocationData.IsForward == symmetricGaugingPoint.IACSReportLocationData.IsForward)
                                        {
                                            haveSymmetricPoint = true;
                                            break;
                                        }
                                    }

                                    if (haveSymmetricPoint)
                                    {
                                        continue;
                                    }
                                }

                                Point3D pointPosition = new Point3D(symmetricGaugingPoint.PointGeometry.Position);
                                pointPosition = (Point3D)pointPosition.Mirror(plane);
                                Vector3D pointNormal = new Vector3D(symmetricGaugingPoint.PointGeometry.Normal * -1);

                                int geometryID, geometryPartID;
                                List<string> elementTypeNames = new List<string>();
                                elementTypeNames.Add(symmetricGaugingPoint.TargetElement.GetBaseType().Name);
                                Point3D closestPoint;
                                SectionElement sectionElement = section.PointOverDomainEntity(pointPosition, elementTypeNames, 0.01, out closestPoint, out geometryID, out geometryPartID) as SectionElement;
                                if (sectionElement == null)
                                {
                                    continue;
                                }

                                AverageSteelThicknessGaugingPoint averageSteelThicknessGaugingPoint = new AverageSteelThicknessGaugingPoint();

                                averageSteelThicknessGaugingPoint.PointGeometry.Position = pointPosition;
                                averageSteelThicknessGaugingPoint.PointGeometry.Normal = pointNormal;

                                averageSteelThicknessGaugingPoint.Section = section;
                                averageSteelThicknessGaugingPoint.Campaign = campaignReport.Campaign;
                                averageSteelThicknessGaugingPoint.CampaignReport = campaignReport;
                                averageSteelThicknessGaugingPoint.TargetElement = sectionElement as IWorkableElement;
                                averageSteelThicknessGaugingPoint.TargetElementGeometryID = geometryID;
                                averageSteelThicknessGaugingPoint.TargetElementGeometrySegmentID = geometryPartID;
                                averageSteelThicknessGaugingPoint.TargetElementPart = symmetricGaugingPoint.TargetElementPart;
                                averageSteelThicknessGaugingPoint.Active = true;

                                averageSteelThicknessGaugingPoint.IACSReportLocationData.ID = symmetricGaugingPoint.IACSReportLocationData.ID;
                                averageSteelThicknessGaugingPoint.IACSReportLocationData.SetColumnNull();
                                averageSteelThicknessGaugingPoint.IACSReportLocationData.Strake = symmetricGaugingPoint.IACSReportLocationData.Strake;
                                averageSteelThicknessGaugingPoint.IACSReportLocationData.IsForward = (bool)symmetricGaugingPoint.IACSReportLocationData.IsForward;
                                averageSteelThicknessGaugingPoint.IACSReportLocationData.IsPortSide = !(bool)symmetricGaugingPoint.IACSReportLocationData.IsPortSide;

                                //#if (DEBUG)
                                //newFrontGaugingPoint.Name = ((bool)newFrontGaugingPoint.IACSReportLocationData.IsForward) ? "F " : "B ";
                                //newFrontGaugingPoint.Name += newFrontGaugingPoint.IACSReportLocationData.ID.ToString();
                                //newFrontGaugingPoint.Name += ((bool)newFrontGaugingPoint.IACSReportLocationData.IsPortSide) ? " P " : " S ";
                                //#else
                                averageSteelThicknessGaugingPoint.Name = averageSteelThicknessGaugingPoint.IACSReportLocationData.ID.ToString();
                                //#endif
                                section.AddPermanentDomainEntityToGroup(averageSteelThicknessGaugingPoint, true, false);
                                //section.Vessel.Document.DocumentStateController.BroadcastEntityCreation(this, averageSteelThicknessGaugingPoint);

                                sectionGaugingPointsBySketch.Add(averageSteelThicknessGaugingPoint);
                                pointsToBeDeleted.Add(averageSteelThicknessGaugingPoint);
                            }

                            #endregion
                        }

                        #endregion

                        #region Remove computed gauging points of collections to avoid unnecessary computations

                        int sketchPointsCount = 0;
                        Vector3D sketchNormal = new Vector3D();

                        if (sectionGaugingPointsBySketch != null)
                        {
                            foreach (SteelThicknessGaugingPoint sectionGaugingPointBySketch in sectionGaugingPointsBySketch)
                            {
                                sketchNormal += sectionGaugingPointBySketch.PointGeometry.Normal;

                                if (sectionSteelThicknessGaugingPoints.Contains(sectionGaugingPointBySketch))
                                {
                                    sectionSteelThicknessGaugingPoints.Remove(sectionGaugingPointBySketch);
                                }
                            }

                            sketchPointsCount += sectionGaugingPointsBySketch.Count;
                        }

                        if (symmetricGaugingPointsBySketch != null)
                        {
                            foreach (SteelThicknessGaugingPoint symmetricGaugingPointBySketch in symmetricGaugingPointsBySketch)
                            {
                                sketchNormal += symmetricGaugingPointBySketch.PointGeometry.Normal;

                                if (symmetricSteelThicknessGaugingPoints.Contains(symmetricGaugingPointBySketch))
                                {
                                    symmetricSteelThicknessGaugingPoints.Remove(symmetricGaugingPointBySketch);
                                }
                            }

                            sketchPointsCount += symmetricGaugingPointsBySketch.Count;
                        }

                        sketchNormal /= sketchPointsCount;
                        sketchNormal.Normalize();

                        #endregion

                        if (sectionGaugingPointsBySketch.Count > 0)
                        {
                            List<SectionElement> sectionElements = this.GetSectionElementsVisibleInSketch(section, minPlane, maxPlane, sectionGaugingPointsBySketch, sketchNormal);

                            // Generate thumbnail
                            section.SectionDrawer.ConfigureView(this.glPanel, section.GetDefaultView(), true);
                            section.SectionDrawer.UpdateLastCamera(this.glPanel);

                            Bitmap thumbnail = new Bitmap(originalThumbnail, originalThumbnail.Width, originalThumbnail.Height);

                            Rectangle rectangle = this.GetRectangleOfRenderizedArea(sectionElements);
                            for (int j = 0; j < thumbnail.Width; j++)
                            {
                                for (int k = 0; k < thumbnail.Height; k++)
                                {
                                    if (this.IsPixelOfRectangle(j, k, rectangle, 3))
                                    {
                                        thumbnail.SetPixel(j, k, Color.Red);
                                    }
                                }
                            }

                            string thumbName = thumbnail.RawFormat.Guid.ToString() + "-" + this.bitmapCount.ToString() + ".jpg";
                            this.bitmapCount++;

                            thumbName = document.HDF5DataAccessController.SaveBitmap(thumbnail, thumbName);
                            bitmaps.Add(thumbName);

                            C4DView view = section.SectionDrawer.ComputeViewForSectionElements(this.glPanel, sectionElements, false, 1.2f, true);
                            if (view == null)
                            {
                                view = section.GetDefaultView();
                            }

                            section.SectionDrawer.ConfigureView(this.glPanel, view, false);
                            section.SectionDrawer.UpdateLastCamera(this.glPanel);

                            List<int> gaugingPointIDs = new List<int>();
                            foreach (SteelThicknessGaugingPoint steelThicknessGaugingPoint in sectionGaugingPointsBySketch)
                            {
                                gaugingPointIDs.Add(steelThicknessGaugingPoint.ID);
                            }

                            section.SectionDrawer.SetPriorityVisibleElements("SteelThicknessGaugingPoint", gaugingPointIDs);

                            Bitmap bitmap = section.SectionDrawer.DrawModelImmediateModeCuttingOfCompartment(this.glPanel);

                            section.SectionDrawer.ClearPriorityVisibleElements("SteelThicknessGaugingPoint");

                            string bitmapName = bitmap.RawFormat.Guid.ToString() + "-" + this.bitmapCount.ToString() + ".jpg";
                            this.bitmapCount++;

                            bitmapName = document.HDF5DataAccessController.SaveBitmap(bitmap, bitmapName);
                            bitmaps.Add(bitmapName);

                            bitmap.Dispose();
                        }

                        foreach (SteelThicknessGaugingPoint pointToBeDeleted in pointsToBeDeleted)
                        {
                            document.DeleteSectionElement(pointToBeDeleted, false);
                        }
                    }
                }

                section.SectionDrawer.CurrentViewModeName = sectionDrawerCurrentViewModeName;

                return bitmaps;
            }
            catch (Exception ex)
            {
                throw new ApplicationException("Sketch for section/campaign report cannot be created!", ex);
            }
        }
        private int DefineInitialIACSID(Section section)
        {
            int initialID = 0;

            IList steelThicknessGaugingPointsInCampaign = null;
            //section.GetPermanentElementsInCampaign(this.iacsCampaign, false, "SteelThicknessGaugingPoint");
            section.GetPermanentElementsInCampaign(this.averageCampaign, false, "SteelThicknessGaugingPoint");

            if (steelThicknessGaugingPointsInCampaign != null && steelThicknessGaugingPointsInCampaign.Count > 0)
            {
                foreach (SteelThicknessGaugingPoint steelThicknessGaugingPoint in steelThicknessGaugingPointsInCampaign)
                {
                    if (!steelThicknessGaugingPoint.IACSReportLocationData.IsIDNull && steelThicknessGaugingPoint.IACSReportLocationData.ID > initialID)
                    {
                        initialID = steelThicknessGaugingPoint.IACSReportLocationData.ID;
                    }
                }
            }

            return initialID;
        }