Author Topic: Mtext Wipeout  (Read 5767 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Mtext Wipeout
« on: July 02, 2012, 02:17:07 PM »
I know I am making this harder than it is.
 
Probably would be better just to create one wipeout, but for starting out just trying to get the bounding box for each fragment.
 
Am I correct assuming this?
 
MTextFragment.Location will give me the bottom left corner of the fragment.
I have the direction from MTextFragment.Direction
I have the distance in X and Y diretion with MTextFragment.Extents.X & MTextFragment.Extents.Y
 
What is the eaiset way to get the four corners or bounding box.
 
I am drawing a blank but I thought with direction vector and distance I could find the 3 other points?
Would it be easier to get the botttom 2 then move them a distance with MTextFragment.Extents.Y or MTextFragment.CapsHeight?
 
For starters here this will just get the bottom left.
Code: [Select]
        [CommandMethod("ExplodeFragments")]
        static public void ExplodeFragments()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
 
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a Mtext");
            peo.SetRejectMessage("\nSelect only Mtext");
            peo.AddAllowedClass(typeof(MText), false);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK)
                return;
            using (Transaction trx = db.TransactionManager.StartTransaction())
            {
                MText text = trx.GetObject(per.ObjectId, OpenMode.ForRead) as MText;
                text.ExplodeFragments(Fragments);
                trx.Commit();
            }
        }
 
        static public MTextFragmentCallbackStatus Fragments(MTextFragment frag, object data)
        {   
            createWipeOut(frag);
            return MTextFragmentCallbackStatus.Continue;
        }
        static void createWipeOut(MTextFragment frag)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            Point3dCollection pnts = new Point3dCollection();
 
            pnts.Add(frag.Location);   
           
            foreach (Point3d pnt in pnts)
            {
                ed.WriteLine(pnt.ToString());           
            }
       
        }

 

BlackBox

  • King Gator
  • Posts: 3770
Re: Mtext Wipeout
« Reply #1 on: July 02, 2012, 05:31:06 PM »
Jeff,

Rather than creating new entities, and managing their draw order, wouldn't it be simpler to just manipulate the Background Mask?

Here's a LISP example Lee's provided, that you might translate to C#.
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #2 on: July 02, 2012, 06:22:16 PM »
Not wanting the mask to be as wide as longest line in every line.
 
In pic how the mask(in black) is as wide as longest line for all lines.
 
 

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #3 on: July 02, 2012, 06:28:26 PM »
Was going for something similar to

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Mtext Wipeout
« Reply #4 on: July 02, 2012, 07:00:51 PM »
Was going for something similar to


That deserves to be added to the AutoCAD wish list :)

... as does having a global system variable for the scale factor ... 1.5 seems to be hard coded in there somewhere.
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: Mtext Wipeout
« Reply #5 on: July 02, 2012, 09:02:59 PM »
Maybe this will help make more sense, this example is bad coding and was throwing it together quickly as a example but works for basic Mtext that's rotation is 0.
 
Instead of calculating points like this
Code - C#: [Select]
  1.  pnts.Add(new Point2d(frag.Location.X, frag.Location.Y));
  2.  
  3. Point2d pnt2 = new Point2d(frag.Location.X + frag.Extents.X, frag.Location.Y);
  4. pnts.Add(pnt2);
  5.  
  6.  
  7. Point2d pnt3 = new Point2d(pnt2.X, pnt2.Y + frag.Extents.Y);
  8. pnts.Add(pnt3);
  9.  
  10.  
  11. Point2d pnt4 = new Point2d(frag.Location.X, frag.Location.Y + frag.Extents.Y);
  12. pnts.Add(pnt4);
  13.  
  14.  

Isn't there a way to calculate the point with a base point, the distance, and a direction vector?
 
 
 
Code - C#: [Select]
  1.  
  2.    [CommandMethod("ExplodeFragments")]
  3.         static public void ExplodeFragments()
  4.         {
  5.             Document doc = Application.DocumentManager.MdiActiveDocument;
  6.             Database db = doc.Database;
  7.             Editor ed = doc.Editor;
  8.  
  9.             PromptEntityOptions peo = new PromptEntityOptions("\nSelect a Mtext");
  10.             peo.SetRejectMessage("\nSelect only Mtext");
  11.             peo.AddAllowedClass(typeof(MText), false);
  12.             PromptEntityResult per = ed.GetEntity(peo);
  13.             if (per.Status != PromptStatus.OK)
  14.                 return;
  15.             using (Transaction trx = db.TransactionManager.StartTransaction())
  16.             {
  17.                 MText text = trx.GetObject(per.ObjectId, OpenMode.ForRead) as MText;
  18.                 text.ExplodeFragments(Fragments);                
  19.                 BlockTableRecord btr = db.CurrentSpace(OpenMode.ForWrite);
  20.                 DrawOrderTable dot = btr.DrawOrderTableId.GetObject(OpenMode.ForWrite) as DrawOrderTable;
  21.                 ObjectIdCollection ids = new ObjectIdCollection();
  22.                 ids.Add(text.ObjectId);
  23.                 dot.MoveToTop(ids);
  24.                 trx.Commit();
  25.             }
  26.         }
  27.  
  28.         static public MTextFragmentCallbackStatus Fragments(MTextFragment frag, object data)
  29.         {  
  30.             createWipeOut(frag);
  31.             return MTextFragmentCallbackStatus.Continue;
  32.         }
  33.         static void createWipeOut(MTextFragment frag)
  34.         {
  35.             Document doc = Application.DocumentManager.MdiActiveDocument;
  36.             Database db = doc.Database;
  37.             Editor ed = doc.Editor;
  38.  
  39.             Point2dCollection pnts = new Point2dCollection();
  40.  
  41.             pnts.Add(new Point2d(frag.Location.X, frag.Location.Y));          
  42.  
  43.             Point2d pnt2 = new Point2d(frag.Location.X + frag.Extents.X, frag.Location.Y);
  44.             pnts.Add(pnt2);
  45.  
  46.             Point2d pnt3 = new Point2d(pnt2.X, pnt2.Y + frag.Extents.Y);
  47.             pnts.Add(pnt3);
  48.  
  49.             Point2d pnt4 = new Point2d(frag.Location.X, frag.Location.Y + frag.Extents.Y);
  50.             pnts.Add(pnt4);
  51.  
  52.             pnts.Add(new Point2d(frag.Location.X, frag.Location.Y));    
  53.  
  54.             using (Transaction trx = db.TransactionManager.StartTransaction())
  55.             {
  56.                 BlockTableRecord btr = db.CurrentSpace(OpenMode.ForWrite);
  57.                 Wipeout wp = new Wipeout();
  58.                 wp.SetDatabaseDefaults();
  59.                 wp.SetFrom(pnts, frag.Normal);
  60.                 btr.AppendEntity(wp);
  61.                 trx.AddNewlyCreatedDBObject(wp, true);
  62.                 trx.Commit();
  63.             }
  64.        
  65.         }
  66.  

Chumplybum

  • Newt
  • Posts: 97
Re: Mtext Wipeout
« Reply #6 on: July 02, 2012, 09:03:40 PM »
Hi Jeff,

I wrote a routine that does something similar called HaloText (its free from the exchange store: http://apps.exchange.autodesk.com/ACD/Detail/Index?id=appstore.exchange.autodesk.com%3ahalotext%3aen). Instead of the background mask being rectangular, it follows the text similar to a halo (see attached image for a better explanation :-))... The new version will have an option to match the background colour.

I ended up using an overrule which clones the text (mtext / dbtext) and adds a lineweight factor to it, unfortunately this doesn't work for truetype fonts.


Cheers, Mark

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #7 on: July 02, 2012, 09:06:39 PM »
Have not been to the app store in a while.
 
Thanks Mark, and will definitely check it out!

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #8 on: July 03, 2012, 12:37:30 PM »
Was going for something similar to


That deserves to be added to the AutoCAD wish list :)

... as does having a global system variable for the scale factor ... 1.5 seems to be hard coded in there somewhere.

Looks like it was added to wish list in 2005 and I voted it , so not looking to great for 2014.

BlackBox

  • King Gator
  • Posts: 3770
Re: Mtext Wipeout
« Reply #9 on: July 03, 2012, 12:43:49 PM »
I agree that this sort of masking would be a great feature.

When you extract the TextString, must you process each character independently, or can you parse the String by line(s), and extract the extents for each line of text?
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #10 on: July 03, 2012, 01:00:23 PM »
I agree that this sort of masking would be a great feature.

When you extract the TextString, must you process each character independently, or can you parse the String by line(s), and extract the extents for each line of text?
Basiclly the ExplodeFragments will return one or more MTextFragment [/b]objects for each line of text. If no changes to font, color, etc.... then should be one for each line or better yet from docs
Quote
This .NET method wraps the AcDbMText.explodeFragments() ObjectARX function by calling the ExplodeFragments(MTextFragmentCallback enumerator, Object userData, WorldDraw context) method with both userData and context set to null.
 

This function runs through the MText object's text string breaking it up into fragments, calling the fragment elaboration function enumerator for each fragment. The current WorldDraw object is used.
 
The elaboration function is called once for each fragment. enumerator points to an MTextFragment structure that's passed into the elaboration function. enumerator provides all the information about the text fragment for which the elaboration function is being called.
 
The elaboration function should return 1 to continue the elaboration operation, or 0 to terminate the operation.
 
In the context of this function, a fragment is a piece of text that lies on the same "word-wrapped" line and has a specific set of characteristics (that is, font, color, height, width, etc.). So, each word-wrap newline and each change in text characteristics starts a new fragment.

 

BlackBox

  • King Gator
  • Posts: 3770
Re: Mtext Wipeout
« Reply #11 on: July 03, 2012, 02:37:50 PM »
Thanks for the clarification/education on ExplodeFragments, Jeff.
"How we think determines what we do, and what we do determines what we get."

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Mtext Wipeout
« Reply #12 on: July 03, 2012, 04:29:33 PM »
Thanks for the clarification/education on ExplodeFragments, Jeff.
Thanks,
 
but just regurgitating what others already have covered

BlackBox

  • King Gator
  • Posts: 3770
Re: Mtext Wipeout
« Reply #13 on: July 03, 2012, 09:37:56 PM »
Thanks for the clarification/education on ExplodeFragments, Jeff.
Thanks,
 
but just regurgitating what others already have covered

"There are two ways of spreading light; to be the candle, or the mirror that reflects it" - Edith Wharton
"How we think determines what we do, and what we do determines what we get."