我从您的代码中学到了很多东西,非常喜欢您的GetObject<T>和GetObjects<T>方法
这很有趣,当我试图用更具功能性/声明性的风格编写C#时,你却用更具命令性的风格来编写F#。
将属性附加到块
的非常基本的代码片段未在多行属性
public static void AppendAttributeTest()
{
Document doc = acadApp.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
try
{
using (doc.LockDocument())
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord currSp = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
PromptNestedEntityOptions pno =
new PromptNestedEntityOptions("\nSelect source attribute to append new attribute below this one >>");
PromptNestedEntityResult nres =
ed.GetNestedEntity(pno);
if (nres.Status != PromptStatus.OK)
return;
ObjectId id = nres.ObjectId;
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
Point3d pnt = nres.PickedPoint;
ObjectId owId = ent.OwnerId;
AttributeReference attref = null;
if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AttributeReference))))
{
attref = tr.GetObject(id,OpenMode.ForWrite) as AttributeReference;
}
BlockTableRecord btr = null;
BlockReference bref = null;
if (owId.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(BlockReference))))
{
bref = tr.GetObject(owId,OpenMode.ForWrite) as BlockReference;
if (bref.IsDynamicBlock)
{
btr = tr.GetObject(bref.DynamicBlockTableRecord,OpenMode.ForRead) as BlockTableRecord;
}
else
{
btr = tr.GetObject(bref.BlockTableRecord,OpenMode.ForRead) as BlockTableRecord;
}
}
Point3d insPt = attref.Position.TransformBy(bref.BlockTransform);
btr.UpgradeOpen();
ObjectIdCollection bids = new ObjectIdCollection();
AttributeDefinition def = null;
foreach (ObjectId defid in btr)
{
if (defid.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AttributeDefinition))))
{
def = tr.GetObject(defid, OpenMode.ForRead) as AttributeDefinition;
if (def.Tag == attref.Tag)
{
def.UpgradeOpen();
bids.Add(defid);
break;
}
}
}
IdMapping map = new IdMapping();
db.DeepCloneObjects(bids, btr.ObjectId, map,true);
ObjectIdCollection coll = new ObjectIdCollection();
AttributeDefinition attDef = null;
foreach (IdPair pair in map)
{
if (pair.IsPrimary)
{
Entity oent = (Entity)tr.GetObject(pair.Value, OpenMode.ForWrite);
if (oent != null)
{
if (pair.Value.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AttributeDefinition))))
{
attDef = oent as AttributeDefinition;
attDef.UpgradeOpen();
attDef.SetPropertiesFrom(def as Entity);
// add other properties from source attribute definition to suit here:
attDef.Justify = def.Justify;
attDef.Position = btr.Origin.Add(
new Vector3d(attDef.Position.X, attDef.Position.Y - attDef.Height * 1.25, attDef.Position.Z)).TransformBy(Matrix3d.Identity
);
attDef.Tag = "NEW_TAG";
attDef.TextString = "New Prompt";
attDef.TextString = "New Textstring";
coll.Add(oent.ObjectId);
}
}
}
}
btr.AssumeOwnershipOf(coll);
btr.DowngradeOpen();
attDef.Dispose();//optional
bref.RecordGraphicsModified(true);
tr.TransactionManager.QueueForGraphicsFlush();
doc.TransactionManager.FlushGraphics();//optional
ed.UpdateScreen();
tr.Commit();
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
}
finally
{
acadApp.ShowAlertDialog("Call command \"ATTSYNC\" manually");
}
}上测试 以下是一个关于将块(一个. dwg文件)插入到当前打开的图形中的小示例。它使用EntitiyJig来动态地要求用户选择一个插入点并设置一个旋转角度。主要功能:
'/**
'* Pedir al usuario donde y con que angulo, para insertar el bloque indicado en el plano abierto en ese momento.
'*/
Public Shared Sub InsertarBloque(ByVal archivoDWG As String)
Dim acadDoc As Document
acadDoc = Application.DocumentManager.MdiActiveDocument
Using acadLockDoc As DocumentLock = acadDoc.LockDocument()
Dim dbTemporal As Database
dbTemporal = New Database(buildDefaultDrawing:=False, noDocument:=True)
dbTemporal.ReadDwgFile(fileName:=archivoDWG, _
fileSharing:=IO.FileShare.Read, _
allowCPConversion:=False, _
password:="")
Dim nombreBloque As String
nombreBloque = IO.Path.GetFileNameWithoutExtension(archivoDWG)
SymbolUtilityServices.ValidateSymbolName(name:=nombreBloque, allowVerticalBar:=False)
Dim acadDB As Database
acadDB = acadDoc.Database
Dim idBloque As ObjectId
idBloque = acadDB.Insert(blockName:=nombreBloque, dataBase:=dbTemporal, preserveSourceDatabase:=False)
Dim bloqueAInsertar As BlockReference
bloqueAInsertar = New BlockReference(position:=Point3d.Origin, BlockTableRecord:=idBloque)
Dim acadEditor As Editor
acadEditor = acadDoc.Editor
bloqueAInsertar.TransformBy(acadEditor.CurrentUserCoordinateSystem)
Dim unaPlantilla As PlantillaBloque_PedirPuntoDeInserccion
unaPlantilla = New PlantillaBloque_PedirPuntoDeInserccion(bloqueAInsertar)
Dim resultadoPedirPunto As PromptResult
resultadoPedirPunto = acadEditor.Drag(unaPlantilla)
If resultadoPedirPunto.Status.Equals(PromptStatus.OK) Then
Dim otraPlantilla As PlantillaBloque_PedirAnguloDeRotacion
otraPlantilla = New PlantillaBloque_PedirAnguloDeRotacion(bloqueAInsertar, _
anguloBase:=bloqueAInsertar.Rotation, _
sistemaCoordenadas:=acadEditor.CurrentUserCoordinateSystem.CoordinateSystem3d, _
puntoBase:=unaPlantilla.getPuntoDeInsercion)
Dim resultadoPedirAngulo As PromptResult
resultadoPedirAngulo = acadEditor.Drag(otraPlantilla)
If resultadoPedirAngulo.Status.Equals(PromptStatus.OK) Then
otraPlantilla.ActualizarRotacion()
Else
bloqueAInsertar.Rotation = 0.0
End If
Using acadTrans As Transaction = acadDoc.TransactionManager.StartTransaction
Dim espacioActual As BlockTableRecord
espacioActual = CType(acadTrans.GetObject(acadDoc.Database.CurrentSpaceId, OpenMode.ForWrite), BlockTableRecord)
espacioActual.AppendEntity(entity:=bloqueAInsertar)
acadTrans.AddNewlyCreatedDBObject(obj:=bloqueAInsertar, add:=True)
Dim bloque As BlockTableRecord
bloque = CType(acadTrans.GetObject(idBloque, OpenMode.ForWrite), BlockTableRecord)
If bloque.HasAttributeDefinitions Then
Dim idElemento As ObjectId
For Each idElemento In bloque
Dim elemento As DBObject
elemento = acadTrans.GetObject(idElemento, OpenMode.ForRead)
If elemento.GetType.Name.Equals("AttributeDefinition") Then
Dim definicionDeAtributo As AttributeDefinition
definicionDeAtributo = CType(acadTrans.GetObject(idElemento, OpenMode.ForRead), AttributeDefinition)
Dim referenciaAAtributo As AttributeReference
referenciaAAtributo = New AttributeReference
referenciaAAtributo.SetAttributeFromBlock(definicionDeAtributo, bloqueAInsertar.BlockTransform)
bloqueAInsertar.AttributeCollection.AppendAttribute(referenciaAAtributo)
acadTrans.AddNewlyCreatedDBObject(obj:=referenciaAAtributo, add:=True)
End If
Next
End If
acadTrans.Commit()
End Using '//acadTrans
End If
End Using '//acadLockDoc
Application.UpdateScreen()
End Sub
要求用户提供插入点:
Friend Class PlantillaBloque_PedirPuntoDeInserccion
Inherits Autodesk.Autocad.EditorInput.EntityJig
Dim mPuntoDeInsercion, mPuntoActivo As Point3d
Public Sub New(bloqueAInsertar as BlockReference)
MyBase.New(bloqueAInsertar)
mPuntoDeInsercion = bloqueAInsertar.Position
End Sub
Protected Overrides Function Sampler(ByVal prompts As Autodesk.AutoCAD.EditorInput.JigPrompts) As Autodesk.AutoCAD.EditorInput.SamplerStatus
Dim opciones As New JigPromptPointOptions
opciones.UserInputControls = UserInputControls.Accept3dCoordinates or _
UserInputControls.NoZeroResponseAccepted or _
UserInputControls.NoNegativeResponseAccepted
opciones.Message = environment.NewLine & "Punto de insercion: "
Dim resultado As PromptPointResult
resultado = prompts.AcquirePoint(opciones)
If mPuntoActivo = resultado.Value Then
Return SamplerStatus.NoChange
Else
mPuntoActivo = resultado.Value
Return SamplerStatus.OK
End If
End Function
Protected Overrides Function Update() As Boolean
mPuntoDeInsercion = mPuntoActivo
Try
CType(Entity, BlockReference).Position = mPuntoDeInsercion
Catch ex As Exception
Return False
End Try
Return True
End Function
Public Function getEntity As Entity
Return Entity
End Function
Public Function getPuntoDeInsercion As Point3d
Return mPuntoDeInsercion
End Function
End Class
向用户询问旋转角度:
Friend Class PlantillaBloque_PedirAnguloDeRotacion
Inherits Autodesk.Autocad.EditorInput.EntityJig
Dim mEntidadARotar As BlockReference
Dim mAnguloBase, mVariacionAngulo As Double
Dim mSistemaDeCoordenadas As CoordinateSystem3d
Dim mPuntoBase As Point3d
Dim mResultado As string
Public Sub New(bloqueAInsertar as BlockReference, _
anguloBase As Double, _
sistemaCoordenadas As CoordinateSystem3d, _
puntoBase As Point3d)
MyBase.New(bloqueAInsertar)
mEntidadARotar = bloqueAInsertar
mAnguloBase = anguloBase
mSistemaDeCoordenadas = sistemaCoordenadas
mPuntoBase = puntoBase
End Sub
Protected Overrides Function Sampler(ByVal prompts As Autodesk.AutoCAD.EditorInput.JigPrompts) As Autodesk.AutoCAD.EditorInput.SamplerStatus
Dim opciones As New JigPromptAngleOptions
opciones.Message = environment.NewLine & "Angulo a rotar: "
opciones.DefaultValue = 0
opciones.BasePoint = mPuntoBase
opciones.UseBasePoint = True
opciones.UserInputControls=UserInputControls.Accept3dCoordinates or UserInputControls.NullResponseAccepted
Dim resultado As PromptDoubleResult
resultado = prompts.AcquireAngle(opciones)
If resultado.Status = PromptStatus.OK Then
mResultado = resultado.StringResult
If mVariacionAngulo = resultado.Value Then
Return SamplerStatus.NoChange
Else
mVariacionAngulo = resultado.Value
Return SamplerStatus.OK
End If
End If
Return SamplerStatus.Cancel
End Function
Protected Overrides Function Update() As Boolean
mEntidadARotar.Rotation = mVariacionAngulo + mAnguloBase
Return True
End Function
Public Sub ActualizarRotacion
mEntidadARotar.Rotation = mVariacionAngulo + mAnguloBase
End Sub
Public Function getEntity As Entity
Return Entity
End Function
Public Function getAnguloDeRotacion As Double
Return mAnguloBase
End Function
Public Function getResultado As String
Return mResultado
End Function
End Class
此函数返回模型空间中按名称列出的特定块引用的所有实例的ObjectdCollection
public ObjectIdCollection GetModelSpaceBlockReferenceOIDCByBlockName(string blockReferenceName)
{
ObjectIdCollection returnOIDs = new ObjectIdCollection();
using (Database db = AcadApp.DocumentManager.MdiActiveDocument.Database)
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btrModel = (BlockTableRecord)trans.GetObject(bt, OpenMode.ForRead);
foreach (ObjectId thisOid in btrModel)
{
Entity blk = (Entity)trans.GetObject(thisOid, OpenMode.ForRead);
if (blk.GetType().ToString() == "Autodesk.AutoCAD.DatabaseServices.BlockReference")
{
BlockReference thisBlockRef = (BlockReference)trans.GetObject(thisOid, OpenMode.ForRead);
if(string.Compare(thisBlockRef.Name, blockReferenceName, true) == 0)
{
returnOIDs.Add(thisOid);
}
}
}
return returnOIDs;
}
}
}
页:
1
[2]