2

Currently I have an object drawn using the AutoCAD class but I the option to mirror it once drawn. I'm not sure how to go about this.

[CommandMethod("DrawTestDoor")]
        public void DrawTestDoor()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument; 
            var ed = acDoc.Editor;
            XDDoor s1 = new XDDoor();
            PromptKeywordOptions pKeyOpts = new PromptKeywordOptions("");
            pKeyOpts.Message = "\nIt is Rated ";
            pKeyOpts.Keywords.Add("True");
            pKeyOpts.Keywords.Add("False");
            pKeyOpts.Keywords.Default = "True";
            pKeyOpts.AllowNone = true;
            PromptResult pKeyRes = acDoc.Editor.GetKeywords(pKeyOpts);
            bool fireRated = Convert.ToBoolean(pKeyRes.StringResult);

            var promptResultheight = ed.GetString("\nEnter the Frame height: ");
            double height = Convert.ToDouble(promptResultheight.StringResult);

            var promptResultwidth = ed.GetString("\nFrame Width: ");
            double width = Convert.ToDouble(promptResultwidth.StringResult);

            var promptResultFrameDepthChange = ed.GetString("\nEnter the frame depth change ");
            double frameDepthChange = Convert.ToDouble(promptResultFrameDepthChange.StringResult);

            PromptKeywordOptions pKeyOpts1 = new PromptKeywordOptions("");
            pKeyOpts1.Message = "\nDoor Handle Side";
            pKeyOpts1.Keywords.Add("Left");
            pKeyOpts1.Keywords.Add("Right");
            pKeyOpts1.Keywords.Default = "Left";
            pKeyOpts1.AllowNone = true;
            s1.DrawSingleXDDoor(height, width, fireRated, frameDepthChange);
            Matrix2d md = new Matrix2d();
            md.Translation.Mirror()
        }

This md.Translation.Mirror() is the line that I think needs changed. I have tried numerous ways to do the mirror but I keep coming back to the issue with I dont know what the s1 object is being saved as as such. Maybe thinking it needs converted to an entity?

public void DrawSingleXDDoor(double height, double width, bool fireRated, double frameDepthChange)
        {
            DrawLid("lid", leafHeight, lidWidth);
        }

public void DrawLid(string type, double height, double width)
        {
            DrawShapes d1 = new DrawShapes();
            DrawComponents xd = new DrawComponents();
            d1.DrawRectangle(0, 0, height, width);
        }
public void DrawRectangle(double startx, double starty, double recHeight, double recWidth)
        {
            double height = recHeight;
            double width = recWidth;
            //Get the drawing document and the dataabses object
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    BlockTable bt;
                    bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                    BlockTableRecord btr;
                    btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; 
                    Polyline p1 = new Polyline();
                    p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
                    p1.AddVertexAt(0, new Point2d(startx + 0, starty + height), 0, 0, 0);
                    p1.AddVertexAt(0, new Point2d(startx + width, starty + height), 0, 0, 0);
                    p1.AddVertexAt(0, new Point2d(startx + width, starty + 0), 0, 0, 0);
                    p1.AddVertexAt(0, new Point2d(startx + 0, starty + 0), 0, 0, 0);
                    p1.SetDatabaseDefaults();
                    btr.AppendEntity(p1);
                    trans.AddNewlyCreatedDBObject(p1, true);
                    trans.Commit();
                }
                catch (System.Exception ex)
                {
                    doc.Editor.WriteMessage("Error encountered: " + ex.Message);
                    trans.Abort();
                }
            }

        }
Joelad
  • 492
  • 3
  • 12
  • Well, it looks like your trying to mirror nothing. You have a default instanciated 2d matrix with no data... so it would make sense that your mirroring will not work. you need to have a reference to some sort of model space object in order to mirror. You most likely will need to create a new transaction to insert the newly mirrored object into the modelspace. Sorry if my terminology is off, its been a few years since i've programmed for autocad. – Trae Moore Nov 27 '19 at 17:52
  • @TraeMoore I'm not sure how to go about the mirror so youre right in the fact I'm not referencing anything. s1 is being drawn how I want it to be drawn. However I'm not sure how to go about mirroring it within the command where it is being instantiated. – Joelad Nov 28 '19 at 09:57

2 Answers2

0

This example was pulled from AutoCAD 2017 .Net SDK.

It looks like you missed setting the mirror point on the transform and insert the mirrored copy to the BlockTable. The code below should execute directly after adding your new p1 (polyline). I got this code sample from here. Give it a shot and let me know. Cheers!

 // Define the mirror line
        Point3d acPtFrom = new Point3d(0, 4.25, 0);
        Point3d acPtTo = new Point3d(4, 4.25, 0);
        Line3d acLine3d = new Line3d(acPtFrom, acPtTo);

        // Mirror the polyline across the X axis
        acPolyMirCopy.TransformBy(Matrix3d.Mirroring(acLine3d));

        // Add the new object to the block table record and the transaction
        acBlkTblRec.AppendEntity(acPolyMirCopy);
        acTrans.AddNewlyCreatedDBObject(acPolyMirCopy, true);
Trae Moore
  • 1,759
  • 3
  • 17
  • 32
  • 1
    Ill give it a go! Ill get back to you tomorrow – Joelad Dec 04 '19 at 09:37
  • I tried it, Cant get it to compare with what I'm doing. – Joelad Dec 05 '19 at 11:33
  • @Joelad, try utilizing the polylines to build a block and then add the block to the modelspace. once you have the block reference, mirror the block. You may have to restructure some of your code... but in the same capacity, you should probably have a factory that creates the objects and then a block converter to convert the objects to a block. Then utilize a custom utility (one you will build) to mirror across the modelspace. – Trae Moore Dec 05 '19 at 13:41
  • Thanks, that sounds nice and all but i dont how to go about it :( – Joelad Dec 05 '19 at 13:45
  • 1
    Start here: https://through-the-interface.typepad.com/through_the_interface/2010/01/creating-an-autocad-block-using-net.html. Keen Walmsley has an excellent blog to follow for c# AutoCad development. – Trae Moore Dec 05 '19 at 13:45
  • steps: Create lines, use lines to create a block, add block to modelspace, mirror block. Sorry, I don't have a computer that can run AutoCAD at the moment. Otherwise I would code an example for you. – Trae Moore Dec 05 '19 at 13:49
  • Cheers. Still seems complicated on where to put the lines of code in each method – Joelad Dec 05 '19 at 14:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203676/discussion-between-trae-moore-and-joelad). – Trae Moore Dec 05 '19 at 14:56
  • I never got this working till now... Ive been working on this the whole time too. I just literally wasnt even thinking about it while doing it either. it just popped out – Joelad Apr 13 '21 at 13:19
0

It has taken me till now to figure this out. Many trials and errors. I will do my best to give as much code as possible with an example

arrays.cs

        public void PopulateWithOldArray(List<double> newArray, List<double> oldArray, bool negate)
        {
            //if there are any previous version of the new array we want them to be cleared so that the called old array will not be affected
            newArray.Clear();
            if (negate == true)
            {
                for (int i = 0; i < oldArray.Count; i++)
                {
                    newArray.Add(-oldArray[i]);
                }
            }
            else
            {
                for (int i = 0; i < oldArray.Count; i++)
                {
                    newArray.Add(oldArray[i]);
                }
            }
        }//end PopulateWithOldArray


        public void MirrorXaxis(double startx, double starty, List<double> x, List<double> y, List<double> angle)
        {
            List<double> changedx = new List<double> { };
            List<double> changedangle = new List<double> { };
            PopulateWithOldArray(changedx, x, true);
            PopulateWithOldArray(changedangle, angle, true);
            DrawShapes ds = new DrawShapes();
            for (int i = 0; i < angle.Count; i++)
            {
                ds.DrawPolyLine(changedx[i] + startx, y[i] + starty, changedx[i + 1] + startx, y[i + 1] + starty, changedangle[i]);
            }//end for
        }//end mirror

drawshapes.cs

using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

namespace doorsetsDraw
{
class DrawShapes
    {
       public void DrawPolyLine(double startx, double starty, double endx, double endy, double endBulgeAngle)
        {
            //Get the drawing document and the dataabses object
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;

            //create the transaction object inside the using block
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {
                try
                {
                    //get the blocktable object
                    //doc.Editor.WriteMessage("Drawing a 2d Polyline!"); //extra option to last editor
                    BlockTable bt;
                    bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

                    BlockTableRecord btr;
                    btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; //draw into model space

                    //specify the polyline's coordinates
                    Polyline p1 = new Polyline();

                    p1.AddVertexAt(0, new Point2d(startx, starty), 0, 0, 0);

                    p1.AddVertexAt(0, new Point2d(endx, endy), BulgeEquationTan(endBulgeAngle), 0, 0);

                    p1.SetDatabaseDefaults();
                    btr.AppendEntity(p1);
                    trans.AddNewlyCreatedDBObject(p1, true);
                    trans.Commit();
                }
                catch (System.Exception ex)
                {
                    doc.Editor.WriteMessage("Error encountered: " + ex.Message);
                    trans.Abort();
                    //abort to roll out of excpetion for unreferenced object
                }//end catch
            }//end using
        }//end drawpolylineElip

        public double BulgeEquationTan(double angleD)
        {
            double tanV = ConvertToRadians(angleD) / 4;
            double tanA = Math.Tan(tanV);
            return tanA;
        }//end BulgeEquationTan

        public double ConvertToRadians(double angle)
        {
            return (Math.PI / 180) * angle;
        }//end ConvertToRadians
}
}
Joelad
  • 492
  • 3
  • 12