Eğrisel Nesnelerin Kırılması
ARC, CIRCLE, LWPOLYLINE, LINE, SPLINE ve ELLIPSE nesnelerinin AutoCAD.Net API’si ile nasıl kırılabileceğini aşağıdaki BreakCurveObjects() yordamında bulabilirsiniz. Bu yordam, belirlenen noktalarda nesneleri kırmak için, Curve sınıfına ait GetSplitCurves(…) üyesini kullanıyor.
public virtual DBObjectCollection GetSplitCurves(DoubleCollection value);
public virtual DBObjectCollection GetSplitCurves(Point3dCollection points);
Kodla ilgili birkaç önemli noktaya dikkat etmekte fayda var;
- Kodun kullanıcı tanımlı koordinat sistemlerinde de çalışabilmesi için seçilen noktaları WCS’ye dönüştürmeyi unutmamak gerek. Çünkü GetPoint(…) yordamı ile elde edilen tüm noktalar kullanıcı tanımlı koordinat sistemindedir.
- Seçtiğiniz noktaların kırmak istediğiniz nesne üzerinde olup olmadığı doğrulanmalı. Bunun için IsPointOnCurve(…) yordamı kullanılmıştır.
- GetSplitCurves(…) yordamına geçirilecek nokta listelerini eğrinin başlangıcına göre mutlaka sıralanmalı. Aksi takdirde noktaları seçim sıranıza bağlı olarak beklediğinizden farklı sonuçlarla karşılaşabilirsiniz.
public static void BreakCurveObjects()
{
// Autocad veritabanına erişim
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
// Daire ve elips nesnelerinin seçimi için seçim filtresi oluşturulması
TypedValue[] tyVals = new TypedValue[8]
{
new TypedValue(-4, "<OR"),
new TypedValue((int)DxfCode.Start, "SPLINE"),
new TypedValue((int)DxfCode.Start, "LINE"),
new TypedValue((int)DxfCode.Start, "ARC"),
new TypedValue((int)DxfCode.Start, "LWPOLYLINE"),
new TypedValue((int)DxfCode.Start, "CIRCLE"),
new TypedValue((int)DxfCode.Start, "ELLIPSE"),
new TypedValue(-4, "OR>")
};
SelectionFilter selFilter = new SelectionFilter(tyVals);
// Daire ya da elips nesnesinin seçilmesi
PromptSelectionOptions pSelOpts = new PromptSelectionOptions();
pSelOpts.AllowDuplicates = false;
pSelOpts.SingleOnly = true;
PromptSelectionResult pSelRes = doc.Editor.GetSelection(pSelOpts, selFilter);
if (pSelRes.Status == PromptStatus.OK)
{
Point3dCollection breakPoints = new Point3dCollection();
DoubleCollection distOfBreakPoints = new DoubleCollection();
// Kırma noktası seçimi için seçenekler
PromptPointOptions pPtOpts = new PromptPointOptions("");
pPtOpts.Message = "\nSelect break point: ";
pPtOpts.AllowNone = true;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
PromptPointResult pPtRes;
// Seçilen eğrinin yazma amaçlı açılması
Curve curve = (Curve)tr.GetObject(pSelRes.Value.GetObjectIds()[0], OpenMode.ForWrite);
// Kırma noktalarının seçilmesi
do
{
pPtRes = doc.Editor.GetPoint(pPtOpts);
// Seçilen koordinatın WCS'ye dönüştürülmesi
Point3d breakPntWCS = pPtRes.Value.TransformBy(ed.CurrentUserCoordinateSystem);
// Seçilen noktanın eğri üzerinde olup olmadığının kontrolü
if (IsPointOnCurve(curve, breakPntWCS))
{
breakPoints.Add(curve.GetClosestPointTo(breakPntWCS, false));
distOfBreakPoints.Add(curve.GetDistAtPoint(breakPntWCS));
}
else
{
ed.WriteMessage("\nSelected point is not on curve!");
}
}
while (pPtRes.Status == PromptStatus.OK);
if (breakPoints.Count > 0)
{
// Noktaların eğri başlangıcına göre sıralanması
double[] rawPoints = distOfBreakPoints.ToArray();
Array.Sort(rawPoints);
Point3dCollection sortedBreakPoints = new Point3dCollection();
foreach (double item in rawPoints)
{
sortedBreakPoints.Add(breakPoints[distOfBreakPoints.IndexOf(item)]);
}
// Sıralanmış noktalara göre eğri parçalarının elde edilmesi
DBObjectCollection objs = curve.GetSplitCurves(sortedBreakPoints);
// Eğri parçalarının çizime eklenmesi
if (objs != null)
{
if (objs.Count > 0)
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
foreach (var obj in objs)
{
Entity ent = obj as Entity;
BlockTableRecord btRecord = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite, false);
btRecord.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
// Orjinal eğrinin silinmesi
curve.Erase();
tr.Commit();
}
}
}
}
}
}
private static bool IsPointOnCurve(Curve crv, Point3d pt)
{
try
{
Point3d p = crv.GetClosestPointTo(pt, false);
return (p - pt).Length <= Tolerance.Global.EqualPoint;
}
catch { }
return false;
}
BreakObjectByObject() yordamı ise eğrisel nesnelerin kesişim noktalarını esas alarak kırma işlemi gerçekleştiriyor.
public static void BreakObjectByObject()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
PromptEntityOptions pEntOpt = new PromptEntityOptions("");
pEntOpt.AllowNone = false;
pEntOpt.Message = "\nSelect a object to break: ";
pEntOpt.SetRejectMessage("\nSelect Arc, Circle, Ellipse, Line, Polyline ve Spline!");
pEntOpt.AddAllowedClass(typeof(Arc), true);
pEntOpt.AddAllowedClass(typeof(Circle), true);
pEntOpt.AddAllowedClass(typeof(Ellipse), true);
pEntOpt.AddAllowedClass(typeof(Line), true);
pEntOpt.AddAllowedClass(typeof(Polyline), true);
pEntOpt.AddAllowedClass(typeof(Spline), true);
PromptEntityResult pEntResObjectToBreak = ed.GetEntity(pEntOpt);
if (pEntResObjectToBreak.Status != PromptStatus.OK)
return;
pEntOpt.Message = "\nSelect breaking object: ";
PromptEntityResult pEntResBreakinObject = ed.GetEntity(pEntOpt);
if (pEntResBreakinObject.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Curve objectToBreak = (Curve)tr.GetObject(pEntResObjectToBreak.ObjectId, OpenMode.ForWrite);
Curve breakinObject = (Curve)tr.GetObject(pEntResBreakinObject.ObjectId, OpenMode.ForRead);
Point3dCollection intersectPts = new Point3dCollection();
objectToBreak.IntersectWith(breakinObject, Intersect.OnBothOperands, intersectPts, IntPtr.Zero, IntPtr.Zero);
if (intersectPts.Count != 0)
{
DoubleCollection distOfBreakPoints = new DoubleCollection();
foreach (Point3d pt in intersectPts)
{
distOfBreakPoints.Add(objectToBreak.GetDistAtPoint(pt));
}
double[] rawPoints = distOfBreakPoints.ToArray();
Array.Sort(rawPoints);
Point3dCollection sortedBreakPoints = new Point3dCollection();
foreach (double item in rawPoints)
{
sortedBreakPoints.Add(intersectPts[distOfBreakPoints.IndexOf(item)]);
}
DBObjectCollection objs = objectToBreak.GetSplitCurves(sortedBreakPoints);
if (objs != null)
{
if (objs.Count > 0)
{
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead, false);
foreach (var obj in objs)
{
Entity ent = obj as Entity;
BlockTableRecord btRecord = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite, false);
btRecord.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
objectToBreak.Erase();
tr.Commit();
}
}
}
}
}
Yorum yapın