Author Topic: Animated Block Hover  (Read 6290 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Animated Block Hover
« on: October 26, 2010, 12:33:56 AM »
Most of this or about all of it is hard-coded but this might inspire a idea for someone.

This will let you hover over a blockrefrence and after 0.25 seconds draw bounding box around all the block references then add 4 circles and remove 4 circles at each corner at 0.25 second intervals.

While the temporary graphics are adding and removing you can keep working.


Here is a link to video Video Link

Code: [Select]

using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using AcadGi =  Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Colors;
using System.Collections;
using System.Collections.Generic;
[assembly: CommandClass(typeof(AnimatedBlockHover.BlockHover))]

namespace AnimatedBlockHover
{
    public class BlockHover
    {
        public static TempGraphics tgStatic = null;
        public static System.Windows.Forms.Control blockHoverCtrl;
       public BlockHover()
        {
            // Create New Windows Control
            blockHoverCtrl = new System.Windows.Forms.Control();
            blockHoverCtrl.CreateControl();
        }

       void SeperateThreadProcess()
        {
            ThreadsDelegate threadDelegate = new ThreadsDelegate(MainThreadProcess);

            TempGraphics tempG = new TempGraphics();
            tempG = tgStatic;
            tempG.drawAction = 0;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
           
            System.Threading.Thread.Sleep(250);

            tempG.drawAction = 1;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }

            System.Threading.Thread.Sleep(250);

            tempG.drawAction = 2;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }

            System.Threading.Thread.Sleep(250);

            tempG.drawAction = 3;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
            System.Threading.Thread.Sleep(250);

            tempG.drawAction = 4;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }           

            System.Threading.Thread.Sleep(250);
            tempG.drawAction = -1;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
            System.Threading.Thread.Sleep(250);
            tempG.drawAction = -2;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
            System.Threading.Thread.Sleep(250);
            tempG.drawAction = -3;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
            System.Threading.Thread.Sleep(250);
            tempG.drawAction = -4;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
            System.Threading.Thread.Sleep(250);
            tempG.drawAction = 250;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);
            }
            else
            {
                MainThreadProcess(tempG);
            }
        }

        delegate void ThreadsDelegate(object obj);

        void MainThreadProcess(object obj)
        {
            TempGraphics tempG = (TempGraphics)obj;           
            if (tempG.drawAction == 0)
            {
                foreach (Polyline pLine in tempG.plList)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(pLine, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }
            else if (tempG.drawAction == 1)
            {
                foreach (Circle cir in tempG.circleList1)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(cir, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }

            else if (tempG.drawAction == 2)
            {
                foreach (Circle cir in tempG.circleList2)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(cir, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }

            else if (tempG.drawAction == 3)
            {
                foreach (Circle cir in tempG.circleList3)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(cir, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }
            else if (tempG.drawAction == 4)
            {

                foreach (Circle cir in tempG.circleList4)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(cir, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }
            else if (tempG.drawAction == -1)
            {

                foreach (Circle cir in tempG.circleList1)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(cir, coll);
                    cir.Dispose();
                }
            }
            else if (tempG.drawAction == -2)
            {

                foreach (Circle cir in tempG.circleList2)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(cir, coll);
                    cir.Dispose();
                }
            }
            else if (tempG.drawAction == -3)
            {

                foreach (Circle cir in tempG.circleList3)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(cir, coll);
                    cir.Dispose();
                }
            }
            else if (tempG.drawAction == -4)
            {

                foreach (Circle cir in tempG.circleList4)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(cir, coll);
                    cir.Dispose();
                }
            }

            else
            {
                foreach (Polyline pLine in tempG.plList)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(pLine, coll);
                    pLine.Dispose();
                }       
                tempG.circleList1.Clear();
                tempG.circleList1 = null;
                tempG.circleList2.Clear();
                tempG.circleList2 = null;
                tempG.circleList3.Clear();
                tempG.circleList3 = null;
                tempG.circleList4.Clear();
                tempG.circleList4 = null;
                tempG.plList.Clear();
                tempG.plList = null;
               
            }

            Application.UpdateScreen();
        }

        [CommandMethod("HighlighBlockReferences")]
        public void HighlighBlockReferences()
        {
            Application.DocumentManager.MdiActiveDocument.Editor.PointMonitor += new PointMonitorEventHandler(HoverHandler);
        }


        private void HoverHandler(object sender, PointMonitorEventArgs e)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            FullSubentityPath[] fsps = e.Context.GetPickedEntities();
            if (fsps.Length > 0)
            {
                FullSubentityPath fsp = fsps[0];

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        Entity ent = (Entity)tr.GetObject(fsp.GetObjectIds()[0], OpenMode.ForRead);                       
                        if (ent is BlockReference)
                        {                     
                                BlockReference bref = ent.Id.GetObject(OpenMode.ForRead) as BlockReference;                           
                                BlockTableRecord btr = bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;                               
                                ObjectIdCollection brefIds = btr.GetBlockReferenceIds(true, false);
                                TempGraphics tg = new TempGraphics();   
                                foreach (ObjectId objId in brefIds)                             
                                {
                                 
                                    Entity ents = objId.GetObject(OpenMode.ForRead) as Entity;
                                    Point3d min = ents.GeometricExtents.MinPoint;
                                    Point3d max = ents.GeometricExtents.MaxPoint;
                                    Polyline pl = new Polyline();
                                    pl.SetDatabaseDefaults();
                                    Point2d p1 = new Point2d(min.X, min.Y);
                                    Point2d p2 = new Point2d(min.X, max.Y);
                                    Point2d p3 = new Point2d(max.X, max.Y);
                                    Point2d p4 = new Point2d(max.X, min.Y);
                                    pl.AddVertexAt(0, p1, 0, 0, 0);
                                    pl.AddVertexAt(1, p2, 0, 0, 0);
                                    pl.AddVertexAt(2, p3, 0, 0, 0);
                                    pl.AddVertexAt(3, p4, 0, 0, 0);
                                    pl.Color = Color.FromColorIndex(ColorMethod.ByAci, 2);
                                    pl.Closed = true;
                                    tg.plList.Add(pl);
                                    double radius = (max.Y - min.Y) / 6;
                                    Circle cir1 = new Circle(new Point3d(p1.X, p1.Y, 0), Vector3d.ZAxis, radius);
                                    Circle cir2 = new Circle(new Point3d(p2.X, p2.Y, 0), Vector3d.ZAxis, radius);
                                    Circle cir3 = new Circle(new Point3d(p3.X, p3.Y, 0), Vector3d.ZAxis, radius);
                                    Circle cir4 = new Circle(new Point3d(p4.X, p4.Y, 0), Vector3d.ZAxis, radius);
                                    tg.circleList1.Add(cir1);
                                    tg.circleList2.Add(cir2);
                                    tg.circleList3.Add(cir3);
                                    tg.circleList4.Add(cir4);
                                   
                                }
                                tgStatic = tg;
                                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(SeperateThreadProcess));
                                thread.Start();
                        }                       
                    }
                    catch
                    {
                        tr.Dispose();
                    }

                    tr.Commit();
                }
               
             
            }
         
        }
    }

    public class TempGraphics
    {
        public  List<Circle> circleList1 = new List<Circle>();
        public  List<Circle> circleList2 = new List<Circle>();
        public  List<Circle> circleList3 = new List<Circle>();
        public  List<Circle> circleList4 = new List<Circle>();
        public  List<Polyline> plList = new List<Polyline>();
        public int drawAction;
       
        public TempGraphics()
        {
            plList.Clear();
            circleList1.Clear();
            circleList2.Clear();
            circleList3.Clear();
            circleList4.Clear();         
        }
    }
}

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #1 on: October 26, 2010, 12:37:36 AM »
Sorry I did not mean to post.
I meant to hit preview and looking at the code it needs explanation.
So if anyone needs an explantion of what is thrown together in that mess or would like it cleaned up with an explanation I will be happy to.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #2 on: October 26, 2010, 01:02:24 AM »
Here it is just creating a rectangle around the block reference to clean it up with out all the hard code mess in it.
Was just seeing if it worked

