在AutoCAD中以一定角度插入块(C#)

时间:2015-08-11 22:02:51

标签: c# autocad autocad-plugin

我正在尝试编写一种能够在AutoCAD中正确绘制块的方法。现在这是我得到的最好的:

public static BlockReference DrawBlock(string name, Point3d position, string layerToInsertOn, List<string> attributeValues = null, Distance xScale = null, Distance yScale = null, Distance zScale = null)
{
    LastPositionPoint = position;
    LastDirectionPoint = position;

    //Creating default distances if null is passed for the scales
    if (xScale == null)
    {
        xScale = new Distance(DistanceType.Inch, 1);
    }
    if (yScale == null)
    {
        yScale = new Distance(DistanceType.Inch, 1);
    }
    if (zScale == null)
    {
        zScale = new Distance(DistanceType.Inch, 1);
    }

    ObjectId blkRecId = _generateBlockRecordId(name); //Generating ID for the block
    BlockReference blkRef = null; //Reference of the block that will be inserted

    using (Transaction tr = _database.TransactionManager.StartTransaction()) //Starting the transaction to insert the block into the drawing
    using (DocumentLock docLock = _activeDocument.LockDocument())
    {
        blkRef = new BlockReference(position, blkRecId); //Creating the block reference
        blkRef.SetDatabaseDefaults();
        blkRef.ScaleFactors = new Scale3d(xScale.Inches, yScale.Inches, zScale.Inches); //Changing the scales to what the programmer specifies
        blkRef.Layer = layerToInsertOn; //Assigning layer to draw the block on
        Point start = Point.MakePointWithInches(position.X, position.Y, position.Z);
        Angle a = new Angle(AngleType.Radian, 0); //Angle to rotate  the block by

        BlockTableRecord blkTblRec = tr.GetObject(_database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
        blkTblRec.AppendEntity(blkRef); //Adding block referece to the block table of the drawing
        tr.AddNewlyCreatedDBObject(blkRef, true); //Adding block to the drawing

        //Assigning attributes of the block
        BlockTableRecord btr = (BlockTableRecord)tr.GetObject(blkRef.BlockTableRecord, OpenMode.ForRead);
        int attCounter = 0; //Counter to iterate through attributes
        foreach (ObjectId objId in btr) //Checking each item in the BlockReference's records
        {
            DBObject obj = objId.GetObject(OpenMode.ForRead);
            if (obj is AttributeDefinition) //If the object is an attribute, update it.
            {
                AttributeDefinition ad = obj as AttributeDefinition;
                AttributeReference ar = new AttributeReference();
                ar.SetAttributeFromBlock(ad, blkRef.BlockTransform);
                ar.Position = ad.Position.TransformBy(blkRef.BlockTransform);
                try
                {
                    ar.TextString = attributeValues.ElementAt(attCounter);
                }
                catch (System.ArgumentOutOfRangeException)
                {
                    ar.TextString = "";
                }
                catch (System.ArgumentNullException)
                {
                    ar.TextString = "";
                }
                attCounter++;
                blkRef.AttributeCollection.AppendAttribute(ar);
                tr.AddNewlyCreatedDBObject(ar, true);
            }
        }
        tr.Commit();
        return blkRef;
    }
}

/// <summary>
        /// Method to generate a block record id for a block to be inserted
        /// </summary>
    private static ObjectId _generateBlockRecordId(string passedBlockName)
    {
        Transaction tr = _database.TransactionManager.StartTransaction();
        DocumentLock docLock = _activeDocument.LockDocument();
        using (tr)
        using (docLock)
        {
            BlockTable blkTbl = tr.GetObject(_database.BlockTableId, OpenMode.ForRead) as BlockTable;
            ObjectId blkRecId = ObjectId.Null;
            if (blkTbl.Has(passedBlockName)) //Checking if the block exists
            {
                blkRecId = blkTbl[passedBlockName]; //If it does, getting the current id
            }
            else //If it doesn't exist create one
            {
                Database blkDb = new Database(false, true);
                blkDb.ReadDwgFile(passedBlockName + ".dwg", System.IO.FileShare.Read, true, ""); //Reading block source file
                _database.Insert(passedBlockName, blkDb, true);
                blkRecId = blkTbl[passedBlockName];
            }
            return blkRecId;
        }
    }

有几个问题。

首先:假设我有一个代表门的街区。这个街区自然是一英尺一英尺。如果我想画一个3&#39;很长一段时间,我将3传递给xScale,以便它正确地代表3&#39;门。结果如下:

enter image description here

这就是我想要的(蓝线表示门进入的墙)。但是,如果墙是垂直方向的,结果就不那么好了。

enter image description here

如何更改DrawBlock方法,以使墙是水平的,垂直的还是介于两者之间的任何位置无关紧要?我知道我可以将长度作为垂直墙的yScale传递,但我需要一个更通用的角度墙解决方案。

此外,如果有人知道如何消除对辅助方法的需求,那也很棒。谢谢!

0 个答案:

没有答案