/// <summary>
        /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class
        /// using the data read from persistent storage.
        /// </summary>
        /// <param name="editDeserializer">The mechanism for reading back content.</param>
        internal LineSubdivisionOperation(EditDeserializer editDeserializer)
            : base(editDeserializer)
        {
            m_Line = editDeserializer.ReadFeatureRef <LineFeature>(DataField.Line);
            m_Face = editDeserializer.ReadPersistent <LineSubdivisionFace>(DataField.Face);
            //FeatureStub[] sections = editDeserializer.ReadFeatureStubArray(DataField.Result);

            if (editDeserializer.IsNextField(DataField.OtherSide))
            {
                InternalIdValue id = editDeserializer.ReadInternalId(DataField.OtherSide);
                OtherSide = (LineSubdivisionOperation)editDeserializer.MapModel.FindOperation(id);
                Debug.Assert(OtherSide != null);
                OtherSide.OtherSide = this;
            }

            Project p         = editDeserializer.Project;
            IEntity pointType = editDeserializer.ReadEntity(DataField.PointType);

            FeatureStub[] sections = CreateStubs(p, pointType, m_Line.EntityType);

            DeserializationFactory result = new DeserializationFactory(this, sections);

            ProcessFeatures(result);

            // Apply any IDs
            if (editDeserializer.IsNextField(DataField.Ids))
            {
                editDeserializer.ReadIdMappings(DataField.Ids);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class
        /// using the data read from persistent storage.
        /// </summary>
        /// <param name="editDeserializer">The mechanism for reading back content.</param>
        internal LineSubdivisionOperation(EditDeserializer editDeserializer)
            : base(editDeserializer)
        {
            m_Line = editDeserializer.ReadFeatureRef<LineFeature>(DataField.Line);
            m_Face = editDeserializer.ReadPersistent<LineSubdivisionFace>(DataField.Face);
            //FeatureStub[] sections = editDeserializer.ReadFeatureStubArray(DataField.Result);

            if (editDeserializer.IsNextField(DataField.OtherSide))
            {
                InternalIdValue id = editDeserializer.ReadInternalId(DataField.OtherSide);
                OtherSide = (LineSubdivisionOperation)editDeserializer.MapModel.FindOperation(id);
                Debug.Assert(OtherSide != null);
                OtherSide.OtherSide = this;
            }

            Project p = editDeserializer.Project;
            IEntity pointType = editDeserializer.ReadEntity(DataField.PointType);
            FeatureStub[] sections = CreateStubs(p, pointType, m_Line.EntityType);

            DeserializationFactory result = new DeserializationFactory(this, sections);
            ProcessFeatures(result);

            // Apply any IDs
            if (editDeserializer.IsNextField(DataField.Ids))
                editDeserializer.ReadIdMappings(DataField.Ids);
        }
        /// <summary>
        /// Obtains update items for a revised version of this edit
        /// (for later use with <see cref="ExchangeData"/> and <see cref="WriteUpdateItems"/>).
        /// </summary>
        /// <param name="face">The revised observed lengths for each subdivision section</param>
        /// <returns>The items representing the change (may be subsequently supplied to
        /// the <see cref="ExchangeUpdateItems"/> method). Never null, but may be an empty collection
        /// if the supplied face does not involve any changes.</returns>
        internal UpdateItemCollection GetUpdateItems(LineSubdivisionFace face)
        {
            UpdateItemCollection result = new UpdateItemCollection();

            if (!m_Face.HasIdenticalObservedLengths(face))
            {
                result.Add(m_Face.GetUpdateItem(DataField.Face, face.ObservedLengths));
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Checks whether this face has identical observed lengths for each section.
        /// </summary>
        /// <param name="that">The face to compare with</param>
        /// <returns>True if this face is identical to the supplied face</returns>
        internal bool HasIdenticalObservedLengths(LineSubdivisionFace that)
        {
            if (this.m_Distances.Length != that.m_Distances.Length)
            {
                return(false);
            }

            for (int i = 0; i < this.m_Distances.Length; i++)
            {
                Distance dThis = this.m_Distances[i];
                Distance dThat = that.m_Distances[i];

                if (!dThis.IsIdentical(dThat))
                {
                    return(false);
                }
            }

            return(true);
        }
        private void newFaceButton_Click(object sender, EventArgs e)
        {
            // If we previously highlighted something, draw it normally (since it cannot exist as part of any other face).
            m_SelectedLine = null;

            // If a second face doesn't already exist, get the user to specify the distances.

            if (m_Face2 == null)
            {
                try
                {
                    this.WindowState = FormWindowState.Minimized;

                    // Get the distance observations

                    using (LegForm dial = new LegForm(GetObservedLength()))
                    {
                        if (dial.ShowDialog() != DialogResult.OK)
                            return;

                        // Must be at least two distances
                        Distance[] dists = dial.Distances;
                        if (dists == null || dists.Length < 2)
                        {
                            MessageBox.Show("The new face must have at least two spans");
                            return;
                        }

                        // Default annotations to the flip side
                        foreach (Distance d in dists)
                            d.IsAnnotationFlipped = true;

                        // Create the new face (for use in preview only)
                        m_Face2 = new LineSubdivisionFace(dists, m_Face1.IsEntryFromEnd);
                        InitializeWorkingFace(m_Face2, false);

                        newFaceButton.Text = "&Other Face";
                    }
                }

                finally
                {
                    this.WindowState = FormWindowState.Normal;
                }
            }

            // Switch to the other face (possibly the one just added)

            if (m_CurrentFace == m_Face1)
                m_CurrentFace = m_Face2;
            else
                m_CurrentFace = m_Face1;

            RefreshList();
        }
        private void LineSubdivisionUpdateForm_Shown(object sender, EventArgs e)
        {
            // Get the object that was selected for update.
            Feature feat = m_UpdCmd.GetUpdate();
            if (feat == null)
                throw new InvalidOperationException("Unexpected update object");

            // Get the edit that created the primary face
            m_pop = (feat.Creator as LineSubdivisionOperation);
            Debug.Assert(m_pop != null);

            if (!m_pop.IsPrimaryFace)
            {
                m_pop = m_pop.OtherSide;
                Debug.Assert(m_pop != null);
                Debug.Assert(m_pop.IsPrimaryFace);
            }

            // Grab something we throw away if the user decides to cancel
            m_Face1 = CreateWorkingFace(m_pop.Face, true);
            m_Face2 = (m_pop.OtherSide == null ? null : CreateWorkingFace(m_pop.OtherSide.Face, false));

            // If we have two faces, the "New Face" button means you want to switch to the other face.
            if (m_Face2 != null)
                newFaceButton.Text = "&Other Face";

            // Default to the face containing the initially selected feature
            m_CurrentFace = (feat.Creator == m_pop ? m_Face1 : m_Face2);

            // If a line was selected, remember where it is in our working copy (and if it's actually on
            // the alternate face, make that the initial face for editing).
            m_SelectedLine = null;
            LineFeature selectedLine = (feat as LineFeature);
            if (selectedLine != null)
            {
                LineFeature[] sections = (m_CurrentFace == m_Face1 ? m_pop.Face.Sections : m_pop.OtherSide.Face.Sections);
                int lineIndex = Array.FindIndex<LineFeature>(sections, t => t == selectedLine);

                if (lineIndex >= 0)
                    m_SelectedLine = m_CurrentFace.Sections[lineIndex];
            }

            // Disable the option to flip annotation if annotation is currently invisible
            if (!EditingController.Current.AreLineAnnotationsDrawn)
                flipDistButton.Enabled = false;

            // Reload the list and repaint
            RefreshList();
        }
        /// <summary>
        /// Initialize the sections for a working copy of a subdivision face.
        /// </summary>
        /// <param name="face">A transient face to create sections for</param>
        /// <param name="isPrimaryFace">Is the specified face the primary face?</param>
        void InitializeWorkingFace(LineSubdivisionFace face, bool isPrimaryFace)
        {
            // Create throwaway line sections (without any feature IDs, not associated with any session,
            // not in spatial index).
            FeatureFactory ff = new ThrowawayFeatureFactory(m_pop);
            ff.LineType = m_pop.Parent.EntityType;
            face.CreateSections(m_pop.Parent, ff, isPrimaryFace);

            // And calculate initial geometry
            face.CalculateGeometry(m_pop.Parent, null);
        }
        /// <summary>
        /// Creates a working copy of an existing face.
        /// </summary>
        /// <param name="face">The face to copy</param>
        /// <param name="isPrimaryFace">Is the specified face the primary face?</param>
        /// <returns>The working copy</returns>
        LineSubdivisionFace CreateWorkingFace(LineSubdivisionFace face, bool isPrimaryFace)
        {
            if (face == null)
                return null;

            // Make a copy of the distance observations from the source face
            Distance[] distances = CopyDistances(face);
            LineSubdivisionFace result = new LineSubdivisionFace(distances, face.IsEntryFromEnd);

            // Create sections and calculate geometry
            InitializeWorkingFace(result, isPrimaryFace);
            return result;
        }
        /// <summary>
        /// Obtains the distances for one subdivision face (along with a note as
        /// to whether the annotation has been flipped or not).
        /// </summary>
        /// <param name="face">The face of interest (may be null)</param>
        /// <returns>A copy of the distances along the face (null if the supplied face is null).</returns>
        Distance[] CopyDistances(LineSubdivisionFace face)
        {
            if (face == null)
                return null;

            Distance[] current = face.ObservedLengths;
            Distance[] result = new Distance[current.Length];

            for (int i = 0; i < result.Length; i++)
                result[i] = new Distance(current[i]);

            return result;
        }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class.
 /// </summary>
 /// <param name="line">The line that is being subdivided.</param>
 /// <param name="distances">The lengths for each subdivision section.</param>
 /// <param name="isEntryFromEnd">Are the distances observed from the end of the line?</param>
 internal LineSubdivisionOperation(LineFeature line, Distance[] distances, bool isEntryFromEnd)
     : base()
 {
     m_Line = line;
     m_Face = new LineSubdivisionFace(distances, isEntryFromEnd);
 }
예제 #11
0
        /// <summary>
        /// Saves a new edit that defines an alternate face for a previously subdivided line.
        /// </summary>
        /// <param name="firstSide">The edit that initially subdivided the line.</param>
        /// <param name="altFace">The definition of the alternate face</param>
        void AddOtherSide(LineSubdivisionOperation firstSide, LineSubdivisionFace altFace)
        {
            try
            {
                LineSubdivisionOperation op = new LineSubdivisionOperation(firstSide.Parent, altFace.ObservedLengths, altFace.IsEntryFromEnd);
                op.OtherSide = firstSide;
                op.Execute();
                firstSide.OtherSide = op;
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message);
            }
        }
예제 #12
0
        /// <summary>
        /// Checks whether this face has identical observed lengths for each section.
        /// </summary>
        /// <param name="that">The face to compare with</param>
        /// <returns>True if this face is identical to the supplied face</returns>
        internal bool HasIdenticalObservedLengths(LineSubdivisionFace that)
        {
            if (this.m_Distances.Length != that.m_Distances.Length)
                return false;

            for (int i = 0; i < this.m_Distances.Length; i++)
            {
                Distance dThis = this.m_Distances[i];
                Distance dThat = that.m_Distances[i];

                if (!dThis.IsIdentical(dThat))
                    return false;
            }

            return true;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="LineSubdivisionOperation"/> class.
 /// </summary>
 /// <param name="line">The line that is being subdivided.</param>
 /// <param name="distances">The lengths for each subdivision section.</param>
 /// <param name="isEntryFromEnd">Are the distances observed from the end of the line?</param>
 internal LineSubdivisionOperation(LineFeature line, Distance[] distances, bool isEntryFromEnd)
     : base()
 {
     m_Line = line;
     m_Face = new LineSubdivisionFace(distances, isEntryFromEnd);
 }
        /// <summary>
        /// Obtains update items for a revised version of this edit
        /// (for later use with <see cref="ExchangeData"/> and <see cref="WriteUpdateItems"/>).
        /// </summary>
        /// <param name="face">The revised observed lengths for each subdivision section</param>
        /// <returns>The items representing the change (may be subsequently supplied to
        /// the <see cref="ExchangeUpdateItems"/> method). Never null, but may be an empty collection
        /// if the supplied face does not involve any changes.</returns>
        internal UpdateItemCollection GetUpdateItems(LineSubdivisionFace face)
        {
            UpdateItemCollection result = new UpdateItemCollection();

            if (!m_Face.HasIdenticalObservedLengths(face))
                result.Add(m_Face.GetUpdateItem(DataField.Face, face.ObservedLengths));

            return result;
        }