Hi! I'm new to here and i'm learning a lot from this forum. really thanks.
I have found some code of Gile that getting OuterMost Intersection Points of Line and Block Reference
first, it explodes the block reference and getting all intersection points of line and new objects(by explode)
then, find shortest distance from startpoint and endpoint of the line.
I wanted to use it to trim(break) with that OuterMostpoints (with GetSplitCurves Method),
and as long as if the block reference is a static block reference, it works perfectly,
but dynamic block reference, it doesn't.
here is my code
public static void TrimLinesByBlockReferences()
{
var adoc = CadApp.DocumentManager.MdiActiveDocument;
var db = adoc.Database;
var ed = adoc.Editor;
using (var tx = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tx.GetObject(db.BlockTableId, OpenMode.ForRead);
var ms = (BlockTableRecord)tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
var op = new PromptSelectionOptions();
op.MessageForAdding = "\nSelect Entities:";
var filter = new SelectionFilter(new TypedValue[]
{
new TypedValue((int)DxfCode.Start, "INSERT,LINE"),
});
var rs = ed.GetSelection(op, filter);
if (rs.Status != PromptStatus.OK) return;
var lines = (from id in rs.Value.GetObjectIds()
let ent = tx.GetObject(id, OpenMode.ForRead)
where ent is Line
select ent as Curve).ToList();
var brs = (from id in rs.Value.GetObjectIds()
let ent = tx.GetObject(id, OpenMode.ForRead)
where ent is BlockReference
select ent as BlockReference).ToList();
foreach (var br in brs)
{
lines = TrimLinesByBlockReference(br, lines);
}
tx.Commit();
}
}
private static List<Curve> TrimLinesByBlockReference(
BlockReference br, List<Curve> lines)
{
var newCurveList = new List<Curve>();
foreach (var line in lines)
{
if (Modules.FindOutmostIntersectingPoints(line as Line, br, out Point3d pt1, out Point3d pt2))
{
var result = Modules.BreakLineOrPolyline(line.ObjectId, pt1, pt2);
if (result != null && result.Count > 0)
{
newCurveList.AddRange(result.OfType<Curve>());
}
else newCurveList.Add(line);
}
else
{
newCurveList.Add(line);
}
}
return newCurveList;
}
below 3 methods are in 'Modules' Class
public static List<Point3d> GetAllIntersectingPoints(
Line line, BlockReference br)
{
var points = new List<Point3d>();
using (var ents = new DBObjectCollection())
{
if (br.IsDynamicBlock) br.ConvertToStaticBlock();
br.Explode(ents);
foreach (Entity ent in ents)
{
var pts = new Point3dCollection();
line.IntersectWith(
ent, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
foreach (Point3d p in pts)
{
points.Add(p);
}
ent.Dispose();
}
}
return points;
}
public static bool FindOutmostIntersectingPoints(
Line line, BlockReference br, out Point3d pt1, out Point3d pt2)
{
pt1 = Point3d.Origin;
pt2 = Point3d.Origin;
var points = GetAllIntersectingPoints(line, br);
// Check for the Points
//var adoc = CadApp.DocumentManager.MdiActiveDocument;
//var db = adoc.Database;
//using (Transaction tx = db.TransactionManager.StartTransaction()){
// var bt = (BlockTable)tx.GetObject(db.BlockTableId, OpenMode.ForRead);
// var ms = (BlockTableRecord)tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
// db.Pdmode = 34;
// DBPoint dbpt;
// foreach (var point in points)
// {
// dbpt = new DBPoint(point);
// ms.AppendEntity(dbpt);
// tx.AddNewlyCreatedDBObject(dbpt, true);
// }
// tx.Commit();
//}
if (points.Count > 0)
{
pt1 = (from p in points
orderby p.DistanceTo(line.StartPoint)
select p).First();
pt2 = (from p in points
orderby p.DistanceTo(line.EndPoint)
select p).First();
return true;
}
else
{
return false;
}
}
public static DBObjectCollection BreakLineOrPolyline(ObjectId curveId, Point3d pt1, Point3d pt2)
{
var doc = CadApp.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
using (var tr = db.TransactionManager.StartTransaction())
{
Curve curve;
try
{
curve = (Curve)tr.GetObject(curveId, OpenMode.ForWrite);
}
catch (Exception e)
{
return null;
}
if (!(curve is Line || curve is Polyline)) return null;
double param1 = curve.GetParameterAtPoint(curve.GetClosestPointTo(pt1, false));
double param2 = curve.GetParameterAtPoint(curve.GetClosestPointTo(pt2, false));
var parameters = new DoubleCollection
(new[] { param1, param2 }
.Distinct()
.OrderBy(x => x)
.ToArray());
var curves = curve.GetSplitCurves(parameters);
var curSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
switch (curves.Count)
{
case 3:
curSpace.AppendEntity((Entity)curves[0]);
tr.AddNewlyCreatedDBObject(curves[0], true);
curSpace.AppendEntity((Entity)curves[2]);
tr.AddNewlyCreatedDBObject(curves[2], true);
curves[1].Dispose();
curves.RemoveAt(1);
curve.Erase();
break;
case 2:
curSpace.AppendEntity((Entity)curves[0]);
tr.AddNewlyCreatedDBObject(curves[0], true);
curSpace.AppendEntity((Entity)curves[1]);
tr.AddNewlyCreatedDBObject(curves[1], true);
curve.Erase();
break;
default:
break;
}
tr.Commit();
return curves;
}
}
by uncomment 'Check for the points' in 'FindOutMostIntersectingPoints' method,
it creates point objects to all the intersected points.
thanks!
Solved! Go to Solution.
Solved by 22951050. Go to Solution.
it seems all the visibility entities are created when using .Explode() method.
is there a way to get entities in current visibility only?
Self Answer
I have found a solution in this link
the entities created by explode method are following their visibility of dynamic block reference,
so before check the intersection, just check if the Visible property is true.
br.Explode(ents);
foreach (Entity ent in ents)
{
// check if the entity is visible
if (ent.Visible == true)
{
var pts = new Point3dCollection();
line.IntersectWith(
ent, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
foreach (Point3d p in pts)
{
points.Add(p);
}
}
ent.Dispose();
}
Can't find what you're looking for? Ask the community or share your knowledge.