在中使用剖面。网
对于所有人来说,我一直在玩.NET中的切片功能,但遇到了一个障碍。
在 AutoCAD 中手动工作时,可以创建剖面(SECTIONPLANE 命令),然后通过在剖面平面上单击鼠标右键,可以创建由剖面平面切割的实体的 2D 剖面。 在设置中,您可以打开背景几何图形并关闭隐藏线,这将创建一个2D部分,该部分显示背景几何图形,但隐藏隐藏在其他实体后面的线。
.NET API 提供对这些相同功能的访问。 但是,我无法实现上述目的。看起来 GenerateSectionGeometry 方法似乎只能应用于一个实体,一次一个。因此,当此方法将背景几何图形的可见性设置为 true 并将隐藏线的可见性设置为 false 时使用,它确实隐藏了实体背面的线条,但实体上应隐藏在另一个实体后面的线条仍然可见。 期望的行为是这些隐藏在实体后面的线不应该是可见的。 此功能是否可以使用 .NET API 实现? 希望如此。
我在下面附上了我的源代码。 如果您看到我做错了什么,请告诉我。
Imports System
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
Namespace Autodesk.AutoCAD.SectionTest
Public Class SOMRClass
_
Public Sub SectionTest()
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acDocEd As Editor = acDoc.Editor
'set up prompt selection options
Dim acPromptSelOpt As PromptSelectionOptions = New PromptSelectionOptions()
acPromptSelOpt.MessageForAdding = vbLf & "Select entities to section: "
acPromptSelOpt.MessageForRemoval = vbLf & "Select entities to remove from selection set: "
acPromptSelOpt.RejectObjectsFromNonCurrentSpace = True
'create a typed value array to define the filter criteria, filter for 3dSolids and BlockReferences
Dim acTypValAr(2) As TypedValue
acTypValAr.SetValue(New TypedValue(DxfCode.Operator, ""), 2)
'assign filter criteria to a selectionfilter object
Dim acSelFtr As SelectionFilter = New SelectionFilter(acTypValAr)
'ask the user to select an entity to section
Dim acSSPrompt As PromptSelectionResult = acDoc.Editor.GetSelection(acPromptSelOpt, acSelFtr)
If acSSPrompt.Status = PromptStatus.OK Then
'save selection set to acSS
Dim acSSet As SelectionSet = acSSPrompt.Value
'ask the user to select points to be used to define the section plane
Dim acPtsColl As Point3dCollection = New Point3dCollection()
Dim acPtPrompt As PromptPointResult = acDocEd.GetPoint(vbLf & "Pick first point for section: ")
If acPtPrompt.Status = PromptStatus.OK Then
acPtsColl.Add(acPtPrompt.Value)
Dim acPromptPtOpt As PromptPointOptions = New PromptPointOptions(vbLf & "Pick end point for section: ")
acPromptPtOpt.BasePoint = acPtPrompt.Value
acPromptPtOpt.UseBasePoint = True
acPtPrompt = acDocEd.GetPoint(acPromptPtOpt)
If acPtPrompt.Status = PromptStatus.OK Then
acPtsColl.Add(acPtPrompt.Value)
Try
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
'now let's create our section object
Dim acSect As Section = New Section(acPtsColl, Vector3d.ZAxis)
acSect.State = SectionState.Plane
acSect.SetHeight(SectionHeight.HeightAboveSectionLine, 3.0)
acSect.SetHeight(SectionHeight.HeightBelowSectionLine, 1.0)
'get modelspace
Dim acBlkTbl As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
Dim acModelSp As BlockTableRecord = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
'the section must be added to the drwing
Dim acSectObjId As ObjectId = acModelSp.AppendEntity(acSect)
acTrans.AddNewlyCreatedDBObject(acSect, True)
'get the section settings for the section object
Dim acSecSettings As SectionSettings = acTrans.GetObject(acSect.Settings, OpenMode.ForWrite)
'set the section type
acSecSettings.CurrentSectionType = SectionType.Section2d
'get the object ID collection of all entities in the selection set
Dim acObjIdCol As ObjectIdCollection = SS2IdCol(acSSet)
'set the source objects
acSecSettings.SetSourceObjects(SectionType.Section2d, acObjIdCol)
'set all visibility settings to false to start with
acSecSettings.SetVisibility(SectionType.Section2d, SectionGeometry.BackgroundGeometry, False)
acSecSettings.SetVisibility(SectionType.Section2d, SectionGeometry.CurveTangencyLines, False)
acSecSettings.SetVisibility(SectionType.Section2d, SectionGeometry.ForegroundGeometry, False)
acSecSettings.SetVisibility(SectionType.Section2d, SectionGeometry.IntersectionFill, False)
acSecSettings.SetHiddenLine(SectionType.Section2d, SectionGeometry.BackgroundGeometry, False)
acSecSettings.SetHiddenLine(SectionType.Section2d, SectionGeometry.ForegroundGeometry, False)
acSecSettings.SetHatchVisibility(SectionType.Section2d, SectionGeometry.IntersectionFill, False)
'prompt user to select options for the visibility section settings
Dim pKeyOpts As PromptKeywordOptions = New PromptKeywordOptions("")
pKeyOpts.Message = vbLf & "Show background: "
pKeyOpts.Keywords.Add("Yes")
pKeyOpts.Keywords.Add("No")
pKeyOpts.AllowNone = False
Dim pKeyRes As PromptResult = acDocEd.GetKeywords(pKeyOpts)
If pKeyRes.Status = PromptStatus.OK Then
If pKeyRes.StringResult = "Yes" Then
'turn on visibility of background geometry
acSecSettings.SetVisibility(SectionType.Section2d, SectionGeometry.BackgroundGeometry, True)
'The user chose to show background, therefore ask the user whether they want to show hidden lines
Dim pKeyOpts2 As PromptKeywordOptions = New PromptKeywordOptions("")
pKeyOpts2.Message = vbLf & "Show hidden lines: "
pKeyOpts2.Keywords.Add("Yes")
pKeyOpts2.Keywords.Add("No")
pKeyOpts2.AllowNone = False
Dim pKeyRes2 As PromptResult = acDocEd.GetKeywords(pKeyOpts2)
If pKeyRes2.Status = PromptStatus.OK Then
If pKeyRes2.StringResult = "Yes" Then
'the user chose to show hidden lines
acSecSettings.SetHiddenLine(SectionType.Section2d, SectionGeometry.BackgroundGeometry, True)
End If
End If
End If
End If
'set generation options
acSecSettings.SetGenerationOptions(SectionType.Section2d, SectionGeneration.SourceSelectedObjects Or SectionGeneration.DestinationNewBlock)
'create a block that will store our generated section drawing
Dim sectblock As BlockTableRecord = New BlockTableRecord()
'set the name of the block to the next available block name in the form "2D_Section_###"
sectblock.Name = GetNextBlkName(acBlkTbl)
'upgrade the blocktable to allow changes
acBlkTbl.UpgradeOpen()
'add the new block to the block table
Dim sectBlockId As ObjectId = acBlkTbl.Add(sectblock)
acTrans.AddNewlyCreatedDBObject(sectblock, True)
For Each acObjId As ObjectId In acObjIdCol
Try
'get the entity, exception occurs heer
Dim acEnt As Entity = acTrans.GetObject(acObjId, OpenMode.ForRead)
'generate the section geometry
Dim flEnts As Array
Dim bgEnts As Array
Dim fgEnts As Array
Dim ftEnts As Array
Dim ctEnts As Array
acSect.GenerateSectionGeometry(acEnt, flEnts, bgEnts, fgEnts, ftEnts, ctEnts)
'add the geometry to the block
For Each flEnt As Entity In flEnts
sectblock.AppendEntity(flEnt)
acTrans.AddNewlyCreatedDBObject(flEnt, True)
Next
For Each bgEnt As Entity In bgEnts
sectblock.AppendEntity(bgEnt)
acTrans.AddNewlyCreatedDBObject(bgEnt, True)
Next
For Each fgEnt As Entity In fgEnts
sectblock.AppendEntity(fgEnt)
acTrans.AddNewlyCreatedDBObject(fgEnt, True)
Next
For Each ftEnt As Entity In ftEnts
sectblock.AppendEntity(ftEnt)
acTrans.AddNewlyCreatedDBObject(ftEnt, True)
Next
For Each ctEnt As Entity In ctEnts
sectblock.AppendEntity(ctEnt)
acTrans.AddNewlyCreatedDBObject(ctEnt, True)
Next
Catch ex As System.Exception
acDocEd.WriteMessage(vbLf & "Error: " & ex.Message)
End Try
Next
'insert the block into model space
Dim insertSuccess As Boolean = InsertSection(sectBlockId)
'commit the transaction
acTrans.Commit()
End Using
Catch ex As System.Exception
acDocEd.WriteMessage(vbLf & "Error: " & ex.Message)
End Try
End If
End If
End If
End Sub
'function to insert the created block into modelspace
Public Function InsertSection(ByVal acBlkTabRecId As ObjectId) As Boolean
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acEd As Editor = acDoc.Editor
Dim success As Boolean = True
Try
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
Dim pPtRes As PromptPointResult
Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")
'prompt for the insertion point of the section block
pPtOpts.Message = vbLf & "Pick the insertion point for the section block: "
pPtRes = acEd.GetPoint(pPtOpts)
If pPtRes.Status = PromptStatus.OK Then
'extract the point
Dim BlkInsertPt As Point3d = pPtRes.Value
'create the block reference
Dim acNewBlkRef As BlockReference = New BlockReference(BlkInsertPt, acBlkTabRecId)
'prompt user for the scale factor
Dim pDblRes As PromptDoubleResult
Dim pDblOpts As PromptDoubleOptions = New PromptDoubleOptions("")
pDblOpts.Message = vbLf & "Enter the scale factor: "
pDblOpts.AllowNegative = False
pDblOpts.AllowZero = False
pDblOpts.DefaultValue = 1
pDblRes = acEd.GetDouble(pDblOpts)
If pDblRes.Status = PromptStatus.OK Then
'calculate the scale factor
Dim ScaleFact As Double = pDblRes.Value
'create the transformation matrix
Dim matTransform As Matrix3d = Matrix3d.Scaling(ScaleFact, BlkInsertPt)
'scale the block
acNewBlkRef.TransformBy(matTransform)
'get modelspace
Dim acBlkTbl As BlockTable = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
Dim acModelSp As BlockTableRecord = acTrans.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
'add teh block reference to the layout block table record
acModelSp.AppendEntity(acNewBlkRef)
'add the block reference to the transaction
acTrans.AddNewlyCreatedDBObject(acNewBlkRef, True)
End If
End If
'commit the transaction
acTrans.Commit()
End Using
Catch ex As System.Exception
acEd.WriteMessage(vbLf & "Error:" & ex.Message)
success = False
End Try
Return success
End Function
'function to take a selectionset and return an object id collection
Private Function SS2IdCol(ByVal acSSet As SelectionSet) As ObjectIdCollection
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
Dim acDocEd As Editor = acDoc.Editor
Dim acOBjIdColl As ObjectIdCollection = New ObjectIdCollection()
Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
For Each acSSObj As SelectedObject In acSSet
acOBjIdColl.Add(acSSObj.ObjectId)
Next
End Using
Return acOBjIdColl
End Function
'function to get the next available block name in the form "2D_Section_###"
Private Function GetNextBlkName(ByVal acBlkTable As BlockTable) As String
Dim startString As String = "001"
Do While acBlkTable.Has("2D_Section_" & startString)
Dim nextInt As Integer = CInt(startString) + 1
startString = nextInt.ToString("000")
Loop
startString = "2D_Section_" & startString
Return startString
End Function
End Class
End Namespace
**** Hidden Message ***** 为了获得一个部分,您可以使用“部分”对象。 有了这个,您可以处理更多的固体。
有些像这样
Autodesk.AutoCAD.DatabaseServices.Section se = new Section(ptsez, asseverticale);
se.TopPlane = limiteSup;
se.BottomPlane = limiteInf;
Array ents;
using (Transaction tr = d.Database.TransactionManager.StartTransaction())
{
// creazione linea sezione
BlockTable bt = (BlockTable)tr.GetObject(d.Database.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt, OpenMode.ForWrite);
btr.AppendEntity(se);
tr.AddNewlyCreatedDBObject(se, true);
// riapertura oggettoa
se = tr.GetObject(se.ObjectId, OpenMode.ForWrite) as Section;
se.State = SectionState.Plane;
//---------SETTAGGI SEZIONE
SectionSettings ss = (SectionSettings)tr.GetObject(se.Settings, OpenMode.ForWrite);
// Impostazione tipo sezione
ss.CurrentSectionType = st;
// We only set one additional option if "Live"
if (st == SectionType.LiveSection)
se.EnableLiveSection(true);
else
{
Autodesk.AutoCAD.DatabaseServices.Section se = new Section(ptsez, asseverticale);
se.TopPlane = limiteSup;
se.BottomPlane = limiteInf;
Array ents;
using (Transaction tr = d.Database.TransactionManager.StartTransaction())
{
// creazione linea sezione
BlockTable bt = (BlockTable)tr.GetObject(d.Database.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt, OpenMode.ForWrite);
btr.AppendEntity(se);
tr.AddNewlyCreatedDBObject(se, true);
// riapertura oggettoa
se = tr.GetObject(se.ObjectId, OpenMode.ForWrite) as Section;
se.State = SectionState.Plane;
//---------SETTAGGI SEZIONE
SectionSettings ss = (SectionSettings)tr.GetObject(se.Settings, OpenMode.ForWrite);
// Impostazione tipo sezione
ss.CurrentSectionType = st;
// We only set one additional option if "Live"
if (st == SectionType.LiveSection)
se.EnableLiveSection(true);
else
{
// Non-live (i.e. 2D or 3D) settings
ObjectIdCollection oic = new ObjectIdCollection();
idsolido = B2UtilCad.b2Handle.GetHandleAsObjectID(d, hnOggettoDaSezionare);
oic.Add(idsolido);
ss.SetSourceObjects(st, oic);
if (st == SectionType.Section2d)
{
// 2D-specific settings
ss.SetVisibility(st, SectionGeometry.BackgroundGeometry, true);
ss.SetHiddenLine(st, SectionGeometry.BackgroundGeometry, false);
}
else if (st == SectionType.Section3d)
{
// 3D-specific settings
ss.SetVisibility(st, SectionGeometry.ForegroundGeometry, true);
}
// Finish up the common 2D/3D settings
ss.SetGenerationOptions(st, SectionGeneration.SourceSelectedObjects | SectionGeneration.DestinationFile);
}
ObjectIdCollection oic = new ObjectIdCollection();
idsolido = B2UtilCad.b2Handle.GetHandleAsObjectID(d, hnOggettoDaSezionare);
oic.Add(idsolido);
ss.SetSourceObjects(st, oic);
if (st == SectionType.Section2d)
{
ss.SetVisibility(st, SectionGeometry.BackgroundGeometry, true);
ss.SetHiddenLine(st, SectionGeometry.BackgroundGeometry, false);
}
else if (st == SectionType.Section3d)
{
ss.SetVisibility(st, SectionGeometry.ForegroundGeometry, true);
}
ss.SetGenerationOptions(st, SectionGeneration.SourceSelectedObjects | SectionGeneration.DestinationFile);
}
亲爱的bikelink,
我很抱歉,但是,从您的代码示例中,我看不出您对partule对象的实现解决了我的问题(或者与我在代码中所做的不同)。 也许你给我的代码示例是不完整的。 也许你可以解释更多。
我的代码适用于关闭背景几何图形时多个实体的 2d 部分。 它不做的是隐藏在打开背景几何图形时应隐藏在其他实体后面的线条(并且隐藏线可见性设置为 false)。 这就是我想要实现的目标。
谢谢,
会 您好,
很抱歉挖出了那个老话题,但这个问题似乎仍未解决<有人找到解决办法了吗?将不胜感激。
页:
[1]