public WallSegment NextClockwise(WallSegment currentSegment) { double currentAngle = 0; foreach (SegmentConnection ws in Segments) { if (ws.Segment.Guid == currentSegment.Guid) { currentAngle = ws.Angle; } } bool found = false; int i = 0; while (!found) { if (currentAngle <= Segments[i].Angle) { found = true; } i++; } if (i > Segments.Count - 1) { //TODO: Make sure this works i = i - Segments.Count; } return(Segments[i].Segment); }
/// <summary> /// Helper method for adding wall segments to ensure everything gets linked correctly. /// </summary> private void AddWallSegment(WallSegment newSegment) { Segments.Add(newSegment); bool startFound = false; bool endFound = false; foreach (WallJoint wj in Joints) { if (wj.Point.IsEqualTo(newSegment.StartPoint)) { startFound = true; newSegment.StartJoint = wj; wj.AddWallSegment(newSegment); } if (wj.Point.IsEqualTo(newSegment.EndPoint)) { endFound = true; newSegment.EndJoint = wj; wj.AddWallSegment(newSegment); } } if (!startFound) { WallJoint newWj = new WallJoint(); newWj.Point = newSegment.StartPoint; newSegment.StartJoint = newWj; newWj.AddWallSegment(newSegment); newWj.Type = JointType.Internal; if (AccessLookup.ContainsKey(newWj.Point)) { newWj.RelativeOffset = AccessLookup[newWj.Point].Offset; newWj.Type = JointType.AccessPoint; } Joints.Add(newWj); } if (!endFound) { WallJoint newWj = new WallJoint(); newWj.Point = newSegment.EndPoint; newSegment.EndJoint = newWj; newWj.AddWallSegment(newSegment); newWj.Type = JointType.Internal; if (AccessLookup.ContainsKey(newWj.Point)) { newWj.RelativeOffset = AccessLookup[newWj.Point].Offset; newWj.Type = JointType.AccessPoint; } Joints.Add(newWj); } newSegment.Generate(); }
private void TraverseExternalSegment(WallSegment currentSegment, WallJoint currentNode, WallJoint startNode) { currentSegment.External = true; PerimeterPath.Add(currentNode); //Get next WallSegment nextSegment = currentNode.NextClockwise(currentSegment); WallJoint nextJoint; if (nextSegment.StartPoint.IsEqualTo(currentNode.Point)) { nextJoint = nextSegment.EndJoint; } else { nextJoint = nextSegment.StartJoint; } if (currentNode.Type == JointType.Internal) { if (Collinear(currentSegment.StartPoint, currentSegment.EndPoint, nextJoint.Point)) { //Check if on line currentNode.Type = JointType.ExternalIntermediate; } else { currentNode.Type = JointType.ExternalCorner; } } if (nextJoint.Point.IsEqualTo(startNode.Point)) { //Back to start nextSegment.External = true; nextJoint.Type = JointType.ExternalCorner; } else { TraverseExternalSegment(nextSegment, nextJoint, startNode); } }
public void AddWallSegment(WallSegment ws) { //TODO: Make sure actually connects to the point SegmentConnection sc = new SegmentConnection() { Segment = ws }; if (ws.StartPoint == Point) { sc.Angle = Point.GetVectorTo(ws.EndPoint).GetAngleTo(Vector3d.YAxis, Vector3d.ZAxis) * 180d / Math.PI; } else { sc.Angle = Point.GetVectorTo(ws.StartPoint).GetAngleTo(Vector3d.YAxis, Vector3d.ZAxis) * 180d / Math.PI; } Segments.Add(sc); Sort(); }
public List <WallSegment> Split(Point3d splitPoint) { List <WallSegment> result = new List <WallSegment>(2); Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Transaction acTrans = acDoc.TransactionManager.TopTransaction; BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Line segment = acTrans.GetObject(PerimeterLine, OpenMode.ForWrite) as Line; Point3dCollection points = new Point3dCollection(); points.Add(splitPoint); var splitLines = segment.GetSplitCurves(points); foreach (DBObject dbobj in splitLines) { Entity e = dbobj as Entity; WallSegment ws = new WallSegment() { PerimeterLine = acBlkTblRec.AppendEntity(e), Guid = System.Guid.NewGuid().ToString() }; e.XData = new ResultBuffer(new TypedValue(1001, "JPP"), new TypedValue(1000, ws.Guid)); acTrans.AddNewlyCreatedDBObject(e, true); result.Add(ws); } return(result); }
public static void CreateWallSegments() { Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor acEditor = acDoc.Editor; if (CurrentOpen != null) { // All work will be done in the WCS so save the current UCS // to restore later and set the UCS to WCS Matrix3d CurrentUCS = acEditor.CurrentUserCoordinateSystem; acEditor.CurrentUserCoordinateSystem = Matrix3d.Identity; // Get the current color, for temp graphics // Color currCol = acCurrDb.Cecolor; Color drawColor = Color.FromColorIndex(ColorMethod.ByAci, 1); // Create a 3d point collection to store the vertices Point3dCollection PickPts = new Point3dCollection(); // Set up the selection options PromptPointOptions promptCornerPtOpts = new PromptPointOptions("\nSelect points along segment: "); promptCornerPtOpts.AllowNone = true; // Get the start point for the polyline PromptPointResult promptResult = acEditor.GetPoint(promptCornerPtOpts); // Continue to add picked corner points to the polyline while (promptResult.Status == PromptStatus.OK) { // Add the selected point PickPts collection PickPts.Add(promptResult.Value); // Drag a temp line during selection of subsequent points promptCornerPtOpts.UseBasePoint = true; promptCornerPtOpts.BasePoint = promptResult.Value; promptResult = acEditor.GetPoint(promptCornerPtOpts); if (promptResult.Status == PromptStatus.OK) { //TODO: Rework this using the transient api so they dont disappear on move // For each point selected, draw a temporary segment acEditor.DrawVector(PickPts[PickPts.Count - 1], // start point promptResult.Value, // end point drawColor.ColorIndex, // highlight colour //currCol.ColorIndex, // current color false); // highlighted } } Polyline acPline = new Polyline(PickPts.Count); acPline.Layer = Constants.JPP_HS_PlotPerimiter; // The user has pressed SPACEBAR to exit the picking points loop if (promptResult.Status == PromptStatus.None) { foreach (Point3d pt in PickPts) { // Alert user that picked point has elevation. if (pt.Z != 0.0) { acEditor.WriteMessage("/nWarning: corner point has non-zero elevation. Elevation will be ignored."); } acPline.AddVertexAt(acPline.NumberOfVertices, new Point2d(pt.X, pt.Y), 0, 0, 0); } // If user has clicked the start point to close the polyline delete this point and // set polyline to closed if (acPline.EndPoint == acPline.StartPoint) { acPline.RemoveVertexAt(acPline.NumberOfVertices - 1); acPline.Closed = true; } } //Explode the line and create wall segments to match DBObjectCollection lineSegments = new DBObjectCollection(); acPline.Explode(lineSegments); using (Transaction tr = acDoc.TransactionManager.StartTransaction()) { // Open the Block table for read BlockTable acBlkTbl = tr.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; foreach (DBObject dbobj in lineSegments) { Line e = dbobj as Line; WallSegment ws = new WallSegment() { PerimeterLine = acBlkTblRec.AppendEntity(e), Guid = Guid.NewGuid().ToString() }; e.XData = new ResultBuffer(new TypedValue(1001, "JPP"), new TypedValue(1000, ws.Guid)); tr.AddNewlyCreatedDBObject(e, true); PlotType.CurrentOpen.WSIntersect(e.StartPoint); PlotType.CurrentOpen.WSIntersect(e.EndPoint); PlotType.CurrentOpen.Segments.Add(ws); } tr.Commit(); } } else { acEditor.WriteMessage("No Plot Type currently open\n"); } }
/// <summary> /// Create the plot and establish all drawing objects. Only to be called when plot is first created or to be reset from plot types /// MUST be called from an active transaction /// <exception cref="ArgumentOutOfRangeException"> An ArugmentOutOfRageException is thrown when a matching wall segment in the plot type isnt found or is duplicated </exception> /// </summary> public void Generate() { Status = PlotStatus.ForApproval; StatusMessage = "Plot generated successfully"; Database acCurDb; acCurDb = Application.DocumentManager.MdiActiveDocument.Database; Transaction acTrans = acCurDb.TransactionManager.TopTransaction; BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; BlockReference newBlockRef; //Link the block reference if (BlockRefPtr == 0) { BlockRef = Core.Utilities.InsertBlock(BasePoint, Rotation, PlotType.BlockID); newBlockRef = (BlockReference)BlockRef.GetObject(OpenMode.ForWrite); } else { //TODO: Add regeneration code. throw new NotImplementedException(); } //Explode the blockref DBObjectCollection explodedBlock = new DBObjectCollection(); newBlockRef.Explode(explodedBlock); //TODO: Move releveant blocks here Main.LoadBlocks(); AccessLookup = new Dictionary <Point3d, AccessPoint>(); foreach (Entity entToAdd in explodedBlock) { //Pull the circles that id access points out if (entToAdd is Circle) { Circle c = entToAdd as Circle; if (c.Layer == Civils.Constants.JPP_HS_PlotPerimiter) { var rb = c.XData; string target = ""; foreach (var tv in rb) { target = tv.Value as string; } Point3d? master = null; AccessPoint?typeAP = null; foreach (AccessPoint ap in this.PlotType.AccessPoints) { //TODO: Add code to match to PlotType WS by comparing start and end points if (ap.Guid == target) { if (master == null) { master = c.Center; typeAP = ap; } else { throw new ArgumentOutOfRangeException("Wall segment match already found", (System.Exception)null); } } } if (master == null) { throw new ArgumentOutOfRangeException("No matching wall segment found", (System.Exception)null); } AccessLookup.Add(master.Value, typeAP.Value); } } } foreach (Entity entToAdd in explodedBlock) { //Identify the lines as these indicate wall segments //TODO: Add handling here for when a line is NOT a wall segmen if (entToAdd is Line) { Line segment = entToAdd as Line; string target = ""; //Get type id var rb = segment.XData; foreach (var tv in rb) { target = tv.Value as string; } WallSegment master = null; WallSegment seg = new WallSegment(); foreach (WallSegment ptWS in this.PlotType.Segments) { //TODO: Add code to match to PlotType WS by comparing start and end points if (ptWS.Guid == target) { if (master == null) { master = ptWS; } else { throw new ArgumentOutOfRangeException("Wall segment match already found", (System.Exception)null); } } } if (master == null) { throw new ArgumentOutOfRangeException("No matching wall segment found", (System.Exception)null); } //TODO: Check, think object is not part of database seg.PerimeterLine = segment.ObjectId; seg.StartPoint = segment.StartPoint; seg.EndPoint = segment.EndPoint; seg.Guid = master.Guid; AddWallSegment(seg); } } //HANDLE EXTERNAL LEVELS //Traverse through wall segments to find external ones, starting with basepoint //Find basepoint WallJoint startNode = null; foreach (WallJoint wj in Joints) { if (wj.Point.IsEqualTo(BasePoint)) { startNode = wj; } } if (startNode == null) { throw new ArgumentOutOfRangeException("Basepoint does not lie on wall joint", (System.Exception)null); } //Recursively traverse through the segments to find the external ones WallSegment startSegment = startNode.North; WallJoint nextNode; if (startSegment.EndPoint == startNode.Point) { nextNode = startSegment.StartJoint; } else { nextNode = startSegment.EndJoint; } PerimeterPath = new List <WallJoint>(); PerimeterPath.Add(startNode); TraverseExternalSegment(startSegment, nextNode, startNode); //Remove the last point PerimeterPath.RemoveAt(PerimeterPath.Count - 1); //GENERATE SUB ELEMENTS foreach (WallJoint wj in PerimeterPath) { wj.Generate(Rotation); } //Check to see if FFL needs to be set if (UpdateLevelsFromSurface) { GetFFLfromSurface(); } Update(); /*Polyline acPline = entToAdd as Polyline; * foreach (AccessPoint ap in PlotType.AccessPoints) * { * PlotLevel pl = new PlotLevel(false, ap.Offset, this, ap.Parameter); * pl.Generate(acPline.GetPointAtParameter(ap.Parameter)); * Level.Add(pl); * } * * //Iterate over all the corners and add to the drawing * int vn = acPline.NumberOfVertices; * for (int i = 0; i < vn; i++) * { * Point3d pt = acPline.GetPoint3dAt(i); * PlotLevel pl = new PlotLevel(false, -0.15, this, acPline.GetParameterAtPoint(pt)); * pl.Generate(pt); * Level.Add(pl); * } * * // Open the Block table for read * BlockTable acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; * * // Open the Block table record Model space for write * BlockTableRecord acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; * * //Ad the FFL Label * // Create a multiline text object * using (MText acMText = new MText()) * { * //Find the centre of the plot outline as an estimated point of insertion * Solid3d Solid = new Solid3d(); * DBObjectCollection coll = new DBObjectCollection * { * acPline * }; * Solid.Extrude(((Region)Region.CreateFromCurves(coll)[0]), 1, 0); * Point3d centroid = new Point3d(Solid.MassProperties.Centroid.X, Solid.MassProperties.Centroid.Y, 0); * Solid.Dispose(); * * acMText.Location = centroid; * acMText.Contents = FinishedFloorLevelText; * acMText.Rotation = Rotation; * acMText.Height = 7; * acMText.Attachment = AttachmentPoint.MiddleCenter; * * FFLLabel = acBlkTblRec.AppendEntity(acMText); * acTrans.AddNewlyCreatedDBObject(acMText, true); * } * * GenerateHatching();*/ }