private static bool IsAccessPoint(Polyline acPline, int index)
        {
            Document acDoc    = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database acCurrDb = acDoc.Database;
            Editor   acEditor = acDoc.Editor;

            try
            {
                DBDictionary outlineExtDict = JPPUtils.getOutlineExtensionDictionary(acPline);

                // Retrieve the Xrecord
                ResultBuffer rbLevel  = JPPUtils.getXrecord(outlineExtDict.Id, "Vertex_" + index.ToString());
                TypedValue[] xrecData = rbLevel.AsArray();
                if (xrecData[1].Value.ToString() == "Access_Point")
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acException)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog
                    ("The following exception was caught: \n" + acException.Message
                    + "\nError checking for access point\n");
                return(true);
            }
        }
Exemple #2
0
        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 Brickwork(bool exposed, ObjectId fflBlockId)
        {
            Document acDoc    = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database acCurrDb = acDoc.Database;
            Editor   acEditor = acDoc.Editor;

            // Find the outline polyline object
            Polyline outline = FetchOutline(fflBlockId);

            if (outline == null)
            {
                acEditor.WriteMessage("\nError, unable to retrieve FFL Block ID!");
                return(false);
            }

            // Retrieve the extension dictionary for the outline

            DBDictionary blockOutlineExtDict = JPPUtils.getOutlineExtensionDictionary(outline);

            if (blockOutlineExtDict == null)
            {
                acEditor.WriteMessage("\nError, unable to retrieve extension dictionary of outline!");
                return(false);
            }
            // Retrieve the level at each vertex from the Xrecords in the outline extenstion dictionary
            double[] levels = new double[outline.NumberOfVertices];        // Array to store the levels
            for (int index = 0; index < outline.NumberOfVertices; index++)
            {
                ResultBuffer rbLevel  = JPPUtils.getXrecord(blockOutlineExtDict.Id, "Vertex_" + index.ToString());
                TypedValue[] xrecData = rbLevel.AsArray();
                levels[index] = Convert.ToDouble(xrecData[3].Value);
            }

            // Retrieve the FFL
            ResultBuffer rbFFL = JPPUtils.getXrecord(blockOutlineExtDict.Id, "FFL");
            double       FFL   = Convert.ToDouble(rbFFL.AsArray()[0].Value);

            // Create the offset polyline
            DBObjectCollection offsetOutlineObjects = outline.GetOffsetCurves(0.300);

            if ((offsetOutlineObjects.Count != 1) || (offsetOutlineObjects[0].GetType() != typeof(Polyline)))
            {
                acEditor.WriteMessage("\nError, unable to create offset outline!");
                return(false);
            }
            Polyline offsetOutline = offsetOutlineObjects[0] as Polyline;

            // For each vertex of the outline polyline check the level against the FFL. If it is
            // less the FFL - 0.15 then there is exposed brickwork, if it is greater than FFL - 0.015
            // tanking is required.
            // At the first occurence the coordinates of the previous vertex need to be saved
            double threshold   = FFL - 0.15;
            int    startVertex = 0;

            // Check if the level of vertex 0 is above of below threshold. If it is iterate anticlockwise
            // around the outline until a vertex with a level at the threshold is found. This
            // defines the start point to work round the outline.
            if ((levels[startVertex] < threshold) || (levels[startVertex] > FFL))
            {
                for (int index = outline.NumberOfVertices - 1; index >= 0; index--)
                {
                    if ((levels[index] > threshold) || (levels[index] < threshold))
                    {
                        // Found the start point for this run of exposed or tanked brickwork
                        startVertex = index;
                        break;
                    }
                }
            }
            Point2dCollection hatchBoundaryPoints = new Point2dCollection();
            Point2dCollection offsetVertices      = new Point2dCollection();
            List <int>        cornerTextIndex     = new List <int>();
            bool creatingHatchBoundary            = false;

            for (int index = 0; index < outline.NumberOfVertices; index++)
            {
                int vertexIndex;
                if (index < (outline.NumberOfVertices - startVertex))
                {
                    vertexIndex = index + startVertex;
                }
                else
                {
                    vertexIndex = index - (outline.NumberOfVertices - startVertex);
                }
                if ((exposed && levels[vertexIndex] < threshold) ||
                    (!exposed && (!IsAccessPoint(outline, vertexIndex)) && levels[vertexIndex] > threshold))
                {
                    if (hatchBoundaryPoints.Count == 0)           // First vertex above or below the threshold
                    {
                        // First point of the hatch boundary will be the previous vertex.
                        // Also, check to see if vertex is an access point. If it is then the hatch boundary point needs to be moved
                        // to accommodate this. It is assumed the access point will be 900mm wide.
                        Point2d firstVertex = new Point2d();
                        if (vertexIndex == 0)
                        {
                            firstVertex = CheckForAccessPoint(outline, outline.NumberOfVertices - 1, true);
                        }
                        else
                        {
                            firstVertex = CheckForAccessPoint(outline, vertexIndex - 1, true);
                        }
                        hatchBoundaryPoints.Add(firstVertex);
                        creatingHatchBoundary = true;
                    }
                    hatchBoundaryPoints.Add(outline.GetPoint2dAt(vertexIndex));
                    offsetVertices.Add(offsetOutline.GetPoint2dAt(vertexIndex));
                    // Check if this vertex is a corner by comparing the angle of the 1st vector and 2nd vector
                    if (IsCorner(outline, vertexIndex))
                    {
                        cornerTextIndex.Add(vertexIndex);
                        cornerTextIndex.Add(Convert.ToInt32(Math.Ceiling((threshold - levels[vertexIndex]) / 0.075)));
                    }
                }
                else if (creatingHatchBoundary)                  // At the end of an exposed brickwork run
                {
                    Point2d lastVertex = CheckForAccessPoint(outline, vertexIndex, false);
                    hatchBoundaryPoints.Add(lastVertex);
                    // offsetVertices.Add(offsetPLine.GetPoint2dAt(vertexIndex));
                    // Now need to close the hatch boundary
                    for (int index2 = offsetVertices.Count - 1; index2 >= 0; index2--)
                    {
                        hatchBoundaryPoints.Add(offsetVertices[index2]);
                    }
                    // Call the function to add the hatch
                    if (!AddHatch(hatchBoundaryPoints, fflBlockId, exposed))
                    {
                        acEditor.WriteMessage("\nError, unable to exposed brick or tanking hatch!");
                        return(false);
                    }
                    // Call function to add text
                    if (!AddCourseText(cornerTextIndex, offsetOutline, fflBlockId, exposed))
                    {
                        acEditor.WriteMessage("\nError, unable to exposed brick or tanking text!");
                        return(false);
                    }
                    hatchBoundaryPoints.Clear();
                    offsetVertices.Clear();
                    cornerTextIndex.Clear();
                    creatingHatchBoundary = false;
                }
            }
            return(true);
        }
        private static Point2d CheckForAccessPoint(Polyline acPline, int index, bool atStart)
        {
            Document acDoc    = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
            Database acCurrDb = acDoc.Database;
            Editor   acEditor = acDoc.Editor;

            int     nextVertexIndex     = 0;
            int     previousVertexIndex = 0;
            Point2d newPoint            = new Point2d();

            try
            {
                // This function determines whether the point passed to the function is an access point; if it
                // is then an offset to allow for the access point opening is calculated and the offset point coordinates
                // returned. The direction of the offset is applied in depends on whether this is the start or end
                // of the hatch boundary.
                // If it's the start of the hatch boundary the offset is applied in the direction of the vector from
                // this point to the next vertex.
                // If it's the end of the hatch boundary the offset is applied in the direction of a vector from this
                // to the previous point.
                // First check if point is an access point as there's nothing to do if not.
                // Fetch the extension dictionary
                DBDictionary outlineExtDict = JPPUtils.getOutlineExtensionDictionary(acPline);

                // Retrieve the Xrecord
                ResultBuffer rbLevel  = JPPUtils.getXrecord(outlineExtDict.Id, "Vertex_" + index.ToString());
                TypedValue[] xrecData = rbLevel.AsArray();
                if (xrecData[1].Value.ToString() != "Access_Point")
                {
                    return(newPoint = acPline.GetPoint2dAt(index));
                }

                // First check if the point is the first vertex of the outline previous or next vertex index.

                if (atStart)
                {
                    if (index == acPline.NumberOfVertices - 1)
                    {
                        nextVertexIndex = 0;
                    }
                    else
                    {
                        nextVertexIndex = index + 1;
                    }
                    // Calculate new point based on the vector angle
                    double vectorAngle = acPline.GetPoint2dAt(index).GetVectorTo(acPline.GetPoint2dAt(nextVertexIndex)).Angle;
                    newPoint = new Point2d(acPline.GetPoint2dAt(index).X + (Constants.Access_Point_Width / 2) * Math.Cos(vectorAngle),
                                           acPline.GetPoint2dAt(index).Y + (Constants.Access_Point_Width / 2) * Math.Sin(vectorAngle));
                }
                else
                {
                    if (index == 0)
                    {
                        previousVertexIndex = acPline.NumberOfVertices - 1;
                    }
                    else
                    {
                        previousVertexIndex = index - 1;
                    }
                    // Calculate new point based on the vector angle
                    double vectorAngle = acPline.GetPoint2dAt(previousVertexIndex).GetVectorTo(acPline.GetPoint2dAt(index)).Angle;
                    newPoint = new Point2d(acPline.GetPoint2dAt(index).X - (Constants.Access_Point_Width / 2) * Math.Cos(vectorAngle),
                                           acPline.GetPoint2dAt(index).Y - (Constants.Access_Point_Width / 2) * Math.Sin(vectorAngle));
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acException)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog
                    ("The following exception was caught: \n" + acException.Message
                    + "\nError accessing vertex Xrecord\n");
                newPoint = acPline.GetPoint2dAt(index);
            }
            return(newPoint);
        }
        public static bool AddFFLData(ObjectId outlineId)
        {
            Document acDoc    = Application.DocumentManager.MdiActiveDocument;
            Editor   acEditor = acDoc.Editor;

            // Each building outline will have an extension dictionary which contains the following XRecords....
            //
            // FFL:         Name - "FFL"
            //              Data - double FFL
            //
            // Rotation:    Name - "Rotation"
            //              Data - double rotation_angle
            //
            // Vertex:      Name - "Vertex_X", where X is the index
            //              Data - integer Index
            //              Data - string "Corner" or "Access"
            //              Data - string "At_FFL" or "At_150_Down" or "Defined_Level"
            //              Data - double Level
            //
            // Add an extension dictionary to the outline
            //
            if (!JPPUtils.addExtensionDictionary(outlineId))
            {
                return(false);
            }
            double             FFLDouble; // Declare here to ensure in scope for later
            PromptDoubleResult promptFFLDouble = acEditor.GetDouble("\nEnter the FFL: ");

            if (promptFFLDouble.Status == PromptStatus.OK)
            {
                FFLDouble = promptFFLDouble.Value;
                ResultBuffer xrecFFLData = new ResultBuffer();
                xrecFFLData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, FFLDouble));
                if (!JPPUtils.addXrecord(outlineId, "FFL", xrecFFLData))
                {
                    acEditor.WriteMessage("\nError: could not add Xrecord: FFL.");
                    return(false);
                }
                // The rotation will be used as the basis for placing the FFL text. Fetch the angle
                // of the first vector to the x-axis and create a Xrecord to store it
                ResultBuffer xrecAngleData       = new ResultBuffer();
                double?      angleOfFirstSegment = getAngle(outlineId);
                if (angleOfFirstSegment == null)
                {
                    return(false);
                }
                xrecAngleData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, angleOfFirstSegment));
                if (!JPPUtils.addXrecord(outlineId, "Rotation", xrecAngleData))
                {
                    acEditor.WriteMessage("\nError: could not add Xrecord: Rotation.");
                    return(false);
                }
                // Add the corner points XRecords
                int?NoOfVertices = getNoOfVertices(outlineId);
                if (NoOfVertices == null)
                {
                    return(false);
                }
                for (int index = 0; index < NoOfVertices; index++)
                {
                    string       xrecName       = "Vertex_" + index.ToString();
                    ResultBuffer xrecVertexData = new ResultBuffer();
                    xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataInteger16, index));
                    xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "Corner"));
                    xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, "Defined_Level"));
                    // Add the default level at 150mm below FFL
                    xrecVertexData.Add(new TypedValue((int)DxfCode.ExtendedDataReal, (FFLDouble - 0.15)));
                    if (!JPPUtils.addXrecord(outlineId, xrecName, xrecVertexData))
                    {
                        acEditor.WriteMessage("\nError: could not add Xrecord: Vertex_" + index + ".");
                        return(false);
                    }
                }
                return(true);
            }
            else if (promptFFLDouble.Status == PromptStatus.Cancel)
            {
                acEditor.WriteMessage("\nDefine FFL request cancelled.");
                return(false);
            }
            else
            {
                acEditor.WriteMessage("\nError entering FFL.");
                return(false);
            }
        }
        public static bool NewFFL()
        {
            // Add comment here to explain what the following code does
            ObjectId outlineId = CreateOutline();

            if (outlineId == ObjectId.Null)
            {
                return(false);
            }
            if (!FormatOutline(outlineId))
            {
                // Remove the outline from the drawing
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }

            if (!AddFFLData(outlineId))
            {
                // Remove the outline from the drawing
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }
            if (!AddLevels(outlineId))
            {
                // Remove the outline from the drawing
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }
            // Adding the text will add other entities to the polyline so need to create an ObjectId collection
            // to store the object ids of each entity added to enable them to be grouped together.
            ObjectIdCollection FFLObjectIdCollection = JPPUtils.createObjectIdCollection(outlineId);

            if (FFLObjectIdCollection == null)
            {
                // Remove the outline from the drawing
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }

            if (!AddText(outlineId, FFLObjectIdCollection))
            {
                // If the text is not added sucessfully need to delete the objects in the object id collection.
                JPPUtils.EraseObjectsCollection(FFLObjectIdCollection);
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }
            if (!JPPUtils.CreateNewBlock(FFLObjectIdCollection))
            {
                // If the block is not created need to delete the objects in the object id collection,
                // and then delete the objects in the object id collection
                JPPUtils.EraseObjectsCollection(FFLObjectIdCollection);
                JPPUtils.EraseEntity(outlineId);
                return(false);
            }

            /* if (!JPPUtils.CreateNewGroup(FFLObjectIdCollection))
             * {
             *  // If the group is not created need to delete the objects in the object id collection,
             *  // and then delete the objects in the object id collection
             *  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);
                }
            }
        }