using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using AcBr = Autodesk.AutoCAD.BoundaryRepresentation;
using Platform = Autodesk.AutoCAD;
using PlatformDb = Autodesk.AutoCAD;
[assembly: CommandClass(typeof(Rivilis.PolyUtils))]
namespace Rivilis
{
public class PolyUtils
{
[CommandMethod("slicetest")]
public static void sliceinside()
{
bool crossing = true; string filter = "LWPOLYLINE";
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
TypedValue[] filList = new TypedValue[1] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };
SelectionFilter sfilter = new SelectionFilter(filList);
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\nВыбирете полилинию";
PromptSelectionResult per = ed.GetSelection(pso, sfilter);
if (per.Status == PromptStatus.OK)
{
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable acBlkTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord acBlkTblRec = tr.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
try
{
SelectionSet acSSet = per.Value;
foreach (SelectedObject acSSObj in acSSet)
{
Polyline pline = new Polyline();
DBObject obj = (DBObject)tr.GetObject(acSSObj.ObjectId, OpenMode.ForRead);
if (obj is Polyline)
{
pline = (Polyline)obj;
PromptSelectionResult selection = SelectByPolyline(ed, pline, crossing, new TypedValue(0, filter));
SelectionSet selSet = selection.Value;
// //
DBObjectCollection dbCurvs = new DBObjectCollection();
foreach (ObjectId id in selection.Value.GetObjectIds())
{
Curve curve = tr.GetObject(id, OpenMode.ForRead) as Curve;
if (curve != null)
{
dbCurvs.Add(curve);
}
}
foreach (Curve curve in dbCurvs)
{
using (DBObjectCollection dbcol1 = new DBObjectCollection())
using (DBObjectCollection dbcol2 = new DBObjectCollection())
{
dbcol1.Add(pline as Curve); dbcol2.Add(curve);
DBObjectCollection regs1 = null, regs2 = null;
// Преобразуем полилинии в области
try
{
regs1 = Region.CreateFromCurves(dbcol1);
regs2 = Region.CreateFromCurves(dbcol2);
}
catch { };
if (regs1 != null & regs2 != null &&
regs1.Count == 1 && regs2.Count == 1)
{
Region reg1 = regs1[0] as Region, reg2 = regs2[0] as Region;
Region reg1Clone = reg1.Clone() as Region;
Region reg2Clone = reg2.Clone() as Region;
// Это будет внешняя часть
reg2Clone.BooleanOperation(BooleanOperationType.BoolSubtract, reg1Clone);
CreatePolyLinesFromRegion(reg2Clone, acBlkTblRec);
reg1Clone.Dispose(); reg2Clone.Dispose();
reg1Clone = reg1.Clone() as Region;
reg2Clone = reg2.Clone() as Region;
// Это будет внутренняя часть
reg2Clone.BooleanOperation(BooleanOperationType.BoolIntersect, reg1Clone);
CreatePolyLinesFromRegion(reg2Clone, acBlkTblRec);
reg1Clone.Dispose(); reg2Clone.Dispose();
reg1.Dispose(); reg2.Dispose();
Curve curveDel = tr.GetObject(curve.ObjectId, OpenMode.ForWrite) as Curve;
curveDel.Erase(); // Удаляем отрезаемый контур
}
}
}
}
}
tr.Commit();
}
catch (PlatformDb.Runtime.Exception Ex) { ed.WriteMessage("Ошибка: " + Ex.Message); }
}
}
}
public static void CreatePolyLinesFromRegion(Region reg, BlockTableRecord btr)
{
if (!reg.IsNull)
{
Transaction tr = btr.Database.TransactionManager.TopTransaction;
using (AcBr.Brep brep = new AcBr.Brep(reg))
{
foreach (AcBr.Face face in brep.Faces)
{
foreach (AcBr.BoundaryLoop loop in face.Loops)
{
int iVert = 0;
Polyline pl = new Polyline();
foreach (AcBr.Vertex p in loop.Vertices)
{
pl.AddVertexAt(iVert++, new Point2d(p.Point.X, p.Point.Y), 0, 0, 0);
}
pl.Closed = true;
btr.AppendEntity(pl);
tr.AddNewlyCreatedDBObject(pl, true);
LayerTable ltb = (LayerTable)tr.GetObject(btr.Database.LayerTableId, OpenMode.ForRead);
if (!ltb.Has("narezka"))
{
ltb.UpgradeOpen();
LayerTableRecord newLayer = new LayerTableRecord();
newLayer.Name = "narezka";
ltb.Add(newLayer);
tr.AddNewlyCreatedDBObject(newLayer, true);
}
pl.LayerId = ltb["narezka"];
}
}
}
}
}
public static PromptSelectionResult SelectByPolyline(Editor ed, Polyline pline, bool mode, params TypedValue[] filter)
{
Point3dCollection polygon = new Point3dCollection();
for (int i = 0; i < pline.NumberOfVertices; i++)
{
polygon.Add(pline.GetPoint3dAt(i));
}
PromptSelectionResult result;
ViewTableRecord view = ed.GetCurrentView();
Zoom(ed, pline.GeometricExtents);
if (mode)
result = ed.SelectCrossingPolygon(polygon, new SelectionFilter(filter));
else
result = ed.SelectWindowPolygon(polygon, new SelectionFilter(filter));
ed.SetCurrentView(view);
return result;
}
public static void Zoom(Editor ed, Extents3d extents)
{
using (ViewTableRecord view = ed.GetCurrentView())
{
Matrix3d worldToEye =
Matrix3d.Rotation(-view.ViewTwist, view.ViewDirection, view.Target) *
Matrix3d.Displacement(view.Target - Point3d.Origin) *
Matrix3d.PlaneToWorld(view.ViewDirection)
.Inverse();
extents.TransformBy(worldToEye);
view.Width = extents.MaxPoint.X - extents.MinPoint.X;
view.Height = extents.MaxPoint.Y - extents.MinPoint.Y;
view.CenterPoint = new Point2d(
(extents.MaxPoint.X + extents.MinPoint.X) / 2.0,
(extents.MaxPoint.Y + extents.MinPoint.Y) / 2.0);
ed.SetCurrentView(view);
}
}
}
}