Пример #1
0
        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);
        }
Пример #2
0
        /// <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();
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }
Пример #6
0
        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");
            }
        }
Пример #7
0
        /// <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();*/
        }