How to break a curve in a blockreference?

How to break a curve in a blockreference?

swaywood
Collaborator Collaborator
1,296 Views
11 Replies
Message 1 of 12

How to break a curve in a blockreference?

swaywood
Collaborator
Collaborator

Hi,

 

I konw there is a method GetSplitCurves

 

DBObjectCollection tmpSplittedCurves = curvLine.GetSplitCurves(pts);

 

Use this can split a curve into several picies curves.

 

but i do not know how to split curves in a blockreference.

 

thanks

 

0 Likes
Accepted solutions (1)
1,297 Views
11 Replies
Replies (11)
Message 2 of 12

_gile
Consultant
Consultant

Hi,

You cannot edit entities in a BlockReference, you can only do it in its BlockTableRecord and the changes will affect all inserted references.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 12

swaywood
Collaborator
Collaborator

Hi Gile,

Thank you for your reply.

Yes , I had make a mistake.

I wanna edit the blocktablerecord, and it will effect its copies(blockreference).

But, I do not know how to edit a blocktablerecord.

Could you give me some code for spliting a curve into several pieces in a blockrecord?

 
0 Likes
Message 4 of 12

swaywood
Collaborator
Collaborator

please see the attached pics.

0 Likes
Message 5 of 12

_gile
Consultant
Consultant

Assuming the user have to specify the break points, why not doing it with native commands as _BEDIT or _REFEDIT ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 12

_gile
Consultant
Consultant

Anyway, here's an example.

 

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

using AcAp = Autodesk.AutoCAD.ApplicationServices.Core.Application;

namespace BreakCurveInBlockSample
{
    public class Commands
    {
        [CommandMethod("NESTEDBREAK")]
        public static void BreakCurveInBlock()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                PromptNestedEntityResult pner;
                while (true)
                {
                    pner = ed.GetNestedEntity("\nSelect curve in block: ");
                    if (pner.Status != PromptStatus.OK)
                        return;
                    if (!pner.ObjectId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Curve))))
                        ed.WriteMessage("\nSelected object is not a curve.");
                    else if (pner.GetContainers().Length == 0)
                        ed.WriteMessage("\nSelected curve is not nested.");
                    else
                        break;
                }
                var curve = (Curve)tr.GetObject(pner.ObjectId, OpenMode.ForWrite);
                var xform = pner.Transform.Inverse() * ed.CurrentUserCoordinateSystem;

                bool tryGetPointonCurve(string message, out Point3d point)
                {
                    var ppr = ed.GetPoint($"\n{message}");
                    if (ppr.Status != PromptStatus.OK)
                    {
                        point = Point3d.Origin;
                        return false;
                    }
                    var pt = ppr.Value.TransformBy(xform);
                    using (var view = ed.GetCurrentView())
                    {
                        point = curve.GetClosestPointTo(pt, view.ViewDirection, false);
                    }
                    return true;
                }

                if (!tryGetPointonCurve("\nSpecify first point: ", out Point3d pt1))
                    return;
                if (!tryGetPointonCurve("\nSpecify second point: ", out Point3d pt2))
                    return;
                if (!tryGetPointonCurve("\nSpecify a point on the part to delete: ", out Point3d pt3))
                    return;
                var points = new Point3dCollection();
                if (curve.GetParameterAtPoint(pt1) < curve.GetParameterAtPoint(pt2))
                {
                    points.Add(pt1);
                    points.Add(pt2);
                }
                else
                {
                    points.Add(pt2);
                    points.Add(pt1);
                }
                var btr = (BlockTableRecord)tr.GetObject(curve.OwnerId, OpenMode.ForWrite);
                var curves = curve.GetSplitCurves(points);
                foreach (Curve c in curves)
                {
                    if (c.GetClosestPointTo(pt3, false).IsEqualTo(pt3))
                    {
                        c.Dispose();
                    }
                    else
                    {
                        btr.AppendEntity(c);
                        tr.AddNewlyCreatedDBObject(c, true);
                    }
                }
                curve.Erase();
                tr.Commit();
            }
            ed.Regen();
        }
    }
}


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 12

swaywood
Collaborator
Collaborator

Hi, Gile:

because this way is more easier for user.

0 Likes
Message 8 of 12

swaywood
Collaborator
Collaborator

Gile:

thank you for your kindly help.

in your code, there are 4 steps,

step 1 is select curve, step 4 is select son curve need be deleted.

is there any way to cancel step 1 through step 4?

because step 4 curve is the same curve before split.

but i do not know how to transform the pt3,

and then use 

public Point3d NonInteractivePickPoint { get; set; }
public bool UseNonInteractivePickPoint { get; set; }

of PromptNestedEntityOptions

to get the nested curve.

please help me, thanks

0 Likes
Message 9 of 12

_gile
Consultant
Consultant
Accepted solution
        [CommandMethod("NESTEDBREAK")]
        public static void BreakCurveInBlock()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                PromptNestedEntityResult pner;
                while (true)
                {
                    pner = ed.GetNestedEntity("\nSelect curve in block (on the part to remove): ");
                    if (pner.Status != PromptStatus.OK)
                        return;
                    if (!pner.ObjectId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Curve))))
                        ed.WriteMessage("\nSelected object is not a curve.");
                    else if (pner.GetContainers().Length == 0)
                        ed.WriteMessage("\nSelected curve is not nested.");
                    else
                        break;
                }
                var curve = (Curve)tr.GetObject(pner.ObjectId, OpenMode.ForWrite);
                var xform = pner.Transform.Inverse() * ed.CurrentUserCoordinateSystem;
                var pt3 = pner.PickedPoint.TransformBy(xform);
                using (var view = ed.GetCurrentView())
                {
                    pt3 = curve.GetClosestPointTo(pt3, view.ViewDirection, false);
                }

                bool tryGetPointonCurve(string message, out Point3d point)
                {
                    var ppr = ed.GetPoint($"\n{message}");
                    if (ppr.Status != PromptStatus.OK)
                    {
                        point = Point3d.Origin;
                        return false;
                    }
                    var pt = ppr.Value.TransformBy(xform);
                    using (var view = ed.GetCurrentView())
                    {
                        point = curve.GetClosestPointTo(pt, view.ViewDirection, false);
                    }
                    return true;
                }

                if (!tryGetPointonCurve("\nSpecify first point: ", out Point3d pt1))
                    return;
                if (!tryGetPointonCurve("\nSpecify second point: ", out Point3d pt2))
                    return;
                var points = new Point3dCollection();
                if (curve.GetParameterAtPoint(pt1) < curve.GetParameterAtPoint(pt2))
                {
                    points.Add(pt1);
                    points.Add(pt2);
                }
                else
                {
                    points.Add(pt2);
                    points.Add(pt1);
                }
                var btr = (BlockTableRecord)tr.GetObject(curve.OwnerId, OpenMode.ForWrite);
                var curves = curve.GetSplitCurves(points);
                foreach (Curve c in curves)
                {
                    if (c.GetClosestPointTo(pt3, false).IsEqualTo(pt3))
                    {
                        c.Dispose();
                    }
                    else
                    {
                        btr.AppendEntity(c);
                        tr.AddNewlyCreatedDBObject(c, true);
                    }
                }
                curve.Erase();
                tr.Commit();
            }
            ed.Regen();
        }

I find it strange that you have so many blocks to modify this way, so much that you need a program.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 10 of 12

swaywood
Collaborator
Collaborator

Hi, Gile:

Many users are not familiar with editing a block reference.

Especially the block with attributes.

In this case, they usually try to break up the block references.

And that's not what I want, because there's a lot of XDATA in the block.

That's why I need a program.

 

could you tell me how to select the curve in blockreference by pt3 selently.

thanks.

0 Likes
Message 11 of 12

_gile
Consultant
Consultant

In my last attempt, the pt3 is got from the curve selection (PickedPoint) and it is the simplest way to get it. So there're only 3 inputs.

If you absolutely need to do it in the reverse way (pick a point and get the entity with NonInteractivePickPoint), you need to set the NonInteractivePickPoint with pt3, and check the result of PromptNestedEntityResult.

I have no time to this right now, but you should be able to do it by yourself.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 12 of 12

swaywood
Collaborator
Collaborator

Hi,Gile:

I Had finished the program,

and known how to edit a entity in a blocktablerecord.

Thanks so much.

 

0 Likes