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