.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem about Getting OutermostIntersectionPoints of line and dynamic block reference

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
22951050
249 Views, 2 Replies

problem about Getting OutermostIntersectionPoints of line and dynamic block reference

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!

outermost.png

 

 

2 REPLIES 2
Message 2 of 3
22951050
in reply to: 22951050

it seems all the visibility entities are created when using .Explode() method.

is there a way to get entities in current visibility only?

Message 3 of 3
22951050
in reply to: 22951050

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.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report