willmswamp 发表于 2011-3-8 18:28:33

在中使用剖面。网

对于所有人来说,
我一直在玩.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 *****

bikelink 发表于 2011-3-13 15:09:32

为了获得一个部分,您可以使用“部分”对象。 有了这个,您可以处理更多的固体。
有些像这样
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);
                            }

willmswamp 发表于 2011-3-15 15:40:11

亲爱的bikelink,
我很抱歉,但是,从您的代码示例中,我看不出您对partule对象的实现解决了我的问题(或者与我在代码中所做的不同)。 也许你给我的代码示例是不完整的。 也许你可以解释更多。
我的代码适用于关闭背景几何图形时多个实体的 2d 部分。 它不做的是隐藏在打开背景几何图形时应隐藏在其他实体后面的线条(并且隐藏线可见性设置为 false)。 这就是我想要实现的目标。
谢谢,

zero.half 发表于 2019-11-27 08:59:43

您好,
很抱歉挖出了那个老话题,但这个问题似乎仍未解决<有人找到解决办法了吗?将不胜感激。
页: [1]
查看完整版本: 在中使用剖面。网