/// <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); }
/// <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; }
/// <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> /// 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); } }
/// <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> /// 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; }