尝试使用 C# 上的 AutoCAD 类镜像图形

Posted

技术标签:

【中文标题】尝试使用 C# 上的 AutoCAD 类镜像图形【英文标题】:Trying to mirror a drawing using the AutoCAD class on C# 【发布时间】:2020-03-22 19:45:42 【问题描述】:

目前我有一个使用 AutoCAD 类绘制的对象,但我可以选择在绘制后镜像它。我不知道该怎么做。

[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()
        

这个md.Translation.Mirror() 是我认为需要改变的行。我已经尝试了很多方法来做镜像,但我一直回到这个问题,因为我不知道s1 对象是这样保存的。也许认为它需要转换为实体?

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();
                
            

        

【问题讨论】:

嗯,看起来你试图镜像什么。你有一个没有数据的默认实例化二维矩阵......所以你的镜像不起作用是有道理的。您需要引用某种模型空间对象才能镜像。您很可能需要创建一个新事务来将新镜像的对象插入模型空间。对不起,如果我的术语被关闭了,我已经有几年没有为 autocad 编程了。 @TraeMoore 我不知道如何去照镜子,所以你说得对,事实上我没有引用任何东西。 s1 正在按照我希望的方式绘制。但是我不确定如何在它被实例化的命令中镜像它。 【参考方案1】:

我直到现在才弄清楚这一点。许多试验和错误。我会尽力提供尽可能多的代码示例

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


【讨论】:

天哪……很高兴你知道了!【参考方案2】:

此示例取自 AutoCAD 2017 .Net SDK。

您似乎错过了在变换上设置镜像点并将镜像副本插入到BlockTable。添加新的p1 (polyline) 后,下面的代码应直接执行。我从here 得到了这个代码示例。试一试,让我知道。干杯!

 // 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);

【讨论】:

我试试看!明天给你回复 我试过了,无法与我正在做的比较。 @Joelad,尝试利用折线构建块,然后将块添加到模型空间。一旦你有了块参考,镜像块。您可能需要重新构建您的一些代码......但以同样的能力,您可能应该有一个创建对象的工厂,然后有一个块转换器将对象转换为块。然后使用自定义实用程序(您将构建的实用程序)在模型空间中镜像。 谢谢,听起来不错,但我不知道该怎么做:( 从这里开始:through-the-interface.typepad.com/through_the_interface/2010/01/…。 Keen Walmsley 为 c# AutoCad 开发撰写了一篇出色的博客。

以上是关于尝试使用 C# 上的 AutoCAD 类镜像图形的主要内容,如果未能解决你的问题,请参考以下文章

C#语言对AutoCAD二次开发

AUTOCAD——复制命令

AutoCad 二次开发 文字镜像

CAD三维绘图的快捷命令

如何使用 C# 在 Autocad 文件中获取标签名称

AutoCAD如何将dwf转成dwg格式