我尝试以编程方式在AutoCAD中绘制实体3D形状。我可以将形状绘制为线框。这是我的代码目前绘制的内容
该对象是一组AutoCAD线组合在一起成为一个Group对象。我想要的是一个方法,它将一个Group作为一个参数,并将该组转换为一个可靠的块引用。这是我的尝试。
public static void DefineBlockFromGroup(Group groupToCreateBlockFrom, string blockName, Point3d origin, bool replaceChosenEntities = false)
{
List<ObjectId> idsOfEntitiesInGroup = groupToCreateBlockFrom.GetAllEntityIds().ToList(); //Getting the entities that will be used to create the block
CreateBlockDefinition(idsOfEntitiesInGroup, blockName, origin, replaceChosenEntities);
}
public static void CreateBlockDefinition(List<ObjectId> entities, string blockName, Point3d origin, bool replaceChosenEntities = false)
{
BlockTableRecord record = new BlockTableRecord(); //Will become record of new block type
ObjectId blockId = ObjectId.Null; //Will become id of new block type
using (Transaction tr = _database.TransactionManager.StartTransaction())
using (DocumentLock docLock = _activeDocument.LockDocument())
{
BlockTable bt = (BlockTable)tr.GetObject(_database.BlockTableId, OpenMode.ForRead); //Getting block table to put new record in
bt.UpgradeOpen();
record = new BlockTableRecord(); //New record will contain all entities which will make up the block
record.Name = blockName; //Setting name of the block
record.Origin = origin; //Setting origin point of the block
bt.Add(record);
tr.AddNewlyCreatedDBObject(record, true);
blockId = bt[record.Name];
tr.Commit();
}
//copy the select entities to block by using deepclone.
ObjectIdCollection collection = new ObjectIdCollection(entities.ToArray());
IdMapping mapping = new IdMapping();
_database.DeepCloneObjects(collection, blockId, mapping, false);
if (replaceChosenEntities)
{
using (Transaction tr = _database.TransactionManager.StartTransaction())
using (DocumentLock docLock = _activeDocument.LockDocument())
{
Entity baseEntity = tr.GetObject(entities[0], OpenMode.ForWrite) as Entity;
foreach (ObjectId id in entities)
{
EraseSingleObjectFromDrawingWithId(id);
}
DrawBlockFacingAPoint(record.Name, record.Origin, record.Origin, baseEntity.Layer, null);
tr.Commit();
}
}
}
public static void EraseSingleObjectFromDrawingWithId(ObjectId idOfObjectToErase)
{
// Start a transaction
using (Transaction tr = _database.TransactionManager.StartTransaction())
{
DBObject objToErase = tr.GetObject(idOfObjectToErase, OpenMode.ForWrite);
// Check to make sure a valid SelectedObject object was returned
if (objToErase != null)
{
objToErase.Erase();
}
tr.Commit();
}
}
public static BlockReference DrawBlockFacingAPoint(string name, Point3d position, Point3d direction, string layerToInsertOn, List<string> attributeValues = null, Distance xScale = null, Distance yScale = null, Distance zScale = null)
{
LastPositionPoint = position;
LastDirectionPoint = direction;
//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); //Generating first AutoCAD point
Point end = Point.MakePointWithInches(direction.X, direction.Y, direction.Z); //Generating second AutoCAD point
GeometryClassLibrary.Line line = new GeometryClassLibrary.Line(start, end); //Creating a line to mirror a block over if necessary
Angle a = new Angle(AngleType.Radian, 0); //Angle to rotate the block by
//Assigning angle based on direction point
if (position.Y != direction.Y)
{
a = line.AngleBetween(GeometryClassLibrary.Line.XAxis);
}
if (direction.Y < position.Y)
{
blkRef.Rotation = a.Negate().GetValue(AngleType.Radian); //Allowing for rotations beyond 180 degrees
}
else
{
blkRef.Rotation = a.GetValue(AngleType.Radian);
}
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 (ArgumentNullException)
{
ar.TextString = "";
}
catch (ArgumentOutOfRangeException)
{
ar.TextString = "";
}
attCounter++;
blkRef.AttributeCollection.AppendAttribute(ar);
tr.AddNewlyCreatedDBObject(ar, true);
}
}
tr.Commit();
return blkRef;
}
}
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;
}
}
很抱歉,涉及的方法太多了。我认为问题在于实际绘制块,但我包含所有涉及的方法以防万一。无论如何,这些方法成功地创建了块定义并绘制了该块的实例来代替行组。问题是块仍然是线框。如果有人知道如何改变这种方法来绘制固体块我将会感到邪恶!
答案 0 :(得分:0)
如果通过&#39;线框&#39;你的意思是一堆线,然后你需要做一些几何操作。如果你看看Solid3d.Create ....方法,你会看到一些选项,我相信得到一个面和挤出可能是最简单的。在UI上有一些命令,请参阅SURFSCULPT命令。