Пример #1
0
            private Curve2d StructurePosCurve(CivilDB.Structure str)
            {
                switch (str.BoundingShape)
                {
                case CivilDB.BoundingShapeType.Cylinder:
                    return(new CircularArc2d(new Point2d(str.Location.X, str.Location.Y), str.InnerDiameterOrWidth / 2));

                case CivilDB.BoundingShapeType.Box:
                    //создать прямоугольник с учетом поворота и точки вставки
                    Vector2d loc      = new Vector2d(str.Location.X, str.Location.Y);
                    Matrix2d rotation = Matrix2d.Rotation(str.Rotation, Point2d.Origin);
                    Point2d  p0       = (new Point2d(-str.InnerDiameterOrWidth / 2, -str.InnerLength / 2)).TransformBy(rotation) + loc;
                    Point2d  p1       = (new Point2d(-str.InnerDiameterOrWidth / 2, str.InnerLength / 2)).TransformBy(rotation) + loc;
                    Point2d  p2       = (new Point2d(str.InnerDiameterOrWidth / 2, str.InnerLength / 2)).TransformBy(rotation) + loc;
                    Point2d  p3       = (new Point2d(str.InnerDiameterOrWidth / 2, -str.InnerLength / 2)).TransformBy(rotation) + loc;

                    LineSegment2d side0 = new LineSegment2d(p0, p1);
                    LineSegment2d side1 = new LineSegment2d(p1, p2);
                    LineSegment2d side2 = new LineSegment2d(p2, p3);
                    LineSegment2d side3 = new LineSegment2d(p3, p0);

                    return(new CompositeCurve2d(new Curve2d[] { side0, side1, side2, side3 }));

                default:
                    return(null);
                }
            }
Пример #2
0
            private PointOnCurve2d GetSplitPt(CivilDB.Structure str, bool start)
            {
                Curve2d strPosCurve = StructurePosCurve(str);
                CurveCurveIntersector2d intersector = new CurveCurveIntersector2d(PositionCurve, strPosCurve);

                if (intersector.NumberOfIntersectionPoints > 0)
                {
                    intersector.OrderWithRegardsTo1();
                    //взять точку пересечения, которая имеет имеет наибольший параметр PositionCurve для начальной точки
                    //и наименьший для конечной точки
                    return(start ? intersector.GetPointOnCurve1(intersector.NumberOfIntersectionPoints - 1)
                        : intersector.GetPointOnCurve1(0));
                }
                return(null);
            }
        // structures
        public Mesh StructureToSpeckle(CivilDB.Structure structure)
        {
            var mesh = SolidToSpeckle(structure.Solid3dBody);

            // assign additional structure props
            try{
                mesh["@baseCurve"]     = CurveToSpeckle(structure.BaseCurve, ModelUnits) as Curve;
                mesh["name"]           = structure.DisplayName;
                mesh["description"]    = structure.Description;
                mesh["connectedPipes"] = structure.ConnectedPipesCount;
                mesh["@location"]      = PointToSpeckle(structure.Location, ModelUnits);
                mesh["station"]        = structure.Station;
                mesh["network"]        = structure.NetworkName;
            }
            catch {}

            return(mesh);
        }
Пример #4
0
        public void StructurePipesLabels()
        {
            Ed.Editor         ed     = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            Civ.CivilDocument civDoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;
            // Document AcadDoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            // Check that there's a pipe network to parse
            if (civDoc.GetPipeNetworkIds() == null)
            {
                ed.WriteMessage("There are no pipe networks to export.  Open a document that contains at least one pipe network");
                return;
            }


            // Iterate through each pipe network
            using (Db.Transaction ts = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction()) {
                Dictionary <string, char> dictPipe = new Dictionary <string, char>(); // track data parts column

                Ed.PromptEntityOptions opt = new Ed.PromptEntityOptions("\nSelect an Structure");
                opt.SetRejectMessage("\nObject must be an Structure.\n");
                opt.AddAllowedClass(typeof(CivDb.Structure), false);
                Db.ObjectId structureID = ed.GetEntity(opt).ObjectId;

                try {
                    //////Db.ObjectId oNetworkId = civDoc.GetPipeNetworkIds()[0];
                    //////CivDb.Network oNetwork = ts.GetObject(oNetworkId, Db.OpenMode.ForWrite) as CivDb.Network;

                    //// Get pipes:
                    //ObjectIdCollection oPipeIds = oNetwork.GetPipeIds();
                    //int pipeCount = oPipeIds.Count;

                    //// we can edit the slope, so make that column yellow
                    //Range colRange = xlWsPipes.get_Range("D1", "D" + ( pipeCount + 1 ));
                    //colRange.Interior.ColorIndex = 6;
                    //colRange.Interior.Pattern = XlPattern.xlPatternSolid;
                    //colRange.Interior.PatternColorIndex = XlColorIndex.xlColorIndexAutomatic;

                    //foreach ( ObjectId oid in oPipeIds ) {

                    //    Pipe oPipe = ts.GetObject(oid, OpenMode.ForRead) as Pipe;
                    //    ed.WriteMessage("   " + oPipe.Name);
                    //    col = 'B';
                    //    row++;
                    //    aRange = xlWsPipes.get_Range("A" + row, System.Type.Missing);
                    //    aRange.Value2 = oPipe.Handle.Value.ToString();
                    //    aRange = xlWsPipes.get_Range("B" + row, System.Type.Missing);
                    //    aRange.Value2 = oPipe.StartPoint.X + "," + oPipe.StartPoint.Y + "," + oPipe.StartPoint.Z;
                    //    aRange = xlWsPipes.get_Range("C" + row, System.Type.Missing);
                    //    aRange.Value2 = oPipe.EndPoint.X + "," + oPipe.EndPoint.Y + "," + oPipe.EndPoint.Z;

                    //    // This only gives the absolute value of the slope:
                    //    // aRange = xlWsPipes.get_Range("D" + row, System.Type.Missing);
                    //    // aRange.Value2 = oPipe.Slope;
                    //    // This gives a signed value:
                    //    aRange = xlWsPipes.get_Range("D" + row, System.Type.Missing);
                    //    aRange.Value2 = ( oPipe.EndPoint.Z - oPipe.StartPoint.Z ) / oPipe.Length2DCenterToCenter;

                    //    // Get the catalog data to use later
                    //    ObjectId partsListId = doc.Styles.PartsListSet["Standard"];
                    //    PartsList oPartsList = ts.GetObject(partsListId, OpenMode.ForRead) as PartsList;
                    //    ObjectIdCollection oPipeFamilyIdCollection = oPartsList.GetPartFamilyIdsByDomain(DomainType.Pipe);

                    //    foreach ( PartDataField oPartDataField in oPipe.PartData.GetAllDataFields() ) {
                    //        // Make sure the data has a column in Excel, if not, add the column
                    //        if ( !dictPipe.ContainsKey(oPartDataField.ContextString) ) {
                    //            char nextCol = ( char )( ( int )'E' + dictPipe.Count );
                    //            aRange = xlWsPipes.get_Range("" + nextCol + "1", System.Type.Missing);
                    //            aRange.Value2 = oPartDataField.ContextString + "(" + oPartDataField.Name + ")";
                    //            dictPipe.Add(oPartDataField.ContextString, nextCol);

                    //            // We can edit inner diameter or width, so make those yellow
                    //            if ( ( oPartDataField.ContextString == "PipeInnerDiameter" ) || ( oPartDataField.ContextString == "PipeInnerWidth" ) ) {
                    //                colRange = xlWsPipes.get_Range("" + nextCol + "1", "" + nextCol + ( pipeCount + 1 ));
                    //                colRange.Interior.ColorIndex = 6;
                    //                colRange.Interior.Pattern = XlPattern.xlPatternSolid;
                    //                colRange.Interior.PatternColorIndex = XlColorIndex.xlColorIndexAutomatic;
                    //            }

                    //            // Check the part catalog data to see if this part data is user-modifiable
                    //            foreach ( ObjectId oPipeFamliyId in oPipeFamilyIdCollection ) {
                    //                PartFamily oPartFamily = ts.GetObject(oPipeFamliyId, OpenMode.ForRead) as PartFamily;
                    //                SizeFilterField oSizeFilterField = null;

                    //                try {
                    //                    oSizeFilterField = oPartFamily.PartSizeFilter[oPartDataField.Name];
                    //                } catch ( System.Exception e ) { }

                    //                /* You can also iterate through all defined size filter fields this way:
                    //                 SizeFilterRecord oSizeFilterRecord = oPartFamily.PartSizeFilter;
                    //                 for ( int i = 0; i < oSizeFilterRecord.ParamCount; i++ ) {
                    //                     oSizeFilterField = oSizeFilterRecord[i];
                    //                  } */

                    //                if ( oSizeFilterField != null ) {
                    //                         // Check whether it can be modified:
                    //                         if ( oSizeFilterField.DataSource == PartDataSourceType.Optional ) {
                    //                             colRange = xlWsPipes.get_Range("" + nextCol + "1", "" + nextCol + ( pipeCount + 1 ));
                    //                             colRange.Interior.ColorIndex = 4;
                    //                             colRange.Interior.Pattern = XlPattern.xlPatternSolid;
                    //                             colRange.Interior.PatternColorIndex = XlColorIndex.xlColorIndexAutomatic;
                    //                         }

                    //                         break;
                    //                     }

                    //            }
                    //        }
                    //        char iColumnPipes = dictPipe[oPartDataField.ContextString];
                    //        aRange = aRange = xlWsPipes.get_Range("" + iColumnPipes + row, System.Type.Missing);
                    //        aRange.Value2 = oPartDataField.Value;

                    //    }
                    //}

                    // Now export the structures

                    Dictionary <string, char> dictStructures = new Dictionary <string, char>(); // track data parts column

                    // Get structures:

                    //Db.ObjectIdCollection oStructureIds = oNetwork.GetStructureIds();
                    //foreach ( Db.ObjectId oid in structureID ) {
                    CivDb.Structure    oStructure    = ts.GetObject(structureID, Db.OpenMode.ForRead) as CivDb.Structure;
                    CivDb.Network      oNetwork      = ts.GetObject(oStructure.NetworkId, Db.OpenMode.ForWrite) as CivDb.Network;
                    string[]           connPipeNames = oStructure.GetConnectedPipeNames();
                    PipeData.BIVPipe   pipe          = new PipeData.BIVPipe();
                    List <Db.ObjectId> pipeIds       = pipe.GetPipeIdByName(connPipeNames);
                    ed.WriteMessage("\nК колодцу присоеденены следующие трубы: ");
                    foreach (Db.ObjectId pipeId in pipeIds)
                    {
                        CivDb.Pipe oPipe = ts.GetObject(pipeId, Db.OpenMode.ForRead) as CivDb.Pipe;
                        ed.WriteMessage("{0} | {1:0.000}   |||   ", oPipe.Name, oStructure.get_PipeCenterDepth(new int()));
                    }
                    //col = 'B';
                    //row++;
                    //aRange = xlWsStructures.get_Range("" + col + row, System.Type.Missing);
                    //aRange.Value2 = oStructure.Handle.Value;
                    //aRange = xlWsStructures.get_Range("" + ++col + row, System.Type.Missing);
                    //aRange.Value2 = oStructure.Position.X + "," + oStructure.Position.Y + "," + oStructure.Position.Z;

                    //foreach ( CivDb.PartDataField oPartDataField in oStructure.PartData.GetAllDataFields() ) {
                    //    // Make sure the data has a column in Excel, if not, add the column
                    //    if ( !dictStructures.ContainsKey(oPartDataField.ContextString) ) {
                    //        char nextCol = ( char )( ( int )'D' + dictStructures.Count );
                    //        //aRange = xlWsStructures.get_Range("" + nextCol + "1", System.Type.Missing);
                    //        //aRange.Value2 = oPartDataField.ContextString;
                    //        dictStructures.Add(oPartDataField.ContextString, nextCol);

                    //    }
                    //    char iColumnStructure = dictStructures[oPartDataField.ContextString];
                    //ed.WriteMessage("\npartDataField.Name: " + oPartDataField.Name + "   ===   ColumnStructure to string: " + iColumnStructure + "   ===   PartDataField.Value: " + oPartDataField.Value.ToString() + "\n");
                    //    //aRange = aRange = xlWsStructures.get_Range("" + iColumnStructure + row, System.Type.Missing);
                    //    //aRange.Value2 = oPartDataField.Value;
                    //}
                    //}
                } catch (Autodesk.AutoCAD.Runtime.Exception ex) {
                    ed.WriteMessage("StructurePipesData: " + ex.Message);
                    return;
                }
            }
        }
Пример #5
0
            //private bool joinedEdge = false;//test

            public void CalcPipePosition(Transaction tr, ObjectId tinSurfId, double defaultDepth, bool sameDepthEveryPt, BlockTableRecord ms)
            {
                //Нужно учитывать размеры колодцев при расчете положения ребра!
                //Колодцы бывают просто цилиндрические и просто коробчатые
                //Учитывать Rotation, BoundingShape, InnerDiameterOrWidth, InnerLength
                //Уточнить кривую в плане по которой идет труба с учетом размеров колодца

                //TODO: Как учесть, что блок прямоугольного колодца может не соответствовать колодцу по направлениям длины и ширины????

                PointOnCurve2d startSplitPt = null;
                PointOnCurve2d endSplitPt   = null;

                CivilDB.Structure strStart = null;
                CivilDB.Structure strEnd   = null;
                if (!StartNode.StructId.IsNull)
                {
                    strStart = (CivilDB.Structure)tr.GetObject(StartNode.StructId, OpenMode.ForRead);
                    //уточнить положение начала кривой в начале с учетом размеров колодца!
                    startSplitPt = GetSplitPt(strStart, true);
                }
                if (!EndNode.StructId.IsNull)
                {
                    strEnd = (CivilDB.Structure)tr.GetObject(EndNode.StructId, OpenMode.ForRead);
                    //уточнить положение конца кривой в начале с учетом размеров колодца!
                    endSplitPt = GetSplitPt(strEnd, false);
                }

                if (startSplitPt != null && endSplitPt != null && startSplitPt.Parameter >= endSplitPt.Parameter)
                {
                    //колодцы стоят вплотную друг к другу или залезают друг на друга. Места для трубы на остается
                    return;
                }

                //проход по составляющим кривой с отбрасыванием частей, отсекаемых колодцами
                //Curve2d.GetSplitCurves работает неправильно
                //Curve2d.Explode тоже не помогает
                if (startSplitPt == null)
                {
                    AddPtToPipePositionList(new XYZ(PositionCurve.StartPoint));
                }
                Curve2d[] segments  = PositionCurve.GetCurves();
                double    currParam = 0;

                foreach (Curve2d seg in segments)
                {
                    Interval interval = seg.GetInterval();
                    double   len      = seg.GetLength(interval.LowerBound, interval.UpperBound);

                    currParam += len;

                    //Если есть точка разбиения в начале и она еще не достигнута
                    if (startSplitPt != null)
                    {
                        if (startSplitPt.Parameter < currParam)
                        {
                            //точка разбиения находится на этой кривой. Ее нужно добавить в список
                            AddPtToPipePositionList(new XYZ(startSplitPt.Point));
                            startSplitPt = null;
                        }
                        else
                        {
                            //точка отсечения начала еще не достигнута, переход к следующей кривой
                            continue;
                        }
                    }


                    if (endSplitPt != null && endSplitPt.Parameter < currParam)
                    {
                        //точка разбиения находится на этой кривой. Ее нужно добавить в список
                        AddPtToPipePositionList(new XYZ(endSplitPt.Point));
                        endSplitPt = null;
                        break;//обход точек заканчивается
                    }

                    AddPtToPipePositionList(new XYZ(seg.EndPoint));
                }


                //Задание глубин заложения ребер по концам
                //- если не задана глубина заложения на одном из концов, сделать их равными
                //- если не задана глубина на обоих концах задать обоим концам глубину по умолчанию согласно вводу в окне
                CivilDB.TinSurface tinSurf         = (CivilDB.TinSurface)tr.GetObject(tinSurfId, OpenMode.ForRead);
                double             startElevByData = double.NegativeInfinity;
                double             endElevByData   = double.NegativeInfinity;

                if (StartPipeJunctionData != null && StartPipeJunctionData.JunctionLevel != double.NegativeInfinity)
                {
                    startElevByData = StartPipeJunctionData.JunctionLevel;
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = startElevByData;
                }
                if (EndPipeJunctionData != null && EndPipeJunctionData.JunctionLevel != double.NegativeInfinity)
                {
                    endElevByData = EndPipeJunctionData.JunctionLevel;
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = endElevByData;
                }



                if (startElevByData != double.NegativeInfinity && endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = startElevByData;
                }
                else if (startElevByData == double.NegativeInfinity && endElevByData != double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = endElevByData;
                }
                else if (startElevByData == double.NegativeInfinity && endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz1 = PipePositionList.First();
                    SetElevBySurf(defaultDepth, tinSurf, xyz1);

                    XYZ xyz2 = PipePositionList.Last();
                    SetElevBySurf(defaultDepth, tinSurf, xyz2);
                }


                //- но не допускать, чтобы труба опускалась ниже дна колодца
                double sartElevByStr = double.NegativeInfinity;
                double endElevByStr  = double.NegativeInfinity;

                if (strStart != null && strStart.SumpElevation > PipePositionList.First().Z)
                {
                    sartElevByStr = strStart.SumpElevation;
                    PipePositionList.First().Z = sartElevByStr;
                }

                if (strEnd != null && strEnd.SumpElevation > PipePositionList.Last().Z)
                {
                    endElevByStr = strEnd.SumpElevation;
                    PipePositionList.Last().Z = endElevByStr;
                }
                //после корректировки уточнить отметку соседней точки если по ней нет данных
                if (sartElevByStr != double.NegativeInfinity &&
                    endElevByData == double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.Last();
                    xyz.Z = sartElevByStr;
                }
                else if (startElevByData == double.NegativeInfinity &&
                         endElevByStr != double.NegativeInfinity)
                {
                    XYZ xyz = PipePositionList.First();
                    xyz.Z = endElevByStr;
                }


                //Убедиться, что если в одном узле без колодца стыкуются несколько ребер,
                //то в месте стыковки обязательно у всех ребер должна быть одинаковая отметка
                double neighborJunctElev = GetNeigborJuncElev(StartNode);
                XYZ    startPos          = PipePositionList.First();

                if (neighborJunctElev != double.NegativeInfinity && startPos.Z != neighborJunctElev)
                {
                    startPos.Z = neighborJunctElev;
                }

                neighborJunctElev = GetNeigborJuncElev(EndNode);
                XYZ endPos = PipePositionList.Last();

                if (neighborJunctElev != double.NegativeInfinity && endPos.Z != neighborJunctElev)
                {
                    endPos.Z = neighborJunctElev;
                }


                //Задание отметок промежуточных точек на ребрах сети (интерполяция либо относительно поверхности)
                if (PipePositionList.Count > 2)
                {
                    if (sameDepthEveryPt)
                    {
                        //одинаковая глубина относительно поверхности земли
                        //метод TinSurface.SampleElevations работает не так как надо! Он не дает подробного учета рельефа!
                        //точки полилинии
                        for (int i = 1; i < PipePositionList.Count - 1; i++)
                        {
                            XYZ xyz = PipePositionList[i];
                            SetElevBySurf(defaultDepth, tinSurf, xyz);
                        }


                        //Помимо углов поворотов нужно добавить промежуточные точки через 1 м для учета рельефа!


                        List <XYZ> positionListExtended = new List <XYZ>();
                        positionListExtended.Add(PipePositionList.First());
                        for (int i = 1; i < PipePositionList.Count; i++)
                        {
                            XYZ      xyz0    = PipePositionList[i - 1];
                            XYZ      xyz1    = PipePositionList[i];
                            double   len     = xyz1.Position2d.GetDistanceTo(xyz0.Position2d);
                            Vector2d vector  = (xyz1.Position2d - xyz0.Position2d).GetNormal();
                            double   currLen = 1;
                            while (currLen < len)
                            {
                                //добавление промежуточных точек
                                Point2d pt = xyz0.Position2d + vector * currLen;
                                XYZ     intermediateXYZ = new XYZ(pt);
                                SetElevBySurf(defaultDepth, tinSurf, intermediateXYZ);
                                positionListExtended.Add(intermediateXYZ);

                                currLen += 1;
                            }
                            positionListExtended.Add(xyz1);
                        }
                        PipePositionList = positionListExtended;
                    }
                    else
                    {
                        //интерполяция между началом и концом
                        double startElev  = startPos.Z;
                        double endElev    = endPos.Z;
                        double elevDiff   = endElev - startElev;
                        double currLength = 0;
                        for (int i = 1; i < PipePositionList.Count - 1; i++)
                        {
                            XYZ xyz = PipePositionList[i];

                            Point2d prevPt = PipePositionList[i - 1].Position2d;
                            currLength += prevPt.GetDistanceTo(xyz.Position2d);


                            xyz.Z = startElev + (elevDiff * currLength / pipeHorizontalLength);
                        }
                    }
                }
            }