TheSwamp
Code Red => .NET => Topic started by: jlatimer11 on March 21, 2013, 02:05:59 PM
-
I'm having an issue that I can't seem to figure out.
Before a form loads I take objects on layers and convert them to polylines. After user input on a form I loop through each layer and offset the polylines.
The issue I'm having is that occasionally some objects are not offset. There is no conditional statements, it's literally select polylines and offset. The number of objects in the selection set is less than the number of items on the layer.
So I'm wondering: Is there a specific instance where objects are committed to the database? Or, is there a way to force the database to update?
-
I'm having an issue that I can't seem to figure out.
Before a form loads I take objects on layers and convert them to polylines. After user input on a form I loop through each layer and offset the polylines.
The issue I'm having is that occasionally some objects are not offset. There is no conditional statements, it's literally select polylines and offset. The number of objects in the selection set is less than the number of items on the layer.
So I'm wondering: Is there a specific instance where objects are committed to the database? Or, is there a way to force the database to update?
You haven't shown any code, and it's difficult to assume what your code does and/or how it does what it does.
The answer to the very general question you're asking, depends on too many variables that aren't known without seeing or knowing something about the code and what it does, so there's no simple answer to it.
-
I'm having an issue that I can't seem to figure out.
Before a form loads I take objects on layers and convert them to polylines. After user input on a form I loop through each layer and offset the polylines.
The issue I'm having is that occasionally some objects are not offset. There is no conditional statements, it's literally select polylines and offset. The number of objects in the selection set is less than the number of items on the layer.
So I'm wondering: Is there a specific instance where objects are committed to the database? Or, is there a way to force the database to update?
You haven't shown any code, and it's difficult to assume what your code does and/or how it does what it does.
The answer to the very general question you're asking, depends on too many variables that aren't known without seeing or knowing something about the code and what it does, so there's no simple answer to it.
I didn't post the code because there was a ton of it, but since it is needed I'll post it.
Pre-Form Load:
<CommandMethod("bsr")> _
Public Sub bsr()
Dim myDB As DatabaseServices.Database
Dim myDWG As ApplicationServices.Document
Dim myEd As EditorInput.Editor
Dim myTransMan As DatabaseServices.TransactionManager
Dim myTrans As DatabaseServices.Transaction
Dim bsrlay As New ArrayList
Dim myBTR As BlockTableRecord
Dim myBT As BlockTable
myDWG = ApplicationServices.Application.DocumentManager.MdiActiveDocument
myDB = myDWG.Database
myEd = myDWG.Editor
myTransMan = myDB.TransactionManager
myTrans = myTransMan.StartTransaction
Using acLckDoc As DocumentLock = myDWG.LockDocument()
myBT = myDWG.Database.BlockTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
myBTR = myBT(Autodesk.AutoCAD.DatabaseServices.BlockTableRecord.ModelSpace).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
makePalletPline(myDWG, myDB, myTrans, myBTR, False)
End Using
myTrans.Commit()
myTrans.Dispose()
Dim form1 As New bs_recesses
form1.Show()
End Sub
Public Sub makePalletPline(ByVal mydwg As Document, ByVal mydb As Database, ByVal mytrans As Transaction, ByVal myBTR As BlockTableRecord)
Dim pb As ArrayList = getBoundsByLayer(mydwg, mydb, "00-PLATE")
Dim minpt As Point3d = New Point3d(pb(0) - 0.01, pb(1) - 0.01, 0)
Dim maxpt As Point3d = New Point3d(pb(2) + 0.01, pb(3) + 0.01, 0)
Dim dlays As ArrayList = getLayersByBounds(mydwg, mydb, minpt, maxpt)
For Each lyr As String In dlays
Dim objidcoll As ObjectIdCollection = makePlinebyLayer(lyr, mydwg, myBTR)
Next
End Sub
Public Function makePlinebyLayer(ByVal layername As String, ByVal myDWG As Document, ByVal myBTR As BlockTableRecord)
Dim PSG As PolylineSegmentCollection = New PolylineSegmentCollection
Dim ents As New ArrayList
Dim segCol As PolylineSegmentCollection = New PolylineSegmentCollection
Dim segments As DBObjectCollection = New DBObjectCollection
Dim mySS As Autodesk.AutoCAD.EditorInput.SelectionSet = Nothing
Dim myPSR As PromptSelectionResult = Nothing
Dim myTV(0) As DatabaseServices.TypedValue
myTV(0) = New DatabaseServices.TypedValue(DatabaseServices.DxfCode.LayerName, layername)
Dim myFilter As New EditorInput.SelectionFilter(myTV)
Dim myObjIds As DatabaseServices.ObjectIdCollection = Nothing
Dim entinfo As New ArrayList
Dim myEnt As DatabaseServices.Entity
Dim retVal As ObjectIdCollection = New ObjectIdCollection
Using myTrans As Transaction = myDWG.Database.TransactionManager.StartTransaction()
myPSR = myDWG.Editor.SelectAll(myFilter)
If Not IsNothing(myPSR.Value) Then
mySS = myPSR.Value
myObjIds = New DatabaseServices.ObjectIdCollection(mySS.GetObjectIds)
For Each myObjId In myObjIds
myEnt = myObjId.GetObject(DatabaseServices.OpenMode.ForWrite)
segments.Add(myEnt)
Next
End If
'Borrowed from TheSwamp.org
Dim i As Integer = 0
Do While (i < segments.Count)
Dim obj As DBObject = segments(i)
Select Case (obj.GetType.Name)
Case "Line"
Dim line As Line = CType(obj, Line)
pt = line.StartPoint
Dim ls As LineSegment2d = New LineSegment2d(New Point2d(pt.X, pt.Y), New Point2d(line.EndPoint.X, line.EndPoint.Y))
segCol.Add(New PolylineSegment(ls))
Case "Arc"
Dim arc As Arc = CType(obj, Arc)
pt = arc.StartPoint
Dim midPT As Point3d = arc.GetPointAtParameter(((arc.EndParam + arc.StartParam) / 2))
Dim ca As CircularArc2d = New CircularArc2d(New Point2d(pt.X, pt.Y), New Point2d(midPT.X, midPT.Y), _
New Point2d(arc.EndPoint.X, arc.EndPoint.Y))
segCol.Add(New PolylineSegment(ca))
Case "Circle"
Dim c As Circle = CType(obj, Circle)
pt = c.Center
segCol.AddRange(New PolylineSegmentCollection(c))
Case "Ellipse"
Dim el As Ellipse = CType(obj, Ellipse)
pt = el.Center
segCol.AddRange(New PolylineSegmentCollection(el))
Case "Spline"
End Select
obj.Dispose()
i = (i + 1)
Loop
For Each psc As PolylineSegmentCollection In segCol.Join
Dim pl As Polyline = psc.ToPolyline
pl.Layer = layername
retVal.Add(myBTR.AppendEntity(pl))
myTrans.AddNewlyCreatedDBObject(pl, True)
Next
myTrans.Commit()
End Using
Return retVal
End Function
After User Data Input on Form:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal ea As System.EventArgs) Handles Button2.Click
Dim minfloor As Decimal = CDec(TextBox6.Text)
Dim myDB As DatabaseServices.Database
Dim myDWG As Autodesk.AutoCAD.ApplicationServices.Document
Dim myEd As EditorInput.Editor
Dim myTransMan As DatabaseServices.TransactionManager
Dim myTrans As DatabaseServices.Transaction
Dim bsrlay As New ArrayList
Dim myBTR As BlockTableRecord
Dim myBT As BlockTable
myDWG = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
myDB = myDWG.Database
myEd = myDWG.Editor
myTransMan = myDB.TransactionManager
myTrans = myTransMan.StartTransaction
Using acLckDoc As DocumentLock = myDWG.LockDocument()
myBT = myDWG.Database.BlockTableId.GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
myBTR = myBT(Autodesk.AutoCAD.DatabaseServices.BlockTableRecord.ModelSpace).GetObject(Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite)
Dim xmin As Point3d = New Point3d(-10,-10,0)
Dim xmax As Point3d = New Point3d(10,10,0)
Dim newlayname As String = "OFFSET"
For Each play As String In Listbox2.Items
Dim xi As ArrayList = selitemXing(play, myTrans, myTransMan, myDB, myEd, myDWG, xmin, xmax) 'WHERE THE PROBLEM HAPPENS. RETURNS A NUMBER LESS THAN THE NUMBER OF OBJECTS
For Each e As Entity In xi
If TypeOf e Is Polyline Then
Dim dbobj As ObjectIdCollection = Tools.Offset(e.ObjectId, (-.010))
ElseIf TypeOf e Is Circle Then
Dim mycirc As Circle = e
Dim mycirc2 As Circle = Nothing
mycirc2 = e.Clone
mycirc2.SetDatabaseDefaults()
mycirc2.Layer = newlayname
mycirc2.Diameter = mycirc.Diameter + (.020)
myBTR.AppendEntity(mycirc2)
myTrans.AddNewlyCreatedDBObject(mycirc2, True)
End If
Next
xi.Clear()
End If
Next
Next
myTrans.Commit()
myTrans.Dispose()
End Sub
Public Function selitemXing(ByVal layername As String, ByVal mytrans As DatabaseServices.Transaction, _
ByVal mytransman As DatabaseServices.TransactionManager, _
ByVal myDB As DatabaseServices.Database, ByVal myED As EditorInput.Editor, _
ByVal myDWG As ApplicationServices.Document, ByVal startpoint As Point3d, ByVal endpoint As Point3d) As ArrayList
Dim myTV(0) As DatabaseServices.TypedValue
myTV(0) = New DatabaseServices.TypedValue(DatabaseServices.DxfCode.LayerName, layername)
Dim myFilter As New EditorInput.SelectionFilter(myTV)
Dim myPSR As EditorInput.PromptSelectionResult
Dim mySS As EditorInput.SelectionSet
Dim myObjIds As DatabaseServices.ObjectIdCollection = Nothing
Dim entinfo As New ArrayList
Dim myEnt As DatabaseServices.Entity
myPSR = myED.SelectCrossingWindow(startpoint, endpoint, myFilter)
Dim i As Integer = 0
If Not IsNothing(myPSR.Value) Then
mySS = myPSR.Value
myObjIds = New DatabaseServices.ObjectIdCollection(mySS.GetObjectIds)
For Each myObjId In myObjIds
myEnt = myObjId.GetObject(DatabaseServices.OpenMode.ForRead)
entinfo.Add(myEnt)
i = i + 1
Next
End If
Return entinfo
End Function
-
You might want to think about refactor that a bit, but looking quickly I saw where you said selitemXing was returning a number less than the total number and probably has to do with SelectCrossingWindow.
Are all entities visible on screen?
Might want to take a different approach.