Include a polyline's width in its bounding box - #1248
Open
redbluevn wants to merge 2 commits into
Open
Conversation
…t coordinates The vertexes of an LWPOLYLINE or a 2D POLYLINE, and the centre of a CIRCLE, are stored in the entity's own object coordinate system. GetBoundingBox returned them unchanged, so for the (0,0,-1) extrusion AutoCAD writes whenever geometry is mirrored the box came back with the sign of X untouched - the entity placed on the opposite side of the drawing from where it belongs. Insert and Arc already go through Matrix4.GetArbitraryAxis for exactly this reason; these three did not. One mirrored polyline is enough to do real damage, because it is usually inside a block: a single one in a block definition of an architectural drawing measured here put its own block's bounding box 8.5 million units wide instead of 208, and with it every one of the 44 references to that block. Polyline3D is left alone - its vertexes are already world coordinates - through a flag on the shared base rather than by relying on its normal staying +Z. LwPolyline's GetBoundingBoxTest was an empty method body; it now covers both the plain and the mirrored case, and CircleTests gained the mirrored case. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A polyline with width covers half of it on each side of the centre line, and
AutoCAD's extents include that. The bounding box measured the centre line alone,
so a drawing whose outermost entity is a wide polyline reported smaller than it
is: on a 17.6 MB client drawing the extents came out exactly 75 units short on
all four sides, the half width of one LWPOLYLINE with ConstantWidth 150.
Each segment is bounded on its own so a taper is only paid for where it occurs.
A straight segment sweeps the strip between its two offset edges, and the offset
goes perpendicular to it - padding in every direction instead would push the box
past the flat end cap, and AutoCAD stops at the cap. A segment with a bulge is
padded by the larger of its two half widths, which contains its sweep. The
widened area is measured in the polyline's own plane and taken to the world
afterwards, so a mirrored polyline still lands on the correct side.
Checked against AutoCAD on drawings it minted itself:
closed square, ConstantWidth 150 AutoCAD (-75,-75)..(1075,1075) exact
open PLINE, width 150 AutoCAD (0,-75)..(1075,1000) exact
open, widths tapering 0-200-400 AutoCAD (0,-108.9)..(1200,1000)
measured (0,-100)..(1200,1000)
The remainder in the third case is the fill AutoCAD adds where two segments
meet, which reaches slightly further than either segment does.
A polyline without any width keeps the centre-line path exactly as before, and
the 3D polyline - whose vertexes carry the fields but no width - is untouched.
On the nineteen client drawings not one extent moves; on the drawing that
prompted this, the extents now match AutoCAD to 3e-06 where they were 75 units
short. Suite 2900/0 with four new cases.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VMhDpZ1rVxTVqbDPqUoYhk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1224. The first commit on this branch belongs to that pull request - a mirrored polyline reporting its bounding box in object coordinates - because this change touches the same two methods and would conflict with it otherwise. Review only the second commit, or take this one after #1224 lands.
The problem
A polyline can carry a width, and it is drawn half on each side of the centre line.
LwPolyline.GetBoundingBoxandPolyline<T>.GetBoundingBoxmeasure the centre line only:So an entity that covers a strip is reported as the line down its middle, and a drawing whose outermost geometry is a wide polyline measures smaller than it is.
How it was found
Asking AutoCAD for the extents of a 17.6 MB client drawing and comparing:
Exactly 75 units short on all four sides — and the entity at the edge is one
LWPOLYLINEwithConstantWidth = 150.The fix
Bound each segment on its own, so a taper is paid for only where it occurs:
Arc.CreateFromBulgerefuses the zero radius), so it contributes the point it sits on, widened.The widened area is measured in the polyline's own plane and taken to the world afterwards, so a mirrored polyline still lands on the correct side.
ConstantWidth(code 43) applies wherever a vertex carries none of its own; for the old-stylePOLYLINEthe polyline's own start and end width (40 and 41) play that role. A 3D polyline carries the fields but no width and is untouched.Measured against AutoCAD, on drawings it minted itself
ConstantWidth150(-75,-75)..(1075,1075)(0,0)..(1000,1000)PLINE, width 150(0,-75)..(1075,1000)(0,0)..(1000,1000)(0,-108.9)..(1200,1000)(0,0)..(1000,1000)(0,-100)..(1200,1000)What is left in the third row is the fill AutoCAD adds where two segments meet, which reaches a little further than either segment does.
On the drawing that prompted this, the extents now match AutoCAD to
3e-06. On nineteen other client drawings not one extent moves, and a polyline with no width keeps exactly the path it had.Tests
GetBoundingBoxIncludesAConstantWidth,GetBoundingBoxCarriesAWidthAcrossTheSegmentAndNotBeyondItsEnds,GetBoundingBoxKeepsTheCentreLineWithoutAWidth, andGetBoundingBoxIncludesTheWidthTheVertexesCarryfor the old-style polyline. Suite 2900 / 0.