Code: [Select]
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using AcadGi =  Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Colors;
using System.Collections;
using System.Collections.Generic;
[assembly: CommandClass(typeof(AnimatedBlockHover.BlockHover))]

namespace AnimatedBlockHover
{
    public class BlockHover
    {
        public static TempGraphics tgStatic = null;
        public static System.Windows.Forms.Control blockHoverCtrl;
       public BlockHover()
        {
            // Create New Windows Form Control
            blockHoverCtrl = new System.Windows.Forms.Control();
            blockHoverCtrl.CreateControl();
        }
       // TempGraphics is a helper class at bottom

       void SeperateThreadProcess()
        {
            ThreadsDelegate threadDelegate = new ThreadsDelegate(MainThreadProcess);

            TempGraphics tempG = new TempGraphics();
            tempG = tgStatic;
            tempG.drawAction = 0;
           // Invoke Control
            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);// Draw Temp because tempG.drawAction == 0
            }
            else
            {
                MainThreadProcess(tempG);
            }
           
            System.Threading.Thread.Sleep(5000);// Sleep 5 Seconds

            tempG.drawAction = 1;

            if (blockHoverCtrl.InvokeRequired)
            {
                blockHoverCtrl.Invoke(threadDelegate, tempG);// Erase Temp Graphics because tempG.drawAction != 0
            }
            else
            {
                MainThreadProcess(tempG);
            }
           
        }

        delegate void ThreadsDelegate(object obj); // delegate

        void MainThreadProcess(object obj) // Add and remove Temp Graphics
        {
            TempGraphics tempG = (TempGraphics)obj;           
            if (tempG.drawAction == 0)
            {
                foreach (Polyline pLine in tempG.plList)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(pLine, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                }
            }
            else
            {
                foreach (Polyline pLine in tempG.plList)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(pLine, coll);
                    pLine.Dispose();
                }   
                tempG.plList.Clear();
                tempG.plList = null;
               
            }

            Application.UpdateScreen();
        }

        [CommandMethod("HighlighBlockReferences")]
        public void HighlighBlockReferences()
        {
            Application.DocumentManager.MdiActiveDocument.Editor.PointMonitor += new PointMonitorEventHandler(HoverHandler);
        }


        private void HoverHandler(object sender, PointMonitorEventArgs e)// PointMonitorEventHandler
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            FullSubentityPath[] fsps = e.Context.GetPickedEntities();
            if (fsps.Length > 0)
            {
                FullSubentityPath fsp = fsps[0];

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        Entity ent = (Entity)tr.GetObject(fsp.GetObjectIds()[0], OpenMode.ForRead);                       
                        if (ent is BlockReference)
                        {                     
                                BlockReference bref = ent.Id.GetObject(OpenMode.ForRead) as BlockReference;                           
                                BlockTableRecord btr = bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;                               
                                ObjectIdCollection brefIds = btr.GetBlockReferenceIds(true, false);
                                TempGraphics tg = new TempGraphics(); // Create new TempGraphics Helper Class
                                foreach (ObjectId objId in brefIds)                             
                                {
                                 
                                    Entity ents = objId.GetObject(OpenMode.ForRead) as Entity;
                                    Point3d min = ents.GeometricExtents.MinPoint;
                                    Point3d max = ents.GeometricExtents.MaxPoint;
                                    Polyline pl = new Polyline();// Create new polylines to add to TempGraphics Helper Class
                                    pl.SetDatabaseDefaults();
                                    Point2d p1 = new Point2d(min.X, min.Y);
                                    Point2d p2 = new Point2d(min.X, max.Y);
                                    Point2d p3 = new Point2d(max.X, max.Y);
                                    Point2d p4 = new Point2d(max.X, min.Y);
                                    pl.AddVertexAt(0, p1, 0, 0, 0);
                                    pl.AddVertexAt(1, p2, 0, 0, 0);
                                    pl.AddVertexAt(2, p3, 0, 0, 0);
                                    pl.AddVertexAt(3, p4, 0, 0, 0);
                                    pl.Color = Color.FromColorIndex(ColorMethod.ByAci, 2);
                                    pl.Closed = true;
                                    tg.plList.Add(pl);  // Add PolyLines             
                                }
                                tgStatic = tg;
                                System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(SeperateThreadProcess));
                                thread.Start();// Start New Thread
                        }                       
                    }
                    catch
                    {
                        tr.Dispose();
                    }

                    tr.Commit();
                }           
            }
         
        }
    }

    public class TempGraphics
    {
        public  List<Polyline> plList = new List<Polyline>();
        public int drawAction;
       
        public TempGraphics()
        {
            plList.Clear();                     
        }
    }
}

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Animated Block Hover
« Reply #3 on: October 26, 2010, 02:04:03 AM »

Very Spiffy Jeff !!
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.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #4 on: October 26, 2010, 04:58:04 AM »

Very Spiffy Jeff !!

Thanks Kerry

The idea was to figure out how to size a wheel(like the picture below) by taking the shortest length x or y of the bounding box and simulating a wheel rolling around the box.
Can any of you can come up with a algorithm for that? 

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Animated Block Hover
« Reply #5 on: October 26, 2010, 06:06:53 AM »
Can't make time to play, but perhaps something like  ;

Polyline is curve


MyStepList shall be a 'list' of distances around the pline.

Code: [Select]
Point3d ptOnPolyline;
ptOnPolyline = pl.GetPointAtParameter(pl.GetParameterAtDistance (determineStepValueByReadingThe_MyStepList ));


I'll leave the mechanics to you   :lmao:
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: Animated Block Hover
« Reply #6 on: October 26, 2010, 06:21:46 AM »
That may not work ... I'll need to investigate ... or you can ... sorry :)


but then again , it just might.

It's dangerous for me to just spew out half baked ideas  :|
« Last Edit: October 26, 2010, 06:32:40 AM by Kerry »
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.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #7 on: October 26, 2010, 06:45:21 AM »
I was thinking along those same lines to divide the length up a multipe of 16 of the circle's circumference then ad 2 blocks one like the picture above and one rotated 22.5 then at each interval alternate blockreferences to show

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #8 on: October 28, 2010, 03:58:44 AM »
Here is one that does a animation as long as you hover over a blockreference and does the animation for all inserted blocks of that type.


This is to just show and give ideas as the overall setup is not a good implementation

This one puts it in a while loop and adds a PromptForSelectionEndingEventHandler which is fired when you hover over an entity, once you move off the the PointMoniter fires but still will fire a couple of times in between PromptForSelectionEndingEventHandler
So a counter resets itself after 4 and sets the condition for the while loop to false to stop the animation.

It probably be better the check the objectIds but here is an idea

Click Here To See Animation
I went orange and blue for Auburn not Gators

Again this was to see if it works and slapping code together real quick.
As I am pasting code I noticed I clear list in a constructor. Go figure? That proves my point of this for a idea.
Code: [Select]
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using AcadGi =  Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Colors;
using System.Collections;
using System.Collections.Generic;
[assembly: CommandClass(typeof(AnimatedBlockHover.BlockHover))]
namespace AnimatedBlockHover
{
    public class BlockHover
    {
        public static TempGraphics tgStatic = null;
        public static System.Windows.Forms.Control blockHoverCtrl;
        public BlockHover()
        {
            // Create New Windows Form Control
            blockHoverCtrl = new System.Windows.Forms.Control();
            blockHoverCtrl.CreateControl();
        }
        // TempGraphics is a helper class at bottom

        void SeperateThreadProcess()
        {
            ThreadsDelegate threadDelegate = new ThreadsDelegate(MainThreadProcess);

            TempGraphics tempG = new TempGraphics();
            tempG = tgStatic;               

            tempG.drawAction = 0;
            if (blockHoverCtrl.InvokeRequired)  blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);           

            tempG.drawAction = 1;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);
           
            tempG.drawAction = 2;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);

            tempG.drawAction = 3;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);

                while (tgStatic.keepOn == true)
                {
                    tempG.drawAction = 4;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 5;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 6;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 7;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 8;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 9;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 10;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);

                    tempG.drawAction = 11;
                    if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
                    else MainThreadProcess(tempG);
                    System.Threading.Thread.Sleep(100);
                }// End While

            tempG.drawAction = 123;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);// Erase Temp Graphics because tempG.drawAction             
            else MainThreadProcess(tempG);
           


        }

        delegate void ThreadsDelegate(object obj); // delegate

        void MainThreadProcess(object obj) // Add and remove Temp Graphics
        {
            TempGraphics tempG = (TempGraphics)obj;
            if (tempG.drawAction == 0)
            {
                foreach (Line lne in tempG.lne1List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }

            else if (tempG.drawAction == 1)
            {
                foreach (Line lne in tempG.lne2List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }

            else if (tempG.drawAction == 2)
            {
                foreach (Line lne in tempG.lne3List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }             
            }

            else if (tempG.drawAction == 3)
            {
                foreach (Line lne in tempG.lne4List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }

            else if (tempG.drawAction == 4)
            {
                foreach (Line lne in tempG.lne1List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 30);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);                   
                }               
            }

            else if (tempG.drawAction == 5)
            {
                foreach (Line lne in tempG.lne2List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 30);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 6)
            {
                foreach (Line lne in tempG.lne3List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 30);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 7)
            {
                foreach (Line lne in tempG.lne4List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 30);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 8)
            {
                foreach (Line lne in tempG.lne1List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 9)
            {
                foreach (Line lne in tempG.lne2List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 10)
            {
                foreach (Line lne in tempG.lne3List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else if (tempG.drawAction == 11)
            {
                foreach (Line lne in tempG.lne4List)
                {
                    lne.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.UpdateTransient(lne, coll);
                }
            }

            else
            {
                foreach (Line lne in tempG.eraseLineList)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.EraseTransient(lne, coll);
                    lne.Dispose();
                }
                tempG.eraseLineList.Clear();
                tempG.eraseLineList = null;               
                tempG.lne1List.Clear();
                tempG.lne1List = null;
                tempG.lne2List.Clear();
                tempG.lne2List = null;
                tempG.lne3List.Clear();
                tempG.lne3List = null;
                tempG.lne4List.Clear();
                tempG.lne4List = null;
            }

            Application.UpdateScreen();
        }

        [CommandMethod("HighlighBlockReferences")]
        public void HighlighBlockReferences()
        {
            Application.DocumentManager.MdiActiveDocument.Editor.PointMonitor += new PointMonitorEventHandler(HoverHandler);
            Application.DocumentManager.MdiActiveDocument.Editor.PromptForSelectionEnding += new PromptForSelectionEndingEventHandler(HoverEndingHandler);
        }
        private void HoverEndingHandler(object sender, PromptForSelectionEndingEventArgs e)// PointMonitorEventHandler
        {
            if (tgStatic != null)
            {
                tgStatic.keepOn = true;
                tgStatic.moniterCount--;
            }
       
        }

        private void HoverHandler(object sender, PointMonitorEventArgs e)// PointMonitorEventHandler
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            if (tgStatic != null)
            {
                if (tgStatic.moniterCount > 4)
                {
                    tgStatic.keepOn = false;
                    tgStatic.moniterCount = 0;
                }

                tgStatic.moniterCount++;
            }
            FullSubentityPath[] fsps = e.Context.GetPickedEntities();
            if (fsps.Length > 0)
            {
                FullSubentityPath fsp = fsps[0];

                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    try
                    {
                        Entity ent = (Entity)tr.GetObject(fsp.GetObjectIds()[0], OpenMode.ForRead);
                        if (ent is BlockReference)
                        {
                            BlockReference bref = ent.Id.GetObject(OpenMode.ForRead) as BlockReference;
                            BlockTableRecord btr = bref.BlockTableRecord.GetObject(OpenMode.ForRead) as BlockTableRecord;
                            ObjectIdCollection brefIds = btr.GetBlockReferenceIds(true, false);
                            TempGraphics tg = new TempGraphics();                           
                            // Create new TempGraphics Helper Class
                            foreach (ObjectId objId in brefIds)
                            {

                                Entity ents = objId.GetObject(OpenMode.ForRead) as Entity;
                                Point3d min = ents.GeometricExtents.MinPoint;
                                Point3d max = ents.GeometricExtents.MaxPoint;
                                Point3d p1 = new Point3d(min.X, min.Y, 0);
                                Point3d p2 = new Point3d(min.X, max.Y, 0);
                                Point3d p3 = new Point3d(max.X, max.Y, 0);
                                Point3d p4 = new Point3d(max.X, min.Y, 0);
                                Line lne1 = new Line(p1, p2);
                                Line lne2 = new Line(p2, p3);
                                Line lne3 = new Line(p3, p4);
                                Line lne4 = new Line(p4, p1);
                                lne1.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                                lne2.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                                lne3.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                                lne4.Color = Color.FromColorIndex(ColorMethod.ByAci, 5);
                                tg.lne1List.Add(lne1);
                                tg.lne2List.Add(lne2);
                                tg.lne3List.Add(lne3);
                                tg.lne4List.Add(lne4);
                            }
                            tgStatic = tg;
                            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(SeperateThreadProcess));
                            thread.Start();// Start New Thread
                        }
                    }
                    catch
                    {
                        tr.Dispose();
                    }

                    tr.Commit();
                }
            }

        }
    }

    public class TempGraphics
    {
        public List<Line> lne1List = new List<Line>();
        public List<Line> lne2List = new List<Line>();
        public List<Line> lne3List = new List<Line>();
        public List<Line> lne4List = new List<Line>();
        public List<Line> eraseLineList = new List<Line>();
        public int drawAction;
        public int moniterCount;
        public bool keepOn = true;

        public TempGraphics()
        {
            lne1List.Clear();
            lne2List.Clear();
            lne3List.Clear();
            lne4List.Clear();
            eraseLineList.Clear();
        }

    }
}

kaefer

  • Guest
Re: Animated Block Hover
« Reply #9 on: November 03, 2010, 03:40:59 PM »
Here is one that does a animation as long as you hover over a blockreference and does the animation for all inserted blocks of that type.


This is to just show and give ideas as the overall setup is not a good implementation
Hi Jeff!

Thanks for the warning, but I'd like to come back anyway. I'm burning to know if it's at least theoretically possible to build a safe implementation for this type of application in the current environment.

First, the trigger. PointMonitor is it; and it is customary to restrict its activity either to one editor temporarily or to extend it over all open documents, current and future. In this scenario there is no defined end point, nothing to signal us that our animation isn't welcome any more.

Then, there's the desire to dispose with the transient lines when we are done. That might happen via time-out or when the operation  is cancelled, however that might be achieved.

And finally, if I get it right, the parallelism is marginally operative because you are running the timer from a UI thread, simulating a UI callback.
That can't be easily replaced with other async operations. I tried the TryCancelled pattern, and was pretty successfull in communication with forms controls, but wouldn't want to touch the Database. Example:
Code: [Select]
    let tickSuccess =
        async {
            while !counter < maxCount do
                do! Async.Sleep millisec
                post ... // Tick
                incr counter
            post ... } // Time-Out
    let tickSuccessCancelled =
        async {
            do! Async.TryCancelled(
                    tickSuccess,
                    (fun _ -> post ...) ) }  // Cancelled

Curious, Thorsten

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Animated Block Hover
« Reply #10 on: November 03, 2010, 08:25:50 PM »
First Off let me apologize Thorsten for posting this mess
Kerry in your reply will you edit Spiffy by changing the 'p' to a 'h' and the 'f's to 't's
This was code slapped together then if got an error changed whatever to get it working.
Trying to explain it has made me dumber and confused but see if this helps.
The first chance I get I will create a much better implementation and post it, or
Thorsten you usually have a better idea how to do things so see if this sparks any ideas.


When the "HighlighBlockReferences" command is called which is in the BlockHover class it creates a control in the BlockHover constructor and assigns it to blockHoverCtrl
Code: [Select]
public static System.Windows.Forms.Control blockHoverCtrl;
        public BlockHover()
        {
            blockHoverCtrl = new System.Windows.Forms.Control();
            blockHoverCtrl.CreateControl();
        }

It adds the PointMonitorEventHandler  passing in HoverHandler method
In the HoverHandler method if the entity is a Block Reference Then
It creates a new instance of the Thread Class

In the Thread constructor the ThreadStart delegate is used to tell what method to process when the new Thread starts.
Code: [Select]
System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(SeperateThreadProcess));
 thread.Start();// Start New Thread

In the mess of code there is
Code: [Select]
delegate void ThreadsDelegate(object obj);


When the new thread starts and the SeperateThreadProcess is called it uses the MainThreadProcess method as the Target Method in the constructor
Code: [Select]
ThreadsDelegate threadDelegate = new ThreadsDelegate(MainThreadProcess);

Then creates a new instance of the TempGraphics Class and points the reference to the tgStatic variable which points to a TempGraphics created in HoverHandler Containing the lines

The TempGraphics Class has the four lists of lines(which are lines connecting the block reference GeometricExtents points)
A integer DrawAction which the value is set in SeperateThreadProcess Method and the MainThreadProcess method uses it to decide what instructions to process
Code: [Select]
TempGraphics tempG = new TempGraphics();
tempG = tgStatic;

From VS2010 Help
Quote
Control.Invoke Method (Delegate, Object []) 
Executes the specified delegate, on the thread that owns the control's underlying window handle, with the specified list of arguments

These 4 set the DrawAction number, invoke the control(passing in the delegate that the Target Method is the MainThreadProcess method , and TempGraphics Class), and sleep for 100 milliseconds
Code: [Select]
tempG.drawAction = 0;
            if (blockHoverCtrl.InvokeRequired)  blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);           

            tempG.drawAction = 1;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);
           
            tempG.drawAction = 2;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);

            tempG.drawAction = 3;
            if (blockHoverCtrl.InvokeRequired) blockHoverCtrl.Invoke(threadDelegate, tempG);
            else MainThreadProcess(tempG);
            System.Threading.Thread.Sleep(100);

When the control is invoked from the code above the 4 lines are drawn in the MainThreadProcess matching the Drawaction and add the lines to a List eraseLineList to erase lines later
Code: [Select]
   if (tempG.drawAction == 0)
            {
                foreach (Line lne in tempG.lne1List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }

            else if (tempG.drawAction == 1)
            {
                foreach (Line lne in tempG.lne2List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }

            else if (tempG.drawAction == 2)
            {
                foreach (Line lne in tempG.lne3List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }             
            }

            else if (tempG.drawAction == 3)
            {
                foreach (Line lne in tempG.lne4List)
                {
                    IntegerCollection coll = new IntegerCollection();
                    AcadGi.TransientManager.CurrentTransientManager.AddTransient(lne, AcadGi.TransientDrawingMode.DirectShortTerm, 128, coll);
                    tempG.eraseLineList.Add(lne);
                }               
            }


The next set runs while you are hovering over the block reference while KeepOn is true which is set true by the method called from
Code: [Select]
Application.DocumentManager.MdiActiveDocument.Editor.PromptForSelectionEnding += new PromptForSelectionEndingEventHandler(HoverEndingHandler);

Once set to false in HoverHandler method it sets the DrawAction to 123 so the instructions in the MainThreadProcess Method following the else statement will erase the graphics

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Animated Block Hover
« Reply #11 on: November 04, 2010, 12:27:41 AM »
First Off let me apologize Thorsten for posting this mess
Kerry in your reply will you edit Spiffy by changing the 'p' to a 'h' and the 'f's to 't's
< .. >




I feel that spiffy still works as I made no qualitative judgment   :-D

http://www.urbandictionary.com/define.php?term=spiffy
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.