Author Topic: Mleaders in Bricscad.  (Read 214 times)

0 Members and 1 Guest are viewing this topic.

Atook

  • Swamp Rat
  • Posts: 846
Mleaders in Bricscad.
« on: November 15, 2017, 01:14:53 am »
I'm having some trouble with mleaders I'm creating in Bricscad via C#. I'm using the same code to create Mleaders in AutoCAD (ACAD_APP), and haven't had any issues. The Bricscad leaders (BRX_APP) are coming in with a landing gap, and the ones I create programatically don't work correctly when grip edited in CAD. If I use the MLeader command (BRX_CMD) in Bricscad, they translate to AutoCAD just fine. To me that's indicating there's fundamental property or something I'm not setting that needs to be included for the Bricscad code.

Any ideas what I need to include (or delete) in my code to get the Bricscad Mleaders working properly?

The GIF shows the defective MLeaders not working in AutoCAD.


Code - C#: [Select]
  1. #if BRX_APP
  2. using System.Diagnostics;
  3. using Teigha.Runtime;
  4. using Teigha.DatabaseServices;
  5. using Bricscad.ApplicationServices;
  6. using Teigha.Geometry;
  7. using Bricscad.EditorInput;
  8. using Arx_App = Bricscad.ApplicationServices.Application;
  9. #elif ACAD_APP
  10. using System.Diagnostics;
  11. using Autodesk.AutoCAD.ApplicationServices;
  12. using Autodesk.AutoCAD.DatabaseServices;
  13. using Autodesk.AutoCAD.EditorInput;
  14. using Autodesk.AutoCAD.Geometry;
  15. using Autodesk.AutoCAD.Runtime;
  16. using Bricscad.PlottingServices;
  17. using Arx_App = Autodesk.AutoCAD.ApplicationServices.Application;
  18. #endif
  19.  
  20. namespace AID
  21. {
  22.  public class SwampCode
  23.  {
  24.    [CommandMethod("TestMleader")]
  25.    public void MleaderTest()
  26.    {
  27.      Document doc = Arx_App.DocumentManager.MdiActiveDocument;
  28.      Database db = doc.Database;
  29.      Editor ed = doc.Editor;
  30.  
  31.      // set the active style
  32.      db.MLeaderstyle = GetMLeaderStyleID("Test");
  33. #if BRX_APP
  34.      // points for the leader
  35.      Point3d leaderPoint = new Point3d(40, 40, 0); // point for leader end point
  36.      Point3d textPoint = new Point3d(50, 20, 0);  // point for label text
  37.      string labelString = "BRX_APP";
  38. #elif ACAD_APP
  39.      Point3d leaderPoint = new Point3d(0, 40, 0); // point for leader end point
  40.      Point3d textPoint = new Point3d(10, 20, 0);  // point for label text
  41.      string labelString = "ACAD_APP";
  42. #endif
  43.  
  44.      // create the MLeader
  45.      MLeader label = new MLeader();
  46.      label.SetDatabaseDefaults();
  47.      label.ContentType = ContentType.MTextContent;
  48.      label.Layer = "mleader";
  49.      int ldNum = label.AddLeader();
  50.      int idx = label.AddLeaderLine(ldNum);
  51.      label.AddFirstVertex(idx, leaderPoint);
  52.      label.AddLastVertex(idx, textPoint);
  53.  
  54.      // new Mtext for the text
  55.      MText mText = new MText();
  56.      mText.SetDatabaseDefaults();
  57.      mText.Contents = labelString;
  58.      mText.TextHeight = 2.5;
  59.      mText.Attachment=AttachmentPoint.MiddleCenter;
  60.      mText.SetAttachmentMovingLocation(AttachmentPoint.MiddleCenter);
  61.  
  62.      label.MText = mText;
  63.  
  64.  
  65.      // add the mleader to currspace
  66.      using (Transaction tr = (doc.TransactionManager).StartTransaction())
  67.      {
  68.        BlockTableRecord curSpace =
  69.        (BlockTableRecord)tr.GetObject(Active.Database.CurrentSpaceId, OpenMode.ForWrite);
  70.  
  71.        curSpace.AppendEntity(label);
  72.        tr.AddNewlyCreatedDBObject(label, true);
  73.        tr.Commit();
  74.      }
  75.    }
  76.  
  77.  
  78.    /// <summary>
  79.    /// Checks if the MLeader Style definition is in the active drawing.
  80.    /// </summary>
  81.    /// <param name="styleName">Name of the MLeader style.</param>
  82.    /// <returns>ObjectID of MLeader style, ObjectId.Null on error</returns>
  83.    public static ObjectId GetMLeaderStyleID(string styleName)
  84.    {
  85.      ObjectId styleId = ObjectId.Null; ;
  86.      using (Transaction tr = (Arx_App.DocumentManager.MdiActiveDocument.TransactionManager).StartTransaction())
  87.      {
  88.        DBDictionary mlDictionary = (DBDictionary)tr.GetObject(Active.Database.MLeaderStyleDictionaryId, OpenMode.ForRead);
  89.        if (mlDictionary.Contains(styleName))
  90.        {
  91.          styleId = mlDictionary.GetAt(styleName);
  92.          MLeaderStyle style = tr.GetObject(styleId, OpenMode.ForWrite) as MLeaderStyle;
  93.          if (style != null)
  94.          {
  95.            Debug.Print($"style.LandingGap: {style.LandingGap}");
  96.            Debug.Print($"style.EnableLanding: {style.EnableLanding}");
  97.          }
  98.        }
  99.        tr.Commit();
  100.        return styleId;
  101.      }
  102.    }
  103.  }
  104. }
  105.  
« Last Edit: November 15, 2017, 08:05:41 pm by Atook »

Bryco

  • Water Moccasin
  • Posts: 1812
Re: Mleaders in Bricscad.
« Reply #1 on: November 16, 2017, 11:15:32 am »
 MLStyle.SetTextAttachmentType(TextAttachmentType.AttachmentMiddle, LeaderDirectionType.LeftLeader);
                MLStyle.SetTextAttachmentType(TextAttachmentType.AttachmentMiddle, LeaderDirectionType.RightLeader);

does you style have these attachments?

MickD

  • Gator
  • Posts: 2970
  • I don't need a job, I need Money!!
Re: Mleaders in Bricscad.
« Reply #2 on: November 16, 2017, 03:20:37 pm »
I only quickly scanned your code but I've had problems with leaders and mtext before and found I had to add the leader to the db before doing any modifications. That is, create a standard leader with defaults, add it to the db then set points and mtext etc.

hth
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

Atook

  • Swamp Rat
  • Posts: 846
Re: Mleaders in Bricscad.
« Reply #3 on: November 16, 2017, 04:48:56 pm »
Thanks Bryco, seems like I either needed to set the mText.Attachment, or the leader.SetTextAttachmentType properties and the grip edits in AutoCAD worked as expected.

Also, in Bricscad, the SetTextAttachmentType method worked, where as setting TextAttachmentType directly threw an eInvalidInput error.

Now for more experimenation to figure out why the code generated mleaders appear to have a dogleg, and the command generated ones dont.

I'll try MickD's approach and add the Mleader to the database before setting any properties.

Atook

  • Swamp Rat
  • Posts: 846
Re: Mleaders in Bricscad.
« Reply #4 on: November 16, 2017, 04:52:43 pm »
I only quickly scanned your code but I've had problems with leaders and mtext before and found I had to add the leader to the db before doing any modifications. That is, create a standard leader with defaults, add it to the db then set points and mtext etc.

hth

MickD, when you say add it to the db, do I need to add it to the transaction, or actually commit the transaction, then retrieve the Mleader  with a new transaction again and set the properties?

MickD

  • Gator
  • Posts: 2970
  • I don't need a job, I need Money!!
Re: Mleaders in Bricscad.
« Reply #5 on: November 16, 2017, 05:44:13 pm »
I only quickly scanned your code but I've had problems with leaders and mtext before and found I had to add the leader to the db before doing any modifications. That is, create a standard leader with defaults, add it to the db then set points and mtext etc.

hth

MickD, when you say add it to the db, do I need to add it to the transaction, or actually commit the transaction, then retrieve the Mleader  with a new transaction again and set the properties?

Yep, commit it then open with the returned objectid. cheers.
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

MickD

  • Gator
  • Posts: 2970
  • I don't need a job, I need Money!!
Re: Mleaders in Bricscad.
« Reply #6 on: November 16, 2017, 06:00:27 pm »
sorry Atook, it's been a while but I dug out a snippet I use below, hth

Code - C#: [Select]
  1.        public static void DrawLeaderForText(Point3d startPoint, Point3d endPoint, ObjectId textId)
  2.        {
  3.            var db = HostApplicationServices.WorkingDatabase;
  4.            using (var tr = db.TransactionManager.StartTransaction())
  5.            {
  6.                var layout = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  7.                var leader = new Leader();
  8.                //leader.SetDatabaseDefaults();
  9.                leader.AppendVertex(startPoint);
  10.                leader.AppendVertex(endPoint);
  11.                leader.HasArrowHead = false;
  12.                var mt = tr.GetObject(textId, OpenMode.ForRead) as MText;
  13.                if(mt != null)
  14.                {
  15.                    var tsid = mt.TextStyleId;
  16.                    leader.TextStyleId = tsid;
  17.                    leader.DimensionStyle = db.Dimstyle;
  18.                }
  19.  
  20.                layout.AppendEntity(leader);
  21.                tr.AddNewlyCreatedDBObject(leader, true);
  22.                leader.Annotation = textId;
  23.                leader.EvaluateLeader();
  24.                tr.Commit();
  25.            }
  26.        }
  27.  
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

Atook

  • Swamp Rat
  • Posts: 846
Re: Mleaders in Bricscad.
« Reply #7 on: November 16, 2017, 06:20:44 pm »
Thanks Mick.

Atook

  • Swamp Rat
  • Posts: 846
Re: Mleaders in Bricscad.
« Reply #8 on: November 27, 2017, 03:49:34 pm »
Turns out the problem was that Bricscad needs to have .SetLastVertex() called instead of .AddLastVertex(). If AddLastVertex is called in Bricscad, an additional control point is added to the leader.

AutoCAD, however, requires the .AddLastVertex() and doesn't seem to care about the .SetLastVertex().

The code for setting vertices now looks like this:
Code - C#: [Select]
  1.  int ldNum = label.AddLeader();
  2.  int idx = label.AddLeaderLine(ldNum);
  3.  label.AddFirstVertex(idx, leaderPoint);
  4. #if ACAD_APP
  5.  label.AddLastVertex(idx, textPoint);
  6. #endif
  7.  label.SetLastVertex(idx, textPoint);

Thanks to Bricscad technical support for helping me out.
« Last Edit: November 27, 2017, 04:03:20 pm by Atook »