Author Topic: AddVertexAt  (Read 8527 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
AddVertexAt
« on: November 08, 2007, 09:08:26 AM »
If you don't know the amount of verticies required when you create the pline and you want to keep adding verticies or if you want to add a verticie to an existing pline, I seem to get an elock problem.
oPline.UpgradeOpen(); doesn't seem to help.
When adding a new entity, the blocktable and the BlockTableRecord need OpenMode.ForWrite, is this necessary for modifying an entity?

MickD

  • King Gator
  • Posts: 3637
  • (x-in)->[process]->(y-out) ... simples!
Re: AddVertexAt
« Reply #1 on: November 08, 2007, 03:40:15 PM »
yes, with OpenForRead you can 'study' the object and get it's properties but if you want to change it you need to tell the db that you're taking control of the object which means no one else can use it while you have it to avoid multiple user issues.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

MickD

  • King Gator
  • Posts: 3637
  • (x-in)->[process]->(y-out) ... simples!
Re: AddVertexAt
« Reply #2 on: November 08, 2007, 03:42:37 PM »
To elaborate a bit further, a symbol table record is just like a normal db record, you need to create it first (which means it's automatically open for writing at that point), add your data to the necessary fields and close it. If you want to edit it you need to get the record, open it for editing and so on.
hth.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Bryco

  • Water Moccasin
  • Posts: 1883
Re: AddVertexAt
« Reply #3 on: November 08, 2007, 10:53:05 PM »
Thanks Mick, I'll try that on the weekend

sinc

  • Guest
Re: AddVertexAt
« Reply #4 on: November 09, 2007, 11:02:41 AM »
If all you want to do is edit an existing polyline, you do not need to do anything with Block Tables or Block Table Records.

However, you DO need to open the polyline itself for write.  You can do this by opening it for write, or by opening it for read and using UpgradeOpen().  And as with all interactions with the drawing database, you must use a transaction for this.

The following two code snippets are identical.  The oId is an object ID, such as one returned by Editor.GetSelection().  This code simply insert a point to the beginning of the selected polyline, so that it now starts at (0,0).

Code: [Select]
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
    Polyline p = tr.GetObject(oId, OpenMode.ForWrite, false) as Polyline;
    if (p != null)
    {
        p.AddVertexAt(0, new Point2d(), 0, 0, 0);
    }
    tr.Commit();
}

Code: [Select]
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
    Polyline p = tr.GetObject(oId, OpenMode.ForRead, false) as Polyline;
    if (p != null)
    {
        p.UpgradeOpen();
        p.AddVertexAt(0, new Point2d(), 0, 0, 0);
    }
    tr.Commit();
}

Bryco

  • Water Moccasin
  • Posts: 1883
Re: AddVertexAt
« Reply #5 on: November 09, 2007, 12:49:41 PM »
Thanks Sinc, that'll get me there.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: AddVertexAt
« Reply #6 on: November 09, 2007, 03:04:19 PM »
Just to keep your weekend busy   :laugh:

Code: [Select]

using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.ApplicationServices;
using AcDb = Autodesk.AutoCAD.DatabaseServices;

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

namespace AddVertex
{
  public class Commands
  {
    public Commands(){}

    [CommandMethod("test")]
    static public void test()
    {
      Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        PromptEntityOptions selopts = new PromptEntityOptions("Select a Polyline");
        selopts.AllowNone = false;
        PromptEntityResult result = ed.GetEntity(selopts);

        if (result.Status == PromptStatus.OK)
        {
         
          ObjectId id = result.ObjectId;

          Database Db = HostApplicationServices.WorkingDatabase;
          AcDb.TransactionManager Tm = Db.TransactionManager;

          using (Transaction tr = Tm.StartTransaction())
          {
              Entity ent = (Entity)Tm.GetObject(id, OpenMode.ForRead);

              if (ent is Polyline)
              {

                PromptIntegerResult intres = ed.GetInteger("\nEnter an int now!");
                PromptPointResult ptres = ed.GetPoint("Go and get a point3d boy!");
                Point2d ptToInsert = new Point2d(ptres.Value.X, ptres.Value.Y);

                Polyline pl = (Polyline)ent;

                if (intres.Value <= pl.NumberOfVertices)
                {
                  pl.UpgradeOpen();

                  List<Point2d> ptList = new List<Point2d>();

                  for (int j = 0; j < pl.NumberOfVertices; j++)
                    ptList.Add(pl.GetPoint2dAt(j));

                  pl.AddVertexAt(0, ptToInsert, 0, 0, 0);

                  ptList.Insert(intres.Value, ptToInsert);

                  for (int k = 0; k < pl.NumberOfVertices; k++)
                    pl.SetPointAt(k, ptList[k]);
                }
                else
                {
                  ed.WriteMessage("\nint is less than NumberOfVertices");
                }
              }
              else
              {
                ed.WriteMessage("\nnot a polyline");
              }
            tr.Commit();
          }
        }
      }
      catch (System.Exception ex)
      {
        ed.WriteMessage(ex.Message);
      }
    }
  }
}

Bryco

  • Water Moccasin
  • Posts: 1883
Re: AddVertexAt
« Reply #7 on: November 09, 2007, 06:32:47 PM »
That's going to be handy Daniel, as I also want to draw a poly using a jig.
Kean Walmsley has an example of this but no arcs and his use of drawvector works great until you zoom or pan.
I thought I would have to draw a pline, do an arc or line jig, then draw a new pline, delete the old, continue.
Now it seems I can adjust the pline as I go.
Although the Undo part of the command (not looking forward to that) may be easier if I just hide the old plines and not delete them,
or (Head hurts thinking about it)

Glenn R

  • Guest
Re: AddVertexAt
« Reply #8 on: November 09, 2007, 07:25:25 PM »
And as with all interactions with the drawing database, you must use a transaction for this.

Actually, no, you don't.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: AddVertexAt
« Reply #9 on: November 10, 2007, 08:31:47 AM »
That's going to be handy Daniel, as I also want to draw a poly using a jig.
Kean Walmsley has an example of this but no arcs and his use of drawvector works great until you zoom or pan.
I thought I would have to draw a pline, do an arc or line jig, then draw a new pline, delete the old, continue.
Now it seems I can adjust the pline as I go.
Although the Undo part of the command (not looking forward to that) may be easier if I just hide the old plines and not delete them,
or (Head hurts thinking about it)

In some instances you may need to convert your LwPolyline to a Polyline2d. If you run into this have a look at the methods Polyline.ConvertFrom() and Polyline.ConvertTo(). I personally haven’t used them, but according to the docs you can transfer the handle, persistent reactors, XData .etc. so the end user doesn’t know you’re replacing entities.

Dan
« Last Edit: November 10, 2007, 10:50:28 AM by Daniel »

sinc

  • Guest
Re: AddVertexAt
« Reply #10 on: November 10, 2007, 09:00:40 AM »
And as with all interactions with the drawing database, you must use a transaction for this.

Actually, no, you don't.

Gotta love these incredibly informative posts that say nothing but "you're wrong"...    :roll:

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8718
  • AKA Daniel
Re: AddVertexAt
« Reply #11 on: November 10, 2007, 09:25:38 AM »
And as with all interactions with the drawing database, you must use a transaction for this.

Actually, no, you don't.

Gotta love these incredibly informative posts that say nothing but "you're wrong"...    :roll:

Actually, no, you don't.  :lol:

sinc

  • Guest
Re: AddVertexAt
« Reply #12 on: November 10, 2007, 09:29:30 AM »
 :-D

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: AddVertexAt
« Reply #13 on: November 10, 2007, 10:13:03 AM »
'must' is the key word ..

You can use .Open() and .Close() for everything, but I wouldn't like to. :lol:















kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

Glenn R

  • Guest
Re: AddVertexAt
« Reply #14 on: November 10, 2007, 10:46:19 PM »
Gotta love these incredibly informative posts that say nothing but "you're wrong"...    :roll:

I didn't say you were wrong - you assumed I did. I was merely pointing out that transactions aren't the only way to do things. Also, it wasn't meant to be informative, as there is a very recent thread in this board that goes into speed of drawing 3d solids if I remember correctly and in there it discusses the open/close paradigm compared with transactions. A search for 'transaction speed' and the first result is the thread I refer to.

'must' is the key word ..

You can use .Open() and .Close() for everything, but I wouldn't like to. :lol:

Spot on Kerry.