internal void InvokeGraphRedrawn(int lineId, Color visibleColor)
        {
            _profileSession.Segments.First(segment => segment.LineId == lineId).VisibleColor = ColorToEsriRgb(visibleColor);

            InvisibleZonesChanged?.Invoke(_profileSession.Segments.First(segment => segment.LineId == lineId),
                                          _profileSession.SessionId, true);
        }
        internal void AddInvisibleZone(double observerHeight, ProfileSurface profileSurface,
                                       Color visibleColor, Color invisibleColor, bool update = true,
                                       List <int> linesIds = null)
        {
            var invisibleSurface       = new ProfileSurface();
            var invisibleSurfacePoints = new List <ProfileSurfacePoint>();
            var groupedLinesSegments   = new List <ProfileLine>();
            var isPrimitive            = true;
            var surfaceSegments        = GetLineSegments(profileSurface.LineId);

            if (surfaceSegments == null)
            {
                surfaceSegments = new List <ProfileSurface> {
                    profileSurface
                };
                isPrimitive = false;
            }

            foreach (var segment in surfaceSegments)
            {
                var firstPointDistance      = segment.ProfileSurfacePoints[0].Distance;
                var sightLineKoef           = 0.0;
                var isInvisibleZone         = false;
                var observerFullHeight      = observerHeight + segment.ProfileSurfacePoints[0].Z;
                var invisibleSurfaceSegment = new ProfileSurface();
                var invisiblePoints         = new List <ProfileSurfacePoint>();

                invisibleSurfaceSegment.LineId = profileSurface.LineId;

                for (var i = 0; i < segment.ProfileSurfacePoints.Length; i++)
                {
                    var currPoint = segment.ProfileSurfacePoints[i];
                    if (!isInvisibleZone)
                    {
                        if (i < segment.ProfileSurfacePoints.Length - 1)
                        {
                            if (CalcAngleOfVisibility(observerFullHeight, segment.ProfileSurfacePoints[i],
                                                      segment.ProfileSurfacePoints[i + 1], firstPointDistance) < 0)
                            {
                                var firstInvisiblePoint = segment.ProfileSurfacePoints[i + 1];

                                if (!invisiblePoints.Exists(point => point == firstInvisiblePoint))
                                {
                                    invisiblePoints.Add(firstInvisiblePoint);
                                }

                                isInvisibleZone = true;
                                sightLineKoef   = (firstInvisiblePoint.Z - observerFullHeight) / (firstInvisiblePoint.Distance - firstPointDistance);
                                i++;
                            }
                        }
                    }
                    else
                    {
                        if (FindY(observerFullHeight, sightLineKoef, segment.ProfileSurfacePoints[i].Distance - firstPointDistance)
                            < segment.ProfileSurfacePoints[i].Z)
                        {
                            isInvisibleZone = false;
                            invisiblePoints.Add(segment.ProfileSurfacePoints[i]);

                            i++;
                        }
                        else
                        {
                            invisiblePoints.Add(segment.ProfileSurfacePoints[i]);
                        }
                    }

                    currPoint.Visible = !isInvisibleZone;
                }

                invisibleSurfaceSegment.ProfileSurfacePoints = invisiblePoints.ToArray();
                groupedLinesSegments.AddRange(GetLines(segment, invisibleSurfaceSegment, _profileSession.SessionId));

                invisibleSurfacePoints.AddRange(invisiblePoints);
            }

            invisibleSurface.ProfileSurfacePoints = invisibleSurfacePoints.ToArray();
            invisibleSurface.LineId = profileSurface.LineId;

            _surfaceProfileChart.AddInvisibleLine(invisibleSurface);
            CalcProfilesVisiblePercents(invisibleSurface, profileSurface);

            var profileLines = new GroupedLines
            {
                LineId         = profileSurface.LineId,
                Lines          = groupedLinesSegments,
                VisibleColor   = ColorToEsriRgb(visibleColor),
                InvisibleColor = ColorToEsriRgb(invisibleColor)
            };

            profileLines.Polylines = ProfileLinesConverter
                                     .ConvertLineToEsriPolyline(profileLines.Lines,
                                                                ArcMap.Document.FocusMap.SpatialReference);
            if (isPrimitive)
            {
                var spatialReference = _profileSession.ProfileLines.First(line => line.Id == profileLines.LineId).SpatialReference;
                profileLines.Vertices = surfaceSegments.Select(surface =>
                {
                    var point = surface.ProfileSurfacePoints.First();

                    return(new ProfilePoint {
                        X = point.X, Y = point.Y, SpatialReference = spatialReference
                    });
                }
                                                               ).ToList();

                profileLines.IsPrimitive = true;
            }

            if (_profileSession.Segments.Count < profileSurface.LineId - 1)
            {
                _profileSession.Segments.Add(profileLines);
            }
            else
            {
                profileLines.IsSelected = _profileSession.Segments[profileSurface.LineId - 1].IsSelected;
                _profileSession.Segments[profileSurface.LineId - 1] = profileLines;
            }

            InvisibleZonesChanged?.Invoke(profileLines, _profileSession.SessionId, update, linesIds);
        }