static public Spline mergeSpline(DBObjectCollection dboCol) { //load spline with a segment Spline springSline = convertSpline(dboCol[0]); dboCol.Remove(dboCol[0]); do { //find the part that intersects DBObject seg = findIntersectingPart(dboCol, springSline); //convert to spline Spline addSeg = convertSpline(seg); //add part to spline springSline.JoinEntity(addSeg); //remove part from collection dboCol.Remove(seg); } while (dboCol.Count > 0); springSline.Color = Color.FromRgb(51, 255, 255); return(springSline); }
//uses join entity to create a polyline. //if there are parts in collection that arent connected it needs to be updated to create a different polyline public static Polyline drawPolyLine(DBObjectCollection dbObjCol) { //check if collection will end as closed poly line or not //if any part has less or more than to intersections with other parts, then it isnt closed. bool isClosed = false; int startSegment = getFirstSeg(dbObjCol); if (startSegment == -1) { //load the first piece of the poly line into the Poly Line startSegment = 0; isClosed = true; } //get first part to start building polyline DBObject firstSeg = dbObjCol[startSegment]; Polyline pLine = makePolyLIne(firstSeg); dbObjCol.Remove(firstSeg); do { //find part that intersects DBObject seg = findIntersectingPart(dbObjCol, pLine as DBObject); //convert part to polyline Polyline pSeg = makePolyLIne(seg); //add part to polyline pLine.JoinEntity(pSeg); //remove part from collection dbObjCol.Remove(seg); //**Need to break if some parts exist but don't intersect with anything //prob need at that point to make into a diff polyline at some point } while (dbObjCol.Count > 0); pLine.Closed = isClosed; return(pLine); }
/** * @brief Metodo que descompone una enitdad AUTOCAD en sub-entidades cuando es posible. Replica el comportamiento del comando * DESCOMPONER / EXPLODE de AutoCAD. Las unidades básicas que devuelve son puntos y lineas. Descompone recursivamente * las entidades hasta dejarlas representadas como puntos, lineas y arcos. * * @param ent Entidad que debe ser descompuesta * @param acBlkTbl Tabla de bloques de AutoCAD para buscar nuevos objetos y añadir nuevos objetos generados. * @param acBlkTblRec Tabla de registros de los bloques de AutoCAD para buscar nuevos objetos y añadir nuevos objetos generados. * @param t Transaccion abierta para manipular la tabla de bloques de AutoCAD. * * @return Devuelve una colección de entidades bajo la clase DBObjectCollection. **/ private static DBObjectCollection ObtenerPuntosyLineas(Entity ent, BlockTable acBlkTbl, BlockTableRecord acBlkTblRec, Transaction t) { DBObjectCollection retorno = new DBObjectCollection(); DBObjectCollection procesar = new DBObjectCollection(); ent.Explode(procesar); while (procesar.Count != 0) { Entity obj = (Entity)procesar[0]; acBlkTblRec.AppendEntity(obj); t.AddNewlyCreatedDBObject(obj, true); dwgf.objetosArtificiales.Add(obj.ObjectId); if (obj.ObjectId.ObjectClass.DxfName == "POINT" || obj.ObjectId.ObjectClass.DxfName == "LINE") { if (retorno.Contains(obj) == false) { retorno.Add(obj); } } if (obj.ObjectId.ObjectClass.DxfName == "ARC") { // Completar con el proceso para los arcos. if (retorno.Contains(obj) == false) { retorno.Add(obj); } } if (obj.ObjectId.ObjectClass.DxfName == "LWPOLYLINE") { DBObjectCollection aux = new DBObjectCollection(); obj.Explode(aux); foreach (DBObject aux2 in aux) { procesar.Add(aux2); } } procesar.Remove(obj); } return(retorno); }
public static DBObjectCollection PolylineFromRegion( Region reg ) { // We will return a collection of entities // (should include closed Polylines and other // closed curves, such as Circles) DBObjectCollection res = new DBObjectCollection(); // Explode Region -> collection of Curves / Regions DBObjectCollection cvs = new DBObjectCollection(); reg.Explode(cvs); // Create a plane to convert 3D coords // into Region coord system Plane pl = new Plane(new Point3d(0, 0, 0), reg.Normal); using (pl) { bool finished = false; while (!finished && cvs.Count > 0) { // Count the Curves and the non-Curves, and find // the index of the first Curve in the collection int cvCnt = 0, nonCvCnt = 0, fstCvIdx = -1; for (int i = 0; i < cvs.Count; i++) { Curve tmpCv = cvs[i] as Curve; if (tmpCv == null) { nonCvCnt++; } else { // Closed curves can go straight into the // results collection, and aren't added // to the Curve count if (tmpCv.Closed) { res.Add(tmpCv); cvs.Remove(tmpCv); // Decrement, so we don't miss an item i--; } else { cvCnt++; if (fstCvIdx == -1) { fstCvIdx = i; } } } } if (fstCvIdx >= 0) { // For the initial segment take the first // Curve in the collection Curve fstCv = (Curve)cvs[fstCvIdx]; // The resulting Polyline Polyline p = new Polyline(); // Set common entity properties from the Region p.SetPropertiesFrom(reg); // Add the first two vertices, but only set the // bulge on the first (the second will be set // retroactively from the second segment) // We also assume the first segment is counter- // clockwise (the default for arcs), as we're // not swapping the order of the vertices to // make them fit the Polyline's order p.AddVertexAt( p.NumberOfVertices, fstCv.StartPoint.Convert2d(pl), BulgeFromCurve(fstCv, false), 0, 0 ); p.AddVertexAt( p.NumberOfVertices, fstCv.EndPoint.Convert2d(pl), 0, 0, 0 ); cvs.Remove(fstCv); // The next point to look for Point3d nextPt = fstCv.EndPoint; // We no longer need the curve fstCv.Dispose(); // Find the line that is connected to // the next point // If for some reason the lines returned were not // connected, we could loop endlessly. // So we store the previous curve count and assume // that if this count has not been decreased by // looping completely through the segments once, // then we should not continue to loop. // Hopefully this will never happen, as the curves // should form a closed loop, but anyway... // Set the previous count as artificially high, // so that we loop once, at least. int prevCnt = cvs.Count + 1; while (cvs.Count > nonCvCnt && cvs.Count < prevCnt) { prevCnt = cvs.Count; foreach (DBObject obj in cvs) { Curve cv = obj as Curve; if (cv != null) { // If one end of the curve connects with the // point we're looking for... if (cv.StartPoint == nextPt || cv.EndPoint == nextPt) { // Calculate the bulge for the curve and // set it on the previous vertex double bulge = BulgeFromCurve(cv, cv.EndPoint == nextPt); if (bulge != 0.0) { p.SetBulgeAt(p.NumberOfVertices - 1, bulge); } // Reverse the points, if needed if (cv.StartPoint == nextPt) { nextPt = cv.EndPoint; } else { // cv.EndPoint == nextPt nextPt = cv.StartPoint; } // Add out new vertex (bulge will be set next // time through, as needed) p.AddVertexAt( p.NumberOfVertices, nextPt.Convert2d(pl), 0, 0, 0 ); // Remove our curve from the list, which // decrements the count, of course cvs.Remove(cv); cv.Dispose(); break; } } } } // Once we have added all the Polyline's vertices, // transform it to the original region's plane p.TransformBy(Matrix3d.PlaneToWorld(pl)); res.Add(p); if (cvs.Count == nonCvCnt) { finished = true; } } // If there are any Regions in the collection, // recurse to explode and add their geometry if (nonCvCnt > 0 && cvs.Count > 0) { foreach (DBObject obj in cvs) { Region subReg = obj as Region; if (subReg != null) { DBObjectCollection subRes = PolylineFromRegion(subReg); foreach (DBObject o in subRes) { res.Add(o); } cvs.Remove(subReg); subReg.Dispose(); } } } if (cvs.Count == 0) { finished = true; } } } return(res); }
public static List <Polyline> RegionToPolylines(Database db, Transaction tr, Region reg, Color color, bool willAddToModelSpace, bool needToConvertPolyline2d, ObjectId layerId) { var polylines = new List <Polyline>(); var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); var btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead); if (reg != null && reg.IsNull == false) { // The resulting Polyline var p = new Polyline(); // Explode Region -> collection of Curves var cvs = new DBObjectCollection(); reg.Explode(cvs); // Create a plane to convert 3D coords // into Region coord system var pl = new Plane(new Point3d(0, 0, 0), reg.Normal); // Set common entity properties from the Region p.SetPropertiesFrom(reg); //check if exploded region is still a region. If yes, We also need to explode the childe region. bool hasRegion = false; foreach (DBObject obj in cvs) { var region = obj as Region; if (region != null) { hasRegion = true; var subPolylines = RegionToPolylines(db, tr, region, color, willAddToModelSpace, needToConvertPolyline2d, layerId); region.Dispose(); polylines.AddRange(subPolylines); } } if (hasRegion) { cvs.Dispose(); pl.Dispose(); return(polylines); } // For initial Curve take the first in the list var cv1 = cvs[0] as Curve; p.AddVertexAt( p.NumberOfVertices, cv1.StartPoint.Convert2d(pl), BulgeFromCurve(cv1, false), 0, 0 ); p.AddVertexAt( p.NumberOfVertices, cv1.EndPoint.Convert2d(pl), 0, 0, 0 ); cvs.Remove(cv1); // The next point to look for Point3d nextPt = cv1.EndPoint; cv1.Dispose(); // Find the line that is connected to // the next point // If for some reason the lines returned were not // connected, we could loop endlessly. // So we store the previous curve count and assume // that if this count has not been decreased by // looping completely through the segments once, // then we should not continue to loop. // Hopefully this will never happen, as the curves // should form a closed loop, but anyway... // Set the previous count as artificially high, // so that we loop once, at least. int prevCnt = cvs.Count + 1; while (cvs.Count > 0 && cvs.Count < prevCnt) { prevCnt = cvs.Count; foreach (Curve cv in cvs) { // If one end of the curve connects with the // point we're looking for... if (cv.StartPoint == nextPt || cv.EndPoint == nextPt) { // Calculate the bulge for the curve and // set it on the previous vertex double bulge = BulgeFromCurve(cv, cv.EndPoint == nextPt); p.SetBulgeAt(p.NumberOfVertices - 1, bulge); // Reverse the points, if needed if (cv.StartPoint == nextPt) { nextPt = cv.EndPoint; } else { // cv.EndPoint == nextPt nextPt = cv.StartPoint; } // Add out new vertex (bulge will be set next // time through, as needed) p.AddVertexAt( p.NumberOfVertices, nextPt.Convert2d(pl), 0, 0, 0 ); // Remove our curve from the list, which // decrements the count, of course cvs.Remove(cv); cv.Dispose(); break; } } } if (cvs.Count >= prevCnt) { // Error. p.Dispose(); } else { // Once we have added all the Polyline's vertices, // transform it to the original region's plane p.TransformBy(Matrix3d.PlaneToWorld(pl)); if (layerId.IsValid) { p.LayerId = layerId; } p.Color = color; // Extra checking if the polyline end point is same as start point. If yes, remove the end point. var startPoint2d = p.GetPoint2dAt(0); var endPoint2d = p.GetPoint2dAt(p.NumberOfVertices - 1); if (Math.Abs(startPoint2d.X - endPoint2d.X) < DistanceTolerance && Math.Abs(startPoint2d.Y - endPoint2d.Y) < DistanceTolerance) { double lastBulge = p.GetBulgeAt(p.NumberOfVertices - 2); p.RemoveVertexAt(p.NumberOfVertices - 1); p.SetBulgeAt(p.NumberOfVertices - 1, lastBulge); } // Make sure the polyline is closed. if (!p.Closed) { p.Closed = true; } // 设置标高. p.Elevation = 0.0; if (p.Area < AreaTolerance) { p.Dispose(); return(polylines); } // Append our new Polyline to the database if (willAddToModelSpace) { btr.UpgradeOpen(); btr.AppendEntity(p); tr.AddNewlyCreatedDBObject(p, true); //// 确保生成出来的polyline为顺时针方向 //GeometryUtils.EnsurePolylineClockWise(p.ObjectId); } pl.Dispose(); polylines.Add(p); return(polylines); } pl.Dispose(); } return(polylines); }
public static DBObjectCollection[] GetScalePoints(Polyline polyline) { JzdService jzdService = new JzdService(); DBObjectCollection[] dbcs = new DBObjectCollection[4]; Point3dCollection point3dCollection = new Point3dCollection(); polyline.GetStretchPoints(point3dCollection); double[] dou = utils.FindFourPoints(point3dCollection); Point3dCollection point3dCollection2 = utils.createFourPoint(dou); Polyline3d polyline3d = utils.CreatePolye(point3dCollection2, true); IList <Zdinfo> list = JzdService.DBCToZdinfo(utils.SelectJzd(point3dCollection2)); int num = utils.PolyDiPoly(point3dCollection, point3dCollection2); int[] array = new int[4]; if (num > 3) { int[] array2 = utils.FindPointsDic(point3dCollection); if (array2[0] == 0) { array = array2; } else { int[] array3 = utils.FindPointsDic(point3dCollection, point3dCollection2); if (array3[0] == 0) { array = array3; } else { int[][] max = new int[][] { array2, array3 }; int num2 = utils.SelectPc1PC2(max, point3dCollection); if (num2 == 0) { array = array2; } else if (num2 == 1) { array = array3; } } } } else { array = utils.FindPointsDic(point3dCollection, point3dCollection2); } IList <string[]> list2 = new List <string[]>(); double num3 = utils.PointAngle(point3dCollection[array[0]], point3dCollection[array[1]]); double num4 = utils.PointAngle(point3dCollection[array[0]], point3dCollection[array[3]]); double num5 = num3 - num4; for (int i = 0; i < 4; i++) { int start = array[i]; int end = array[i + 1]; DBObjectCollection dbc = jzdService.SelectJzd(polyline, point3dCollection, array, i, 0.02, 0.9, 1); dbc.Remove(polyline); IList <Zdinfo> list3 = JzdService.DBCToZdinfo(dbc); ; if (num5 < 0.0 && num3 < 40.0) { switch (i) { case 0: dbcs[0] = dbc; break; case 1: dbcs[1] = dbc; break; case 2: dbcs[2] = dbc; break; case 3: dbcs[3] = dbc; break; } } else { switch (i) { case 0: dbcs[1] = dbc; break; case 1: dbcs[2] = dbc; break; case 2: dbcs[3] = dbc; break; case 3: dbcs[0] = dbc; break; } } } return(dbcs); }
/** * @brief Metodo que descompone una enitdad AUTOCAD en sub-entidades cuando es posible. Replica el comportamiento del comando * DESCOMPONER / EXPLODE de AutoCAD. Las unidades básicas que devuelve son puntos y lineas. Descompone recursivamente * las entidades hasta dejarlas representadas como puntos, lineas y arcos. * * @param ent Entidad que debe ser descompuesta * @param acBlkTbl Tabla de bloques de AutoCAD para buscar nuevos objetos y añadir nuevos objetos generados. * @param acBlkTblRec Tabla de registros de los bloques de AutoCAD para buscar nuevos objetos y añadir nuevos objetos generados. * @param t Transaccion abierta para manipular la tabla de bloques de AutoCAD. * * @return Devuelve una colección de entidades bajo la clase DBObjectCollection. **/ private static DBObjectCollection ObtenerPuntosyLineas(Entity ent, BlockTable acBlkTbl, BlockTableRecord acBlkTblRec, Transaction t) { DBObjectCollection retorno = new DBObjectCollection(); DBObjectCollection procesar = new DBObjectCollection(); ent.Explode(procesar); while (procesar.Count != 0) { Entity obj = (Entity) procesar[0]; acBlkTblRec.AppendEntity(obj); t.AddNewlyCreatedDBObject(obj, true); dwgf.objetosArtificiales.Add(obj.ObjectId); if (obj.ObjectId.ObjectClass.DxfName == "POINT" || obj.ObjectId.ObjectClass.DxfName == "LINE") { if (retorno.Contains(obj) == false) { retorno.Add(obj); } } if (obj.ObjectId.ObjectClass.DxfName == "ARC") { // Completar con el proceso para los arcos. if (retorno.Contains(obj) == false) { retorno.Add(obj); } } if (obj.ObjectId.ObjectClass.DxfName == "LWPOLYLINE") { DBObjectCollection aux = new DBObjectCollection(); obj.Explode(aux); foreach (DBObject aux2 in aux) { procesar.Add(aux2); } } procesar.Remove(obj); } return retorno; }