Custom Objects With .NET

Custom Objects With .NET

Anonymous
Not applicable
4,290 Views
12 Replies
Message 1 of 13

Custom Objects With .NET

Anonymous
Not applicable

Hi all, I will better explain my question with a concrete simple example.

Let's say I want to build a command 2CIRCLE in .NET which would create two concentric circles where the inner one's radius is half of the outer one's radius.

I can see how to create this command, but what I cannot see at the moment is how to edit it later on. If someone selects it later on by clicking on either of the circles:

  1. both circles (the whole custom object) should be selected.
  2. editing an inner circle's radius (with the mouse) should be allowed but it should always affect the outer circle as the outer circle's radius should always be kept at double inner circle's radius length.

Is this possible with .NET or it has to be done with C++?

Thanks very much.

0 Likes
Accepted solutions (1)
4,291 Views
12 Replies
Replies (12)
Message 2 of 13

_gile
Consultant
Consultant
Accepted solution

Hi,

 

You cannot create custom object with the .NET API but you can use the Overrule API.

 

Here's a little example.

using Autodesk.AutoCAD.GraphicsInterface;

using AcDb = Autodesk.AutoCAD.DatabaseServices;

namespace CircleOverrruleSample
{
    class CircleOverrule : DrawableOverrule
    {
        public static string RegAppName => "Gile_ConcentricCircles";

        public CircleOverrule()
        {
            AddOverrule(GetClass(typeof(AcDb.Circle)), this, true);
            SetXDataFilter(RegAppName);
            Overruling = true;
        }

        public override bool WorldDraw(Drawable drawable, WorldDraw wd)
        {
            var circle = (AcDb.Circle)drawable;
            wd.Geometry.Circle(circle.Center, circle.Radius, circle.Normal);
            wd.Geometry.Circle(circle.Center, circle.Radius / 2.0, circle.Normal);
            return true;
        }
    }
}
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;

namespace CircleOverrruleSample
{
    class CircleJig : EntityJig
    {
        Circle circle;
        double radius;

        public CircleJig(Circle circle) : base(circle)
        {
            this.circle = circle;
            radius = circle.Radius;
        }
        protected override SamplerStatus Sampler(JigPrompts prompts)
        {
            var options = new JigPromptDistanceOptions("\nSpecify the radius; ");
            options.BasePoint = circle.Center;
            options.UseBasePoint = true;
            options.UserInputControls =
                UserInputControls.Accept3dCoordinates | 
                UserInputControls.NoNegativeResponseAccepted | 
                UserInputControls.NoZeroResponseAccepted;
            var result = prompts.AcquireDistance(options);
            if (result.Value == radius)
                return SamplerStatus.NoChange;
            radius = result.Value;
            return SamplerStatus.OK;
        }

        protected override bool Update()
        {
            circle.Radius = radius;
            return true;
        }
    }
}
using System;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;

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

namespace CircleOverrruleSample
{
    public class Initialization : IExtensionApplication
    {
        DocumentCollection docs = AcAp.DocumentManager;
        static CircleOverrule overrule;

        public void Initialize()
        {
            overrule = new CircleOverrule();
            AcAp.Idle += OnIdle;
        }

        private void OnIdle(object sender, EventArgs e)
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            if (doc != null)
            {
                AcAp.Idle -= OnIdle;
                doc.Editor.WriteMessage("\nCircleOverrruleSample loaded.\n");
            }
        }

        public void Terminate()
        { }
    }
}
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

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

[assembly: CommandClass(typeof(CircleOverrruleSample.Commands))]

namespace CircleOverrruleSample
{
    public class Commands
    {
        [CommandMethod("2CIRCLE")]
        public static void TwoCircleCommand()
        {
            var doc = AcAp.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var ppr = ed.GetPoint("\nSpecify the center; ");
            if (ppr.Status == PromptStatus.OK)
            {
                using (var tr = db.TransactionManager.StartTransaction())
                {
                    var cSpace = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
                    var circle = new Circle(ppr.Value, Vector3d.ZAxis, 1.0);
                    cSpace.AppendEntity(circle);
                    tr.AddNewlyCreatedDBObject(circle, true);
                    using (var data = new ResultBuffer(
                    new TypedValue(1001, CircleOverrule.RegAppName),
                    new TypedValue(1000, "Dummy text")))
                    {
                        AddXdata(circle, data);
                    }
                    var jig = new CircleJig(circle);
                    var pr = ed.Drag(jig);
                    if (pr.Status != PromptStatus.OK)
                    {
                        circle.Erase();
                    }
                        tr.Commit();
                }
            }
        }

        private static void AddXdata(DBObject dbObj, ResultBuffer data)
        {
            var db = dbObj.Database;
            var tr = db.TransactionManager.TopTransaction;
            var regAppName = (string)data.AsArray()[0].Value;
            var regAppTable = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
            if (!regAppTable.Has(regAppName))
            {
                var regApp = new RegAppTableRecord() { Name = regAppName };
                regAppTable.UpgradeOpen();
                regAppTable.Add(regApp);
                tr.AddNewlyCreatedDBObject(regApp, true);
            }
            dbObj.XData = data;
        }
    }
}

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 13

Anonymous
Not applicable

Hey Gile!

Can you send me your soluttion file? I am very grateful for that. 

My email is: hungspkt123@gmail.com

Thanks you!

0 Likes
Message 4 of 13

_gile
Consultant
Consultant

@Anonymous 

I do not understand why you want a solution which you'll probably have to edit to match your computer architecture rather than build it by yourself with the source code I provided.

Anyway, I attached the whole solution for Visual Studio 2017.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 13

Kélcyo
Advocate
Advocate

Starting from the base of your code, it is possible to create a 3D polyline with 3 vertices that represents 2 tangents and the central point a point of inflection. And an arc that has its start and end point limited to displacements on top of the tangents? That is, the grips of the 3D polyline, adjust the arc with the beginning and end always touching the tangents, while the grips of the arc, only move on top of the tangent sizing its length...

0 Likes
Message 6 of 13

_gile
Consultant
Consultant

Hi,

I'm sorry, I do not understand what you describe. May be a drawing should be more descriptive.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 13

Kélcyo
Advocate
Advocate

I believe this illustration is understandable. The Tangents of the 3D Polyline are the rails limiting the movement of the Arc's points. The grips (points of the 3D Polyline) are free to change and after any adjustment, the Arc is automatically adjusted to the new location, maintaining its previous length.

Captura de tela 2024-05-04 053456.png

0 Likes
Message 8 of 13

_gile
Consultant
Consultant

You do not provide enough informations.

How are the points of tangency between the arc and the polyline segments determined?

Is the arc radius fixed? If so, what happens if a polyline segment is too short?

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 13

ActivistInvestor
Mentor
Mentor

The fact that you show an oblique view of a two-dimensional drawing with text is enough for me to head for the nearest exit. 

0 Likes
Message 10 of 13

Kélcyo
Advocate
Advocate
The three points are obtained by 3 vertices of a polyline3d, while the arc has a fixed length, which is adjusted the radius, according to the angle between the two 3D tangents. However, if one of the segments of the polyline3d that form the tangents, is smaller than the tangent allowed by the radius that determines the fixed length, the arc is automatically reset to have the point with a limit slightly smaller than the tangent on its side, so that it does not occur from the initial or end point of the polyline3d coincide with the same of the arc.
0 Likes
Message 11 of 13

Kélcyo
Advocate
Advocate
It is not about objects in 2 dimensions, the oblique way of representing was only for a better description of the items involved, the polyline is 3d, and the arc touches its tangents
0 Likes
Message 12 of 13

Kélcyo
Advocate
Advocate

I will try to give a more detailed explanation about my construction of objects

1-we obtain two 3d points that have their claws shown to be changed

2-we draw an imaginary line that connects the two points, this imaginary line is the position track of another 3d point which has limits at the beginning and end so as not to coincide with the previous points

3- the tangent is formed and the point that moves first on the track would be the starting or ending point of the arc

4- repeat the process, making one of the points of the second process were coincident and formed an inflection point, we would now have 3 points that form two imaginary lines where they move along them, two points that are the initial and final points of an arc with fixed length and variable radius

5-by moving one of the points of the arc, the other also moves on the other tangent symmetrically, changing its length and blocking the limits on both sides of the tangents

0 Likes
Message 13 of 13

_gile
Consultant
Consultant

I'm sorry, it's still confusing for me.

You should start another topic trying to describe precisely what are the input data (e.g., a 3d polyline and the constraints of the arc with respect to the polyline).



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes