|
发表于 2013-9-3 10:20:56
|
显示全部楼层
嘿n.yuan,谢谢回复!
这就是我这样做的方式(代码方面):
步骤1)插入我的动态块:
- ...
- ' assure the desired doorsketchBlock is present in the blocktable
- acadBlockId = Acad.searchOrImportBlock(Acad.SketchblocksFileName, blockName)
- ' insert the block in modelspace
- acadblockref = Acad.InsertBlock(blockName, insPnt, 1, 1, 1, _acParentBlockref.Rotation)
- 'Set Dynamic properties
- AttVals.Clear()
- AttVals.Add("Lookup|" & dimNuttigeBreedte & " x " & dimPaneelBreedte)
- AttVals.Add("Paneeldikte|" & _acParentBlockref.ScaleFactors.Y)
- AttVals.Add("Draairichting|" & conDraairichting)
- Acad.set_DynamicBlockProperties(acadblockref, AttVals)
- 'Set Attributes
- AttVals.Clear()
- AttVals.Add("InventTransId|" & genInventTransId)
- AttVals.Add("DIM|" & dimNuttigeBreedte & "|" & dimPaneelBreedte & "|" & dimNuttigeHoogte & "|" & _acParentBlockref.ScaleFactors.Z & "|" & doorPanelConn)
- AttVals.Add("ONDERBOUW|" & IIf(conVerzonkenOpstelling, _
- Acad.get_AttValByIdx(_acParentBlockref, 3) & "|" & conVerzonkenOpstelling, _
- Acad.get_AttValByIdx(_acParentBlockref, 3)))
- Acad.set_BlockAttributes(acadblockref, AttVals)
- ...
4种方法在上面的代码中发挥作用:
Acad.searchOrImportBlock(检查当前绘图中是否已经存在所需的块可块,如果没有,它将从“主绘图”中获取它)
Acad.InsertBlock(知道所需的块存在于当前绘图的可块中,它会将其插入模型空间并返回一个BlockResources对象)
Acad.set_DynamicBlockProperties(用于设置给定BlockResources的动态属性)
Acad.set_BlockAttributes(用于设置属性值给定的Block引用)
Acad.searchOrImportBlock
- Shared Function searchOrImportBlock(_sourceFileName As String, _blockName As String) As ObjectId
- ' Get the current document and database
- Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
- Dim acCurDb As Database = acDoc.Database
- ' Lock the document
- Using acLckDoc As DocumentLock = acDoc.LockDocument()
- ' Start a transaction in the database
- Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
- ' Get the Block table for the current database
- Dim acBlockTbl As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
- ' If found in local BlockTableRecord
- If acBlockTbl.Has(_blockName) Then
- Return acBlockTbl(_blockName)
- End If
- End Using ' Dispose of the transaction
- End Using ' Unlock the document
- ' If not found in local BlockTableRecord then Import from _sourceFileName
- Return importBlockFromSourceFile(_sourceFileName, _blockName)
- End Function
- Shared Function importBlockFromSourceFile(_sourceFileName As String, _blockName As String) As ObjectId
- Dim sourceDb As New Database(False, True)
- Dim acObjIdColl As ObjectIdCollection = New ObjectIdCollection()
- ' Read the DWG into a side database
- sourceDb.ReadDwgFile(_sourceFileName, System.IO.FileShare.Read, True, "")
- Using acTrans As Transaction = sourceDb.TransactionManager.StartTransaction()
- ' Open the block table
- Dim bt As BlockTable = DirectCast(acTrans.GetObject(sourceDb.BlockTableId, OpenMode.ForRead, False), BlockTable)
- If bt.Has(_blockName) Then
- acObjIdColl.Add(bt(_blockName))
- 'SendCommandMessage(vbCrLf & "Imported block: '" & _blockName & "' from '" & _sourceFileName & "'" & vbCrLf)
- End If
- '' Check each block in the block table
- 'For Each btrId As ObjectId In bt
- ' Dim btr As BlockTableRecord = DirectCast(acTrans.GetObject(btrId, OpenMode.ForRead, False), BlockTableRecord)
- ' If btr.Name = _blockName Then
- ' acObjIdColl.Add(btr.ObjectId)
- ' SendCommandMessage(vbCrLf & "Importing block: " & btr.Name)
- ' End If
- ' btr.Dispose()
- 'Next
- End Using
- Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
- Dim acCurDb As Database = acDoc.Database
- ' Lock the document
- Using acLckDoc As DocumentLock = acDoc.LockDocument()
- ' Start a transaction in the database
- Using acTrans = acDoc.TransactionManager.StartTransaction()
- ' Open the Block table for read
- Dim acBlkTblNewDoc As BlockTable
- acBlkTblNewDoc = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
- ' Open the Block table record Model space for read
- Dim acBlkTblRecNewDoc As BlockTableRecord
- acBlkTblRecNewDoc = acTrans.GetObject(acBlkTblNewDoc(BlockTableRecord.ModelSpace), OpenMode.ForRead)
- ' Clone the objects to the new database
- Dim acIdMap As IdMapping = New IdMapping()
- acCurDb.WblockCloneObjects(acObjIdColl, acBlkTblRecNewDoc.ObjectId, acIdMap, DuplicateRecordCloning.Ignore, False)
- ' Commit the transaction
- acTrans.Commit()
- End Using ' Dispose of the transaction
- End Using ' Unlock the document
- 'Return ObjectId
- Return acObjIdColl(0)
- End Function
Acad.InsertBlock
-
- Shared Function InsertBlock(ByVal _blockName As String, ByVal insPt As Point3d, ByVal xBlkScale As Double, _
- ByVal yBlkScale As Double, ByVal zBlkScale As Double, ByVal ang As Double) As BlockReference
- ' Get the current document and database
- Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
- Dim acCurDb As Database = acDoc.Database
- ' Lock the document
- Using acLckDoc As DocumentLock = acDoc.LockDocument()
- ' Start a transaction in the database
- Using acTrans = acDoc.TransactionManager.StartTransaction()
- Dim blkTable As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
- If blkTable.Has(_blockName) Then
- Dim blkObjId As ObjectId = blkTable(_blockName)
- Dim blkRef As BlockReference = New BlockReference(insPt, blkObjId)
- blkRef.SetDatabaseDefaults()
- blkRef.ScaleFactors = New Scale3d(xBlkScale, yBlkScale, zBlkScale)
- blkRef.Rotation = ang
- Dim blkTblRec As BlockTableRecord
- ' Assumes the current space was already changed to.
- blkTblRec = acTrans.GetObject(acCurDb.CurrentSpaceId, OpenMode.ForWrite)
- blkTblRec.AppendEntity(blkRef)
- acTrans.AddNewlyCreatedDBObject(blkRef, True)
- ' add the attribute definitions.
- Dim blkTblR As BlockTableRecord = blkObjId.GetObject(OpenMode.ForRead)
- For Each objId As ObjectId In blkTblR
- Dim obj As DBObject = objId.GetObject(OpenMode.ForRead)
- If TypeOf obj Is AttributeDefinition Then
- Dim ad As AttributeDefinition = objId.GetObject(OpenMode.ForRead)
- Dim ar As AttributeReference = New AttributeReference()
- ar.SetAttributeFromBlock(ad, blkRef.BlockTransform)
- ar.Position = ad.Position.TransformBy(blkRef.BlockTransform)
- blkRef.AttributeCollection.AppendAttribute(ar)
- acTrans.AddNewlyCreatedDBObject(ar, True)
- End If
- Next
- ' Commit the transaction
- acTrans.Commit()
- Return blkRef
- End If
- End Using ' Dispose of the transaction
- End Using ' Unlock the document
- End Function
Acad.set_DynamicBlockProperties
- Shared Sub set_DynamicBlockProperties(_blkRef As BlockReference, _attVals As List(Of String))
- ' Get the current document and database, and start a transaction
- Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
- Dim acCurDb As Database = acDoc.Database
- ' Lock the new document
- Using acLckDoc As DocumentLock = acDoc.LockDocument()
- ' Start a transaction in the new database
- Using acTrans = acDoc.TransactionManager.StartTransaction()
- 'Open _blkRef For writing
- _blkRef = DirectCast(acTrans.GetObject(_blkRef.Id, OpenMode.ForWrite), BlockReference)
- For Each dynamicProperty As DynamicBlockReferenceProperty In _blkRef.DynamicBlockReferencePropertyCollection
- Dim recievedValue As String = get_AttVal(dynamicProperty.PropertyName, _attVals)
- If Not String.IsNullOrEmpty(recievedValue) Then
- If is_DynamicValueAllowed(recievedValue, dynamicProperty) Then
- If IsNumeric(recievedValue) Then
- dynamicProperty.Value = CDbl(recievedValue)
- Else
- dynamicProperty.Value = recievedValue
- End If
- Else
- MsgBox("Voor DynamicBlock '" & _blkRef.Name & "'" & _
- " werd voor property '" & dynamicProperty.PropertyName & "'" & _
- " getracht de niet-toegestane waarde '" & recievedValue & "' mee te geven." & _
- vbLf & vbLf & _
- "Gelieve dit te controleren !", vbOKOnly + MsgBoxStyle.Exclamation)
- End If
- End If
- Next
- ' Commit the transaction
- acTrans.Commit()
- End Using ' Dispose of the transaction
- End Using ' Unlock the document
- End Sub
Acad.set_BlockAttributes
-
- Shared Sub set_BlockAttributes(_blkRef As BlockReference, _attVals As List(Of String))
- ' Get the current document and database, and start a transaction
- Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
- Dim acCurDb As Database = acDoc.Database
- ' Lock the new document
- Using acLckDoc As DocumentLock = acDoc.LockDocument()
- ' Start a transaction in the new database
- Using acTrans = acDoc.TransactionManager.StartTransaction()
- Dim attCol As AttributeCollection = _blkRef.AttributeCollection
- For Each attId As ObjectId In attCol
- Dim attRef As AttributeReference = DirectCast(acTrans.GetObject(attId, OpenMode.ForWrite), AttributeReference)
- Dim recievedValue As String = get_AttVal(attRef.Tag, _attVals)
- If Not String.IsNullOrEmpty(recievedValue) Then attRef.TextString = recievedValue
- Next
- ' Commit the transaction
- acTrans.Commit()
- End Using ' Dispose of the transaction
- End Using ' Unlock the document
- End Sub
我不认为上述代码有任何功劳。没有一个是完全编译粘贴的,最近它是完全手工编写的吗?
步骤2)遍历插入的块:
我已经收集了“Sketch”层中的所有Block引用,现在我想评估它们,并根据它们的名称采取行动
-
- 'Perform individual convertion per block in the SketchBlocksCollection, based on it's type (Name)
- For Each acSketchBlockRef As BlockReference In SketchBlocksCollection
- Select Case acSketchBlockRef.Name
- Case "SketchHoekBlock V"
- convert_Corner_vertical(acSketchBlockRef, SketchBlocksCollection)
- Case "SketchVloerBlock"
- Dim MaxUsedFloorPanelLenght = convert_Floor(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, sketchOrigins, MaxUsedLength)
- MaxUsedLength = Math.Max(MaxUsedLength, MaxUsedFloorPanelLenght)
- Case "SketchPlafondBlock"
- Dim MaxUsedCielingPanelLenght = convert_Cieling(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, sketchOrigins, MaxUsedLength)
- MaxUsedLength = Math.Max(MaxUsedLength, MaxUsedCielingPanelLenght)
- Case "SketchPaneelBlock"
- convert_Wall(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, SketchHorizontalCornerBlocksCollection, SketchDeurBlocksCollection)
- [b]Case "SketchDraaiDeurBlock", "SketchDraaiDeurDubbelBlock", "SketchSchuifDeurBlock"[/b]
- convert_Door(acSketchBlockRef) 'code never reached
- Case "SketchVBNBlock"
- convert_VBN(acSketchBlockRef, SketchConversionSettings, sketchOrigins)
- Case Else
- End Select
- Next acSketchBlockRef
这里出错了:
Case"SketchDraaiDeurBlock
因此acSketchBlockRef.Name计算结果为(例如)"*U24",而不是"SketchDraaiDeurBlock"。
我尝试了这个:
- For Each acSketchBlockRef As BlockReference In SketchBlocksCollection
- Select Case[b] EffectiveName(acSketchBlockRef)[/b]
- Case "SketchHoekBlock V"
- convert_Corner_vertical(acSketchBlockRef, SketchBlocksCollection)
- Case "SketchVloerBlock"
- Dim MaxUsedFloorPanelLenght = convert_Floor(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, sketchOrigins, MaxUsedLength)
- MaxUsedLength = Math.Max(MaxUsedLength, MaxUsedFloorPanelLenght)
- Case "SketchPlafondBlock"
- Dim MaxUsedCielingPanelLenght = convert_Cieling(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, sketchOrigins, MaxUsedLength)
- MaxUsedLength = Math.Max(MaxUsedLength, MaxUsedCielingPanelLenght)
- Case "SketchPaneelBlock"
- convert_Wall(acSketchBlockRef, SketchBlocksCollection, SketchConversionSettings, SketchHorizontalCornerBlocksCollection, SketchDeurBlocksCollection)
- Case "SketchDraaiDeurBlock", "SketchDraaiDeurDubbelBlock", "SketchSchuifDeurBlock"
- convert_Door(acSketchBlockRef)
- Case "SketchVBNBlock"
- convert_VBN(acSketchBlockRef, SketchConversionSettings, sketchOrigins)
- Case Else
- convert_Door(acSketchBlockRef)
- End Select
- Next acSketchBlockRef
使用方法'有效名称'being:
- Public Shared Function EffectiveName(ByVal blkref As BlockReference) As String
- If blkref.IsDynamicBlock Then
- Return DirectCast(blkref.DynamicBlockTableRecord.GetObject(OpenMode.ForRead), BlockTableRecord).Name
- Else
- Return blkref.Name
- End If
- End Function
但是在这里,blkref.IsDynamicBlock总是返回false。
这是一个满嘴的!
有什么想法吗? |
|