TheSwamp
Code Red => VB(A) => Topic started by: Tuoni on November 06, 2006, 06:08:26 AM
-
I have stumbled upon a large problem in a script I am currently writing.
The routine basically checks for overlapping layers - it does this by copying a reference polygon to a region and doing a series of subtractions to work out how much (if any) of the polygon overlaps another one.
The script works perfectly if the reference polygon is contained completely within another (if it is smaller), or if the reference polygon overlaps the other. HOWEVER, if the polygons have vertices which touch more than once (eg they are the same shape, or share a common series of vertices) then when I run the getboundingbox command, the arrays minExt and maxExt both return 0,0,0.
Is this a limitation with the getboundingbox command, and does anybody have any ideas on how to fix this problem?
-Tuoni
-
A little code snippet would go a long way here....
-
entry.GetBoundingBox minExt, maxExt
startPtD(0) = minExt(0) + 1: startPtD(1) = maxExt(1): startPtD(2) = 0#
endPtD(0) = minExt(0) + 1: endPtD(1) = minExt(1): endPtD(2) = 0#
startPt = startPtD: endPt = endPtD
Set lineObj = ThisDrawing.ModelSpace.AddLine(startPt, endPt)
intPointsNew = entry.IntersectWith(lineObj, acExtendNone)
startPtD(0) = intPointsNew(0) - 10: startPtD(1) = intPointsNew(1): startPtD(2) = intPointsNew(2)
endPtD(0) = intPointsNew(3) - 10: endPtD(1) = intPointsNew(4): endPtD(2) = intPointsNew(5):
There isn't really anything else I can post - when the two LwPolyLines which I want to compare are nested, this code works perfectly - ie getboundingbox returns a value. When one has more than one vertex which touches the outside polyline, getboundingbox returns minExt 0,0,0 and maxExt 0,0,0.
All variables are declared, and correctly declared and I just can't understand why when the lines touch the getboundingbox command returns values of 0 in both the arrays - ie it is *populating* the array, just with incorrect data :/
-
Mayby an example from some code I wrote can help you in finding your problem...
sorry I've commented it in my native language.
And looking at the code I seem to remember I had to use variant due to a Quirck in the Acad VBA model involving Getboundingbox
Function LimitsSelSet(Selset As AcadSelectionSet) As Variant
Dim Ent As AcadEntity
Dim LL As Variant
Dim UR As Variant
Dim Limits(0 To 1, 0 To 2) As Double
Limits(0, 0) = -0.0000000000001
For Each Ent In Selset
If Left$(Ent.ObjectName, 7) <> "AcDbDim" And Ent.ObjectName <> "AcDbAttributeDefinition" _
And Ent.ObjectName <> "AcDBText" Then 'negeer dimensies attributen en texten
Ent.GetBoundingBox LL, UR
If Limits(0, 0) = -0.0000000000001 Then 'init upperleft, lowerright
Limits(0, 0) = LL(0): Limits(0, 1) = LL(1): Limits(0, 2) = LL(2)
Limits(1, 0) = UR(0): Limits(1, 1) = UR(1): Limits(1, 2) = UR(2)
Else 'get boundingbox selectionset
If Limits(0, 0) > LL(0) Then Limits(0, 0) = LL(0)
If Limits(0, 1) > LL(1) Then Limits(0, 1) = LL(1)
If Limits(0, 2) > LL(2) Then Limits(0, 2) = LL(2)
If Limits(1, 0) < UR(0) Then Limits(1, 0) = UR(0)
If Limits(1, 1) < UR(1) Then Limits(1, 1) = UR(1)
If Limits(1, 2) < UR(2) Then Limits(1, 2) = UR(2)
End If
End If
Next Ent
LimitsSelSet = Limits
End Function
Good Luck.
-
Thanks for the swift reply, however the code hasn't helped at all :( - there will still be the problem of GetBoundingBox returning 0,0,0 in the two arrays :(
I'm at a complete loss - the code is correct otherwise the event wouldn't work on the rest of the polylines on the drawing - i have tried (stupid as it sounds) different layers, drawings, shapes etc ad nausem but it seems that if more than one vertex in a shape touches another object then the getBoundingBox command fails to return the correct values - see the attached screenies if you need clarification of what I mean
-
So... what are those correct declarations in your code....
Acad does have a lot of quircks, which means you shouldn't allways write decent code because it won't work.
edit: tested it and I didn't have a problem....
Code:
Sub test()
Dim LineObj As AcadLine
Dim Entry As AcadEntity
Dim minExt As Variant
Dim maxExt As Variant
Dim StartPtd(0 To 2) As Double
Dim EndPtD(0 To 2) As Double
Dim UserPoint(0 To 2) As Double
Dim ReturnObj As AcadObject
Dim intPointsNew As Variant
ThisDrawing.Utility.GetEntity ReturnObj, UserPoint, "Select an object"
If TypeOf ReturnObj Is AcadEntity Then
Set Entry = ReturnObj
Entry.GetBoundingBox minExt, maxExt
StartPtd(0) = minExt(0) + 1
StartPtd(1) = maxExt(1)
StartPtd(2) = 0#
EndPtD(0) = minExt(0) + 1
EndPtD(1) = minExt(1)
EndPtD(2) = 0#
Set LineObj = ThisDrawing.ModelSpace.AddLine(StartPtd, EndPtD)
intPointsNew = Entry.IntersectWith(LineObj, acExtendNone)
If UBound(intPointsNew) > 5 Then
StartPtd(0) = intPointsNew(0) - 10
StartPtd(1) = intPointsNew(1)
StartPtd(2) = intPointsNew(2)
EndPtD(0) = intPointsNew(3) - 10
EndPtD(1) = intPointsNew(4)
EndPtD(2) = intPointsNew(5)
End If
End If
End Sub
-
Acad does have a lot of quircks, which means you shouldn't allways write decent code because it won't work.
Yeah, I learnt this early on... I come from a more "pure" programming background (as in... writing fully independent executables) rather than scripting through object libraries and the like - something I have only been doing in the past 2 years or so, and with AutoCAD about 3/4 months.
Dim lineObj As AcadLine
Dim startPt As Variant
Dim endPt As Variant
Dim startPtD(2) As Double
Dim endPtD(2) As Double
Dim minExt As Variant
Dim maxExt As Variant
Dim intPointsNew As Variant
The messing with loading startPtD (the array of doubles) then loading the values from there into startPt (Variant array) is due to the fact that when you want to check for interceptions against an arc (or anything containing an arc) it has to be a variant array containing data in the "Variant/Doubles" type - exactly one of the quirks you mentioned.
-
doing a series of subtractions
the problem is probably happening here. If you subtract 2 identical objects you have nothing left to get the boundingbox of
-
As nice a solution as that would seem, the object is having nothing subtracted from it (and if you think about it, I'd get a different error - it would fail because "entry" would no longer exist)
-
The point here is that you haven't shown enough code. We can only guess.The fact that a poly shares some points with another poly doesnt change the outcome of Getboundingbox, it only looks at the entity you give it, as far as I can tell.
-
There is no other code I can show you, it is all unrelated to this function. I would have thought this to be the case, too, but like I say it works until you touch another line with more than one vertex. I feed it with entry (which is a region) and if entry touches a polyline more than once then it returns values of 0,0,0. There is no other code I can show you.
-
Dnereb: I have only just seen your edit. Thanks, I tested it and I also don't have a problem with it - although I fail to see why that code works and mine doen't :/
-
look closely at the way I abuse the variant type and convert it into double arrays
the double declaration
Dim Somepoint(0 to 2) as Double
is somehow diffrent to acad as
Dim Somepoint(3) as double
BTW I program in VB and Vb.net as well nowadays....