Feature/hatch patterns - #318
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #318 +/- ##
==========================================
+ Coverage 91.87% 91.95% +0.08%
==========================================
Files 128 128
Lines 9352 9451 +99
Branches 1966 2003 +37
==========================================
+ Hits 8592 8691 +99
- Misses 684 685 +1
+ Partials 76 75 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds support for user-defined and custom hatch patterns, including parsing/writing inline DXF hatch pattern definitions and exposing additional hatch-related properties for UI/editing. This fits into the CAD core by extending Hatch DXF round-tripping and property handling, plus a few related robustness tweaks (zoom-to-window guard, missing block handling).
Changes:
- Extend
Hatchto support DXF pattern type (group code 76) with inline pattern lines (user-defined/custom) and library pattern cloning. - Add hatch-specific properties (
hatchSpacing,hatchDouble) and support callablereadOnlyevaluation in the property system. - Add/extend Jest coverage for hatch patterns and property manager helpers; update spellchecker dictionary.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/properties/propertyManager.test.js | Adds tests for new PropertyManager helper methods and callback behaviour. |
| test/entities/hatch.test.js | Adds tests for unknown patterns, patternLines behaviour, inline DXF parsing, and DXF output for code 76/78. |
| cspell.json | Adds hatch-related tokens to cspell word list. |
| core/tables/block.js | Changes Block.boundingBox() behaviour for empty blocks. |
| core/properties/propertyManager.js | Adds getEntityForProperty() helper for resolving an entity to evaluate property metadata/readOnly. |
| core/properties/property.js | Adjusts Property.value setter semantics when readOnly is callable. |
| core/properties/entityProperties.js | Evaluates callable readOnly(entity) when setting properties. |
| core/lib/canvas.js | Guards zoom-to-window scale calculation against non-finite/invalid scale deltas. |
| core/entities/insert.js | Logs warning when referenced block is missing; adjusts bounding box behaviour for empty blocks. |
| core/entities/hatch.js | Implements inline/user-defined/custom hatch pattern handling, caching, DXF 76/77/78 handling, and pattern selection options. |
Comments suppressed due to low confidence (1)
core/tables/block.js:272
Block.boundingBox()now returnsnullwhenentitiesis empty, but the method is documented as returningBoundingBoxand inherited methods likeEntity.within()assumeboundingBox()is non-null. Also, the loop does not guard against child entities returningnullbounding boxes (e.g.Insert.boundingBox()can now return null), which will throw when accessingentityBoundingBox.xMin. Consider returning an emptyBoundingBoxfor empty blocks (consistent with other entities) and/or skipping null child bounding boxes (similar toBoundingBox.fromEntities).
boundingBox() {
if (!this.entities.length) return null;
let xmin = Infinity;
let xmax = -Infinity;
let ymin = Infinity;
let ymax = -Infinity;
for (let idx = 0; idx < this.entities.length; idx++) {
const entityBoundingBox = this.entities[idx].boundingBox();
xmin = Math.min(xmin, entityBoundingBox.xMin);
xmax = Math.max(xmax, entityBoundingBox.xMax);
ymin = Math.min(ymin, entityBoundingBox.yMin);
ymax = Math.max(ymax, entityBoundingBox.yMax);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| */ | ||
| boundingBox() { | ||
| const blockBB = this.block.boundingBox(); | ||
| if (!blockBB) return null; |
| // User-defined hatches (76=0) are normalised to the sentinel name 'U' | ||
| // so the pattern type is implied by the name rather than stored separately. | ||
| const resolvedPatternName = data?.[70] === 1 ? 'SOLID' : patternType === 0 ? 'U' : rawPatternName; | ||
| if (resolvedPatternName !== 'U' && !Patterns.patternExists(resolvedPatternName)) { |
| /** | ||
| * Build PatternLine objects from inline DXF pattern data (group code 76 = 0 or 2). | ||
| * DXF stores deltas pre-multiplied by scale; we divide by scale and convert | ||
| * inches→mm (×25.4) to match the library's mm-based PatternLine format. | ||
| * @param {Object} data - raw DXF group-code data for the HATCH entity | ||
| * @return {Array<PatternLine>} array of PatternLine objects | ||
| */ | ||
| #buildInlinePatternLines(data) { | ||
| const scale = data[41] ?? 1; | ||
| // DXF group code 53 per-family angles are written by AutoCAD as absolute |
Add support for user defined and custom hatch patterns.
fixes dubstar-04/Design#437