Author Topic: How to use the DrawVectors function?  (Read 8885 times)

0 Members and 1 Guest are viewing this topic.

csharpbird

  • Newt
  • Posts: 64
How to use the DrawVectors function?
« on: October 30, 2008, 12:26:54 PM »
public void DrawVectors(
    ResultBuffer rb,
    Matrix3d transform
);

How to use?
Thanks in advance!

TonyT

  • Guest
Re: How to use the DrawVectors function?
« Reply #1 on: October 30, 2008, 05:37:24 PM »
public void DrawVectors(
    ResultBuffer rb,
    Matrix3d transform
);

How to use?
Thanks in advance!

See the docs for acedGrVecs() or the (grvecs) LISP function.

csharpbird

  • Newt
  • Posts: 64
Re: How to use the DrawVectors function?
« Reply #2 on: October 30, 2008, 10:35:13 PM »
Code: [Select]
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            TypedValue[] values = { new TypedValue((int)DxfCode.Color,1),
                                    new TypedValue((int)DxfCode.XCoordinate,new Point3d(0,0,0)),
                                    new TypedValue((int)DxfCode.XCoordinate,new Point3d(100,100,0))
                                  };
            ResultBuffer buffer = new ResultBuffer(values);
            ed.DrawVectors(buffer, Matrix3d.Identity);
No Effect!!

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #3 on: October 31, 2008, 04:17:54 AM »


Should that be in this order .. ?
StartPoint,
Endpoint,
Color

?
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.

csharpbird

  • Newt
  • Posts: 64
Re: How to use the DrawVectors function?
« Reply #4 on: October 31, 2008, 05:19:37 AM »


Should that be in this order .. ?
StartPoint,
Endpoint,
Color

?

No effect.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #5 on: October 31, 2008, 07:00:56 AM »

I'll have a look ... Give me a little while ...
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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #6 on: October 31, 2008, 07:16:54 AM »
Have a play with something like this perhaps ...
Code: [Select]
namespace kdub.Testing.Commands
{
    /// <summary>
    /// Summary description for TestCommands Class.
    /// </summary>
    public class TestCommands
    {
        // CodeHimBelonga kwb@theSwamp 20081031
        //
        [CommandMethod("Cmd1")]
        static public void test()
        {           
            Editor ed = AcadApp.DocumentManager.MdiActiveDocument.Editor;

            // create  a new resbuf
            ResultBuffer resBuff = new ResultBuffer();
            // create a start point, end point, then color -
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(0.0, 0.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(100, 100,0)));
 
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(100.0, 100.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200, 100, 0)));

            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200.0, 100.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200, 200, 0)));
            resBuff.Add(new TypedValue((int)DxfCode.Color, 1));

            ed.DrawVectors(resBuff, Matrix3d.Identity);

        }
    }
}

and a piccy to titillate the senses ...

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.

csharpbird

  • Newt
  • Posts: 64
Re: How to use the DrawVectors function?
« Reply #7 on: October 31, 2008, 08:54:33 AM »
Seems the following
resBuff.Add(new TypedValue((int)DxfCode.Color, 1));
should be:
resBuff.Add(new TypedValue((int)LispDataType.Int16, 1));
« Last Edit: October 31, 2008, 09:12:05 AM by csharpbird »

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #8 on: October 31, 2008, 06:08:13 PM »
From the docs
Quote
Result-buffer elements in the vlist can be as follows:

A pair of points (RTPOINT or RT3DPOINT) that specify the endpoints of the vector, expressed in the current UCS; these can be three-dimensional points.
Note You must pass these points as pairs--that is, in two successive result buffers--or the acedGrVecs() call will fail.

A color value that applies to all succeeding vectors until vlist specifies another color. The color is specified as a short integer (RTSHORT). AutoCAD colors are in the range 0-255. If the color value is greater than 255, succeeding vectors are drawn in XOR ink, which complements anything it draws over and erases itself when overdrawn. If the color value is less than 0, the vector is highlighted.


.. so yes, the color should be LispDataType.Int16, or RTSHORT's value of 5003

The Points can be either
LispDataType.Point3d  .. (5009 .. RT3DPOINT)
or
LispDataType.Point2d  .. (5002 .. RTPOINT )
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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #9 on: October 31, 2008, 06:15:02 PM »
also. I note that if the color is added prior to the points the nominated color will be used.

Code: [Select]
             ResultBuffer resBuff = new ResultBuffer();
           
            resBuff.Add(new TypedValue((int)LispDataType.Int16, 1));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(0.0, 0.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(100, 100,0)));
            resBuff.Add(new TypedValue((int)LispDataType.Int16, 2));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(100.0, 100.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200, 100, 0)));
            resBuff.Add(new TypedValue((int)LispDataType.Int16, 3));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200.0, 100.0, 0.0)));
            resBuff.Add(new TypedValue((int)LispDataType.Point3d, new Point3d(200, 200, 0)));

            ed.DrawVectors(resBuff, Matrix3d.Identity);


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.

TonyT

  • Guest
Re: How to use the DrawVectors function?
« Reply #10 on: November 01, 2008, 01:43:02 AM »
Kerry seems to have unraveled that for you.

FWIW, DrawVectors/acedGrVecs is legacy, and that's probably why
you can only draw using the 256 colors.

In ObjectARX, you can use the Editor's MonitorInputPoint event to
draw temporary graphics as well, and you're not limited to drawing
only vectors or to 256 colors, and they aren't wiped out by a REDRAW.

Code: [Select]
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            TypedValue[] values = { new TypedValue((int)DxfCode.Color,1),
                                    new TypedValue((int)DxfCode.XCoordinate,new Point3d(0,0,0)),
                                    new TypedValue((int)DxfCode.XCoordinate,new Point3d(100,100,0))
                                  };
            ResultBuffer buffer = new ResultBuffer(values);
            ed.DrawVectors(buffer, Matrix3d.Identity);
No Effect!!

sinc

  • Guest
Re: How to use the DrawVectors function?
« Reply #11 on: November 01, 2008, 12:06:19 PM »
Do you mean Editor.PointMonitor?  How do you use that, Tony?  What methods do we use to draw the temporary graphics, and how do the temporary graphics get removed when we're finished with them?

Spike Wilbury

  • Guest
Re: How to use the DrawVectors function?
« Reply #12 on: November 01, 2008, 01:55:41 PM »
Do you mean Editor.PointMonitor?  How do you use that, Tony?  What methods do we use to draw the temporary graphics, and how do the temporary graphics get removed when we're finished with them?

Something like: ?

Code: [Select]
PointMonitorEventArgs e

Circle circle = new Circle(e.Context.RawPoint, Vector3d.ZAxis, 10);

e.Context.DrawContext.Geometry.Draw(circle);

circle.Radius = 20;

e.Context.DrawContext.Geometry.Draw(circle);

sinc

  • Guest
Re: How to use the DrawVectors function?
« Reply #13 on: November 01, 2008, 02:59:48 PM »
Yeah, like that...  Thanks!

Spike Wilbury

  • Guest
Re: How to use the DrawVectors function?
« Reply #14 on: November 01, 2008, 03:25:48 PM »
Yeah, like that...  Thanks!

Sinc,

Have a look at this url link (I guess was posted here too, but forgot where it is):

http://through-the-interface.typepad.com/through_the_interface/2007/11/devtv-introduct.html

(Introduction to AutoCAD .NET Programming - includes the SLN if I recall)
« Last Edit: November 01, 2008, 03:29:12 PM by Esquivel »

sinc

  • Guest
Re: How to use the DrawVectors function?
« Reply #15 on: November 01, 2008, 03:36:28 PM »
I saw those, but didn't take the time to watch them, because they looked too "introductory".

Would they help with my current problem?

I'm trying to use the PointMonitor event, the way you indicated, and it's working fine with one exception.  It works fine the first time it is invoked.  But the second time it is invoked, it displays the geometry drawn during the first invocation until the user moves the mouse.  As soon as the user moves the mouse, it updates the geometry, and everything is drawn correctly.  But I can't figure out why it appears to be "remembering" the geometry from the last invocation...

Spike Wilbury

  • Guest
Re: How to use the DrawVectors function?
« Reply #16 on: November 01, 2008, 03:56:53 PM »
I saw those, but didn't take the time to watch them, because they looked too "introductory".

Would they help with my current problem?

I'm trying to use the PointMonitor event, the way you indicated, and it's working fine with one exception.  It works fine the first time it is invoked.  But the second time it is invoked, it displays the geometry drawn during the first invocation until the user moves the mouse.  As soon as the user moves the mouse, it updates the geometry, and everything is drawn correctly.  But I can't figure out why it appears to be "remembering" the geometry from the last invocation...

Below there are some of those functions:

Code: [Select]

[CommandMethod("newInput")]
public void NewInput()
{
// start our input point Monitor   
// get the editor object
Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
// now add the delegate to the events list
ed.PointMonitor += new PointMonitorEventHandler(this.MyInputMonitor);
ed.TurnForcedPickOn();
// now pick some point, this emulates a real world input that may be required
// pick the center point of the circle
PromptPointOptions getPointOptions = new PromptPointOptions("Pick A Point : ");
if (ed.GetPoint(getPointOptions).Status == PromptStatus.OK)
{
// do something
}

// now remove our point monitor as we are finished With it
ed.PointMonitor -= new PointMonitorEventHandler(this.MyInputMonitor);
}

public void MyInputMonitor(object sender, PointMonitorEventArgs e)
{
// first lets check what is under the Cursor
FullSubentityPath[] fullEntPath = e.Context.GetPickedEntities();
if (fullEntPath.Length > 0)
{
// start a transaction
Transaction trans = acadApp.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction();
try
{
// open the Entity for read, it must be derived from Curve
Curve ent = (Curve)trans.GetObject(fullEntPath[0].GetObjectIds()[0], OpenMode.ForRead);
// ok, so if we are over something - then check to see if it has an extension dictionary
if (ent.ExtensionDictionary.IsValid)
{
// open it for read
DBDictionary extensionDict = (DBDictionary)trans.GetObject(ent.ExtensionDictionary, OpenMode.ForRead);
// find the entry
ObjectId entryId = extensionDict.GetAt("MyData");
// if we are here, then all is ok
// extract the xrecord
Xrecord myXrecord = (Xrecord) trans.GetObject(entryId, OpenMode.ForRead);
// now draw the positions
foreach (TypedValue value in myXrecord.Data)
{
// if the TypeCode is a distance value
if (value.TypeCode == 40)
{
// draw some temporary graphics along the Curve to show the distances

// first get the point along the curve
Point3d pnt = ent.GetPointAtDist((double)value.Value);
// next work out how many pixels are in a unit square - so we can keep the temporary graphics a set size
Point2d pixels = e.Context.DrawContext.Viewport.GetNumPixelsInUnitSquare(pnt);
// setup the constant distances
double xDist = 10 / pixels.X;
double yDist = 10 / pixels.Y;

// then draw the temporary Graphics
Circle circle = new Circle(pnt, Vector3d.ZAxis, xDist);
e.Context.DrawContext.Geometry.Draw(circle);
// more temporary graphics
DBText text = new DBText();
// always a good idea to set the Database defaults With things like text, dimensions etc
text.SetDatabaseDefaults();
// set the position of the text to the same point as the circle, but offset by the radius
text.Position = pnt + new Vector3d(xDist, yDist, 0);
text.TextString = value.Value.ToString();
text.Height = yDist;
e.Context.DrawContext.Geometry.Draw(text);
}
}
}
// all ok, commit it
trans.Commit();
}
catch
{
}
finally
{
// whatever happens, nuke the transaction
trans.Dispose();
}
}
}

Code: [Select]
[CommandMethod("pointmonitor")]
static public void pointmonitor()
{
// get the editor object
Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
// now add the delegate to the events list
ed.PointMonitor += new PointMonitorEventHandler(ed_PointMonitor);
}

static void ed_PointMonitor(object sender, PointMonitorEventArgs e)
{
// first let's check what's under the cursor
FullSubentityPath[] fullEntPath = e.Context.GetPickedEntities();

if (fullEntPath.Length > 0)
{
// display a tooltip
// start a transaction
Transaction trans = acadApp.DocumentManager.MdiActiveDocument.Database.TransactionManager.StartTransaction();
try
{
// open the entity for read
Entity ent = (Entity) trans.GetObject(fullEntPath[0].GetObjectIds()[0], OpenMode.ForRead);
e.AppendToolTipText("The Entity is a " + ent.GetType().ToString());

// ok, so if we are over something - then lets highlight it in the palette Window
// find the tag we want in the tree
Font fontRegular = new Font("Microsoft Sans Serif", 8f, FontStyle.Regular);
Font fontBold = new Font("Microsoft Sans Serif", 8f, FontStyle.Bold);

// wait until after we have processed the whole tree before we handle the different sized text
myPalette.treeView1.SuspendLayout();
foreach (TreeNode node in myPalette.treeView1.Nodes)
{
// if it's the one we want
if (ent.ObjectId == (ObjectId)node.Tag)
{
if (!fontBold.Equals(node.NodeFont))
{
node.NodeFont = fontBold;
node.Text = node.Text;
}
}
else if (!fontRegular.Equals(node.NodeFont))
{
node.NodeFont = fontRegular;
}
}

// now it's time to recalc the layout of the treeview
myPalette.treeView1.ResumeLayout();
myPalette.treeView1.Refresh();
myPalette.treeView1.Update();

// all ok, commit it
trans.Commit();
}
catch
{
// Explicit catch all here as we're monitoring cursor movement
}
finally
{
trans.Dispose();
}
}

// ok, so now lets do something really pointless! space invaders!
if ((e.Context.History & PointHistoryBits.NotDigitizer) > PointHistoryBits.DidNotPick)
{
// this means the mouse has been clicked... so...
// create a Circle
Circle circle = new Circle(e.Context.RawPoint, Vector3d.ZAxis, 10);
// draw it
e.Context.DrawContext.Geometry.Draw(circle);
// wait for a while
System.Threading.Thread.Sleep(50);
// draw
circle.Radius = 20;
e.Context.DrawContext.Geometry.Draw(circle);
// wait for a while
System.Threading.Thread.Sleep(50);
// draw it
circle.Radius = 40;
e.Context.DrawContext.Geometry.Draw(circle);
// wait for a while
System.Threading.Thread.Sleep(50);
// draw it
circle.Radius = 80;
e.Context.DrawContext.Geometry.Draw(circle);
// wait for a while
System.Threading.Thread.Sleep(50);
}

}

I am not doing nothing lately with C#... so, cannot be of much help  :-(

sinc

  • Guest
Re: How to use the DrawVectors function?
« Reply #17 on: November 01, 2008, 04:11:33 PM »
I'll take a look through that later, just to see what all is in it.

But I figured out the problem.  It was related to the fact that I was already using an EntityJig, and I tried to save some processing by using a calculation from the EntityJig.  The call to PointMonitor was happening before the required data was being updated by the EntityJig, so that wasn't working.

I redid the code, so that the PointMonitor handler performs the required calculation, and it works fine now.

In the process, it seems as though the EntityJig is no longer necessary.  I was having problems with the EntityJig, in that I wanted to draw a series of objects, and I couldn't figure out any good way of doing that with a Jig.  However, it seems quite easy to do it with PointMonitor instead.  So I suspect I may want to redo this code, and possibly eliminate the Jig entirely.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: How to use the DrawVectors function?
« Reply #18 on: November 01, 2008, 06:10:55 PM »
And I'd like to thank Glenn for the translation Luis posted ...

Just thought I should post the solution as well because of the UserControl.
< link to zip. >
http://www.theswamp.org/index.php?topic=19780.msg243411#msg243411

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.

TonyT

  • Guest
Re: How to use the DrawVectors function?
« Reply #19 on: November 01, 2008, 10:41:59 PM »
Do you mean Editor.PointMonitor?  How do you use that, Tony?  What methods do we use to draw the temporary graphics, and how do the temporary graphics get removed when we're finished with them?

Sorry, yes I meant PointMonitor (the native method is monitorInputPoint).

It's also a good thing to not leave the handler attached to the event any
longer than needed (e.g., only when you want the graphics to be drawn).

The temporary graphics are erased and redrawn every time the mouse
moves or any other 'input' occurs, so you don't have to worry about
removing it, but you do have to be mindful of excessive processing in
the event handler, for the same reason.


« Last Edit: November 01, 2008, 10:45:13 PM by TonyT »