public static bool EditFFLValue(ObjectId fflToEditId, double level) { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument; Database acCurrDb = acDoc.Database; Editor acEditor = acDoc.Editor; using (Transaction acTrans = acCurrDb.TransactionManager.StartTransaction()) { try { // Prompt user for new FFL double?newFFL = 0.0; // Declare here to ensure in scope for later BlockTable acBlkTbl = acTrans.GetObject(acCurrDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockReference fflBlock = acTrans.GetObject(fflToEditId, OpenMode.ForRead) as BlockReference; BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[fflBlock.Name], OpenMode.ForWrite) as BlockTableRecord; if (acBlkTblRec == null) { acEditor.WriteMessage("\nError FFL block not found."); return(false); } // Check there is only one instance of this block reference in the drawing if (acBlkTblRec.GetBlockReferenceIds(false, true).Count != 1) { acEditor.WriteMessage("\nError more than one instance of the block reference."); return(false); } // Iterate around the object collection to find the polyline to retrieve the current FFL value newFFL = level; double?fflDiff = 0.0; foreach (ObjectId objId in acBlkTblRec) { // Fetch the object Object fflObj = acTrans.GetObject(objId, OpenMode.ForWrite); double?currFFL = 0.0; if (fflObj.GetType() == typeof(Polyline)) { Polyline acPline = fflObj as Polyline; // Check the outline has an extension dictionary DBDictionary acExtDict = (DBDictionary)acTrans.GetObject(acPline.ExtensionDictionary, OpenMode.ForRead); if (acExtDict == null) { acEditor.WriteMessage("\nError cannot retrieve the extension dictionary of polyline."); return(false); } currFFL = JPPUtils.getFFL(acPline.Id); if (currFFL == null) { acEditor.WriteMessage("\nError retrieving current FFL value."); return(false); } fflDiff = newFFL - currFFL; // Update FFL Xrecord ResultBuffer resBuff = new ResultBuffer(); resBuff.Add(new TypedValue((int)DxfCode.ExtendedDataReal, newFFL)); // Overwrite the Xrecord with new data if (!JPPUtils.addXrecord(objId, "FFL", resBuff)) { acEditor.WriteMessage("\nError updating Xrecord with new FFL value."); return(false); } // Update the levels Xrecords to reflect the new ffl for (int vertexIndex = 0; vertexIndex < acPline.NumberOfVertices; vertexIndex++) { // Access Xrecord for the vertex and update the level value ObjectId vertexXrecId = acExtDict.GetAt("Vertex_" + vertexIndex.ToString()); if (vertexXrecId == null) { acEditor.WriteMessage("\nError cannot retrieve vertex Xrecord"); acTrans.Abort(); return(false); } Xrecord vertexXrec = acTrans.GetObject(vertexXrecId, OpenMode.ForWrite) as Xrecord; TypedValue[] vertexXrecData = vertexXrec.Data.AsArray(); // Get the current level double currLevel = Convert.ToDouble(vertexXrecData[3].Value); ResultBuffer newXrecData = new ResultBuffer(); newXrecData.Add(vertexXrecData[0]); newXrecData.Add(vertexXrecData[1]); newXrecData.Add(vertexXrecData[2]); newXrecData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, currLevel + fflDiff)); // Overwrite the data in the Xrecord with new data vertexXrec.Data = newXrecData; } break; } } // Iterate around the MText objects of the block to update the FFL text and // levels text foreach (ObjectId objId in acBlkTblRec) { // Fetch the object Object fflObj = acTrans.GetObject(objId, OpenMode.ForWrite); if (fflObj.GetType() == typeof(MText)) { MText fflMText = (MText)fflObj; if (fflMText.Text.StartsWith("FFL")) { double dblNewFFL = (double)newFFL; fflMText.Contents = "FFL " + dblNewFFL.ToString("N3"); } else { double currLevel = Convert.ToDouble(fflMText.Contents); double newLevel = currLevel + (double)fflDiff; fflMText.Contents = newLevel.ToString("N3"); } } } // Update the graphics fflBlock.UpgradeOpen(); fflBlock.RecordGraphicsModified(true); acTrans.Commit(); return(true); } catch (Autodesk.AutoCAD.Runtime.Exception acException) { Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog ("The following exception was caught: \n" + acException.Message + "\nError editing FFL value!\n"); return(false); } } // return true; }
private static bool addAccessPoint(Point3d accessPoint, ObjectId dbObjectId, string level) { Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument; Database acCurrDb = acDoc.Database; Editor acEditor = acDoc.Editor; using (Transaction acTrans = acCurrDb.TransactionManager.StartTransaction()) { // Add the access point to the 'buildingOutline' polyline by iterating around the polyline // comparing the distance of each vertex from the start point to the distance of new // point form the start point. When the new point distance is less than the current // vertex add the new point. // // NOTE: this requires that the newpoint lies on the 'buildingOutline' polyline. // try { int accessPointIndex = 0; // Fetch the polyline Polyline buildingOutline = acTrans.GetObject(dbObjectId, OpenMode.ForWrite) as Polyline; for (int index = 0; index <= buildingOutline.NumberOfVertices; index++) { // Check whether index is equal to the number of vertices. If it is the access // point is lies on the segment from the last point of the building outline to the // first point of the building outline so compare the distance to the new point against // the length of the building outline if (index == buildingOutline.NumberOfVertices) { if (buildingOutline.GetDistAtPoint(accessPoint) < buildingOutline.Length) { buildingOutline.AddVertexAt(index, new Point2d(accessPoint.X, accessPoint.Y), 0, 0, 0); accessPointIndex = index; break; // Make sure loop is not executed again } else { // Error condition } } // Else check distance along polyline of new point against each vertex (corner) to find // segment of outline where access point lies. else { if (buildingOutline.GetDistAtPoint(accessPoint) < buildingOutline.GetDistAtPoint(buildingOutline.GetPoint3dAt(index))) { buildingOutline.AddVertexAt(index, new Point2d(accessPoint.X, accessPoint.Y), 0, 0, 0); accessPointIndex = index; break; // Found segment to add } } } // SHOULD add a check in the above to trap case where the added point is a corner. Check with JPP on how to handle this. // Now have the index of the new vertex so update the Xrecord name for each vertex beyond the added // vertex before adding Xrecord for new vertex. First check that new vertex doesn't lie between the // first and last vertices // if (accessPointIndex < buildingOutline.NumberOfVertices - 2) // Not the last vertex if (accessPointIndex < buildingOutline.NumberOfVertices - 1) // Not the last vertex { // Update name Xrecords for those beyond the new vertex for (int index = buildingOutline.NumberOfVertices - 1; index > accessPointIndex; index--) { string newKey = "Vertex_" + index.ToString(); string oldKey = "Vertex_" + (index - 1).ToString(); bool accessPointAdded = JPPUtils.renameXrecord(dbObjectId, oldKey, newKey, true); } } // Fetch the FFL double to calculte value of level // Add the new Xrecord ResultBuffer xrecVertexData = new ResultBuffer(); xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataInteger16, accessPointIndex)); xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "Access_Point")); xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, level)); // Need to calculate the actual level and therefore need the FFL double?FFLDouble = JPPUtils.getFFL(dbObjectId); // Add the level based on the FFL and whether the access point is at FFL or 150mm below FFL if (level == "At_FFL") { xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, FFLDouble)); } else { xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, (FFLDouble - 0.15))); } bool success = JPPUtils.addXrecord(dbObjectId, ("Vertex_" + accessPointIndex.ToString()), xrecVertexData); acTrans.Commit(); return(true); } catch (Autodesk.AutoCAD.Runtime.Exception acException) { Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog ("The following exception was caught: \n" + acException.Message + "\nError adding access point!\n"); acTrans.Commit(); return(false); } } }