@toolpath/plan 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -120,7 +120,7 @@ const press = (action: DraftAction) => {
120
120
  | `addSetup` | A setup facing a direction nothing faces yet |
121
121
  | `setProcess` | Hold a setup 3 axis, 3+1 or 3+2 |
122
122
  | `setToolOrientation` | A folder in an indexed setup tilted to a direction of its own, or not |
123
- | `pinInto` | A click on the part in an open folder: the feature pinned there, or taken out if it is |
123
+ | `pinInto` | In an open folder: a left click pins the feature there, a right click takes out one pinned there |
124
124
  | `pinFrom` | The feature pinned in the folder facing its direction, or a new setup; let go if pinned that way |
125
125
  | `moveFeature` | A feature's row dropped on a folder: pinned there |
126
126
  | `unpin` | The feature let go: Toolpath decides where it is machined |
@@ -134,7 +134,9 @@ Each kind makes the plan Toolpath's own app makes for the same click; the packag
134
134
  to the app's own helper. A pin,
135
135
  of any kind, does what pinning does there: the person's pins whose every face it covers are let go,
136
136
  and its own faces are no longer ignored. Pinning a feature where it is pinned already lets it go, as
137
- a second click does.
137
+ a right click does. A left click on a feature in the open folder already sends nothing: it stays,
138
+ and a pick among its readings (`choosePinReading`, `target: 'add'`) pins another beside it. With
139
+ Ignore open, `ignoreClick` says what a click does: a left click ignores, a right click lets go.
138
140
 
139
141
  `facts` say what the action did beyond the draft, for the status line: the pins a pin `replaced`,
140
142
  the faces it `unignored`, the pins an ignore `unpinned`, whether a pin `added` a setup, whether it
package/dist/index.d.ts CHANGED
@@ -601,27 +601,29 @@ declare const regionLabel: (regions: ReadonlyArray<number>) => string;
601
601
  declare const takeBackIgnore: (plan: Constraints, saved: Constraints, regions: ReadonlyArray<number>, context: Pick<PlanRules, "kernel">) => Constraints;
602
602
  /** What a click on the part does while ignoring (`ignoreClick`). */
603
603
  type IgnoreClick =
604
- /** The region was ignored: the ignored regions among those taken are let go. */
604
+ /** A right click: the ignored regions among those taken are let go. */
605
605
  {
606
606
  kind: 'unignore';
607
607
  regions: Array<number>;
608
608
  }
609
- /** What the click takes is ignored. */
609
+ /** A left click: what the click takes is ignored. */
610
610
  | {
611
611
  kind: 'ignore';
612
612
  regions: Array<number>;
613
613
  };
614
614
  /**
615
- * What a click on region `region`, taking `regions` (`ignoreSelection`), does while ignoring:
616
- * ignored, the ignored regions among those taken are let go; otherwise they are ignored.
615
+ * What a click taking `regions` (`ignoreSelection`) does while ignoring: a left click ignores
616
+ * them, a right click (`remove`) lets go of those ignored. Null where it has nothing to do: a left
617
+ * click on regions every one ignored, a right click on none.
617
618
  */
618
- declare const ignoreClick: ({ region, ignored, regions, }: {
619
- region: number;
619
+ declare const ignoreClick: ({ ignored, regions, remove, }: {
620
620
  /** The regions ignored now. */
621
621
  ignored: ReadonlySet<number>;
622
622
  /** The regions the click takes: the CAD face clicked, or a feature's faces. */
623
623
  regions: ReadonlyArray<number>;
624
- }) => IgnoreClick;
624
+ /** A right click: it takes out, never adds. */
625
+ remove: boolean;
626
+ }) => IgnoreClick | null;
625
627
 
626
628
  /**
627
629
  * One edit to a plan's constraints: its setups, folders, pins and ignored faces. Every id an action
@@ -726,17 +728,16 @@ type DraftAction =
726
728
  }
727
729
  /**
728
730
  * A pick among the features a click in a folder read (`chooseReading`): `reading` meant instead of
729
- * `tag`, which the click pinned (`target: 'pin'`) or took out (`'takeOut'`) in `folderId`. Where
730
- * the click's edit no longer stands — Undo, Discard — it is made again first, in the same step.
731
- * `readings` are every feature the click read. Needs the plan as applied. A folder gone since
732
- * — Undo — changes nothing.
731
+ * `tag`, which a left click pinned (`target: 'pin'`) or left in the folder (`'add'`), or a right
732
+ * click took out (`'takeOut'`), in `folderId`. Where the click's edit no longer stands — Undo,
733
+ * Discard — it is made again first, in the same step. Needs the plan as applied. A folder gone
734
+ * since — Undo — changes nothing.
733
735
  */
734
736
  | {
735
737
  kind: 'choosePinReading';
736
738
  tag: string;
737
- target: 'pin' | 'takeOut';
739
+ target: 'pin' | 'add' | 'takeOut';
738
740
  reading: string;
739
- readings: ReadonlyArray<string>;
740
741
  folderId: string;
741
742
  }
742
743
  /**
@@ -1229,9 +1230,13 @@ declare const withPin: (plan: Constraints, tag: string, pinned: ReadonlyArray<Dr
1229
1230
  replaced: Array<string>;
1230
1231
  unignored: Array<number>;
1231
1232
  };
1232
- /** What a click does to its feature: pin it in the folder, or take it out — unpinned. */
1233
- type PinTarget = 'pin' | 'takeOut';
1234
- /** What a click made of a feature since the plan was saved: pinned in the folder, or taken out. */
1233
+ /**
1234
+ * What a click does to its feature: a left click pins it in the folder, or — in it already —
1235
+ * leaves it there (`add`: a pick among its readings adds another); a right click takes it out,
1236
+ * unpinned.
1237
+ */
1238
+ type PinTarget = 'pin' | 'add' | 'takeOut';
1239
+ /** What a click made of a feature: pinned in the folder, left in it, or taken out. */
1235
1240
  interface PinChange {
1236
1241
  tag: string;
1237
1242
  target: PinTarget;
@@ -1262,15 +1267,12 @@ declare const folderClick: (plan: Constraints, feature: {
1262
1267
  };
1263
1268
  /**
1264
1269
  * A line's choice among the features its click read. On a pin: itself, or another pinned in its
1265
- * place. On a feature taken out: it stays out, and at most one other is pinned instead — choosing
1266
- * again, or choosing to take it out, lets the one before go. A feature that goes leaves the folder as
1267
- * a click takes it out: unpinned, never put back where it was before. Answers the plan, and the
1268
- * lines whose choice is made — a pin swapped away keeps its choice unmade, so undo brings it back
1269
- * to be made.
1270
- */
1271
- declare const chooseReading: (plan: Constraints, saved: Constraints, line: PinChange, reading: string,
1272
- /** The features its click read, the line's among them. */
1273
- read: ReadonlyArray<string>, folder: {
1270
+ * place. On a feature left in the folder (`add`): itself, or another pinned there too — as any pin,
1271
+ * replacing the pins it covers. On a feature taken out: itself, or another taken out in its place,
1272
+ * the line's pinned back. Answers the plan, and the lines whose choice is made — a pin swapped away
1273
+ * keeps its choice unmade, so undo brings it back to be made.
1274
+ */
1275
+ declare const chooseReading: (plan: Constraints, saved: Constraints, line: PinChange, reading: string, folder: {
1274
1276
  id: string;
1275
1277
  direction: PlanDirection;
1276
1278
  }, context: PinContext) => {
@@ -1574,6 +1576,8 @@ declare const resultsView: ({ plan, constraints, part, }: {
1574
1576
  constraints: Pick<Constraints, "setups"> | null;
1575
1577
  part: PlanPart;
1576
1578
  }) => ResultsView;
1579
+ /** Whether a setup machines a feature, by tag in any case: lists it, as more than not machined. */
1580
+ declare const machines: (setup: ResultsSetupView, tag: string) => boolean;
1577
1581
  /** The setup a feature is machined in, by tag in any case: the first listing it, or null. */
1578
1582
  declare const setupOf: (setups: ReadonlyArray<ResultsSetupView>, tag: string) => ResultsSetupView | null;
1579
1583
 
@@ -1865,4 +1869,4 @@ declare const removeLibrary: (crib: ToolCrib, id: string) => ToolCrib;
1865
1869
  /** The crib with two libraries' places swapped, every other entry left where it is. */
1866
1870
  declare const swapLibraries: (crib: ToolCrib, a: string, b: string) => ToolCrib;
1867
1871
 
1868
- export { type ActionTarget, type AppFields, type AutomaticStock, BOX_ENVELOPE, COVERAGE_KINDS, COVERAGE_LABELS, type CheckContext, type CheckedDraft, type ConfirmCheck, type ConfirmContext, type Constraints, type ConstraintsCoverage, type Coverage, type CoverageFeature, type CoverageKind, DONE_COLOR, DRAFT_ACTION_KINDS, type DirectionAnalysis, type DirectionsKnown, type DraftAction, type DraftActionKind, type DraftFacts, type DraftFolder, type DraftResult, type DraftSetup, type DropAt, type Edited, type EnginePlan, type EnginePlanAction, type EnginePlanSetup, FLAT_BAR_FIELDS, type Face, type FaceGroup, type FaceHatch, type FacePaint, type FeatureBore, type FeatureGroupView, type FixedBoxCheck, type FixedStock, type FlatFolder, type FolderFeature, type Frame, HISTORY, type Hold, IGNORE, type IgnoreMode, type IgnoredAs, type Landing, MAX_DEPTH, MAX_NAME, MAX_SETUPS, type ModelAxis, type ModelBox, type ModelCylinder, NO_FIRST_FOLDER, type NotMachinedFeature, type NotMachinedReason, type NotMachinedWhy, OTHER_FOLDER_COLOR, PART_ROW, PRECISION, type PinChange, type PinContext, type PinEdit, type Pinned, type PinnedFeature, type PlacedFolder, type PlanCheck, type PlanDirection, type PlanFeatureRow, type PlanHighlight, type PlanIssue, type PlanOrientationView, type PlanPart, type PlanReading, type PlanRules, type PlanSession, type PlanSetupView, type PlannedSetup$1 as PlannedSetup, type PlannedSetupView, type Projection, type Quantity, REASON_SHORT, ROUND_STOCK_FIELDS, type ReadingAt, type ReadingContext, type ReadingScope, type ResultsCoverage, type ResultsFeatureRow, type ResultsSetupView, type ResultsView, STOCK_LABELS, type SessionEvent, type SessionRules, type SetupPlan, type SetupProcess, type ShowTarget, type SplitRegion, type StatedOrientation, type Statement, type StockOption, type StockPosition, TILTED_FIRST_FOLDER, type ToolCrib, type ToolCribEntry, UNMACHINED_FACE_COLOR, type Units, type UnmachinedMark, actionsFor, addFolder, addLibrary, addSetup, allClear, allFolders, applyDraftAction, areaOf, axisAlong, canRedo, canUndo, changedSinceResults, chooseReading, classifyFaces, confirmChecks, copyDirection, cribOf, cribUntouched, currentFor, defaultStock, densityUnit, describeClause, directionAnalysis, draftView, echoesStock, faceRegions, facesByRegion, featureGroups, featureTypeLabel, featureTypePlural, featuresAt, findPlaced, fixedBoxCheck, fixedBoxPlacement, flattenFolders, folderClick, folderPath, foldersFromPlan, formatArea, formatDimensions, formatFeed, formatLength, formatSurfaceSpeed, formatWeight, frameFacing, framesOf, fromInput, gapAt, groupFaces, heightOf, holdsFor, ignoreClick, ignoreEdit, ignoreSelection, ignoredAs, ignoredAsSaved, implicitLibraryIds, indexedFor, isDirection, isFallback, isFromBelow, isHeld, isHoleType, isIndexed, isUnits, liftLoneFolder, listsTag, moveFeature, moveFolder, moveSetup, moveWithin, nextFolderName, notFinishedIn, notFinishedOf, notMachinedOf, offeredLibraries, parseDraftSetups, parseStock, parseToolLength, pinEdit, pinFrom, pinHomes, pinInto, pinOf, pinTargetOf, pinnedIn, pinsWhere, placedAlong, placedFolders, planChecks, planCounts, planFromResults, planHatch, planPaint, planRunOf, planSession, planTags, planView, projectFolder, readingDetail, readingOf, readingsFor, reasonLine, refusalClauses, regionLabel, removeFolder, removeFolders, removeLibrary, renameFolder, replacedBy, restoreFeature, resultsView, roundTo, rowsOf, sameDirection, sameJson, sameStock, setSetupProcess, setToolOrientation, setupOf, sortedKeys, startSession, startingLibrary, stateOf, statementOf, stepFor, stockEdited, stockPlacement, stockRequest, suitsMaterial, swapLibraries, tagKey, tagSet, takeBack, takeBackIgnore, toInput, toStored, unignoreEdit, unignorePinned, unignoredNote, unpinFeature, unpinnedNote, whyOf, whyText, withFolders, withIgnored, withPin, withoutIgnored };
1872
+ export { type ActionTarget, type AppFields, type AutomaticStock, BOX_ENVELOPE, COVERAGE_KINDS, COVERAGE_LABELS, type CheckContext, type CheckedDraft, type ConfirmCheck, type ConfirmContext, type Constraints, type ConstraintsCoverage, type Coverage, type CoverageFeature, type CoverageKind, DONE_COLOR, DRAFT_ACTION_KINDS, type DirectionAnalysis, type DirectionsKnown, type DraftAction, type DraftActionKind, type DraftFacts, type DraftFolder, type DraftResult, type DraftSetup, type DropAt, type Edited, type EnginePlan, type EnginePlanAction, type EnginePlanSetup, FLAT_BAR_FIELDS, type Face, type FaceGroup, type FaceHatch, type FacePaint, type FeatureBore, type FeatureGroupView, type FixedBoxCheck, type FixedStock, type FlatFolder, type FolderFeature, type Frame, HISTORY, type Hold, IGNORE, type IgnoreMode, type IgnoredAs, type Landing, MAX_DEPTH, MAX_NAME, MAX_SETUPS, type ModelAxis, type ModelBox, type ModelCylinder, NO_FIRST_FOLDER, type NotMachinedFeature, type NotMachinedReason, type NotMachinedWhy, OTHER_FOLDER_COLOR, PART_ROW, PRECISION, type PinChange, type PinContext, type PinEdit, type Pinned, type PinnedFeature, type PlacedFolder, type PlanCheck, type PlanDirection, type PlanFeatureRow, type PlanHighlight, type PlanIssue, type PlanOrientationView, type PlanPart, type PlanReading, type PlanRules, type PlanSession, type PlanSetupView, type PlannedSetup$1 as PlannedSetup, type PlannedSetupView, type Projection, type Quantity, REASON_SHORT, ROUND_STOCK_FIELDS, type ReadingAt, type ReadingContext, type ReadingScope, type ResultsCoverage, type ResultsFeatureRow, type ResultsSetupView, type ResultsView, STOCK_LABELS, type SessionEvent, type SessionRules, type SetupPlan, type SetupProcess, type ShowTarget, type SplitRegion, type StatedOrientation, type Statement, type StockOption, type StockPosition, TILTED_FIRST_FOLDER, type ToolCrib, type ToolCribEntry, UNMACHINED_FACE_COLOR, type Units, type UnmachinedMark, actionsFor, addFolder, addLibrary, addSetup, allClear, allFolders, applyDraftAction, areaOf, axisAlong, canRedo, canUndo, changedSinceResults, chooseReading, classifyFaces, confirmChecks, copyDirection, cribOf, cribUntouched, currentFor, defaultStock, densityUnit, describeClause, directionAnalysis, draftView, echoesStock, faceRegions, facesByRegion, featureGroups, featureTypeLabel, featureTypePlural, featuresAt, findPlaced, fixedBoxCheck, fixedBoxPlacement, flattenFolders, folderClick, folderPath, foldersFromPlan, formatArea, formatDimensions, formatFeed, formatLength, formatSurfaceSpeed, formatWeight, frameFacing, framesOf, fromInput, gapAt, groupFaces, heightOf, holdsFor, ignoreClick, ignoreEdit, ignoreSelection, ignoredAs, ignoredAsSaved, implicitLibraryIds, indexedFor, isDirection, isFallback, isFromBelow, isHeld, isHoleType, isIndexed, isUnits, liftLoneFolder, listsTag, machines, moveFeature, moveFolder, moveSetup, moveWithin, nextFolderName, notFinishedIn, notFinishedOf, notMachinedOf, offeredLibraries, parseDraftSetups, parseStock, parseToolLength, pinEdit, pinFrom, pinHomes, pinInto, pinOf, pinTargetOf, pinnedIn, pinsWhere, placedAlong, placedFolders, planChecks, planCounts, planFromResults, planHatch, planPaint, planRunOf, planSession, planTags, planView, projectFolder, readingDetail, readingOf, readingsFor, reasonLine, refusalClauses, regionLabel, removeFolder, removeFolders, removeLibrary, renameFolder, replacedBy, restoreFeature, resultsView, roundTo, rowsOf, sameDirection, sameJson, sameStock, setSetupProcess, setToolOrientation, setupOf, sortedKeys, startSession, startingLibrary, stateOf, statementOf, stepFor, stockEdited, stockPlacement, stockRequest, suitsMaterial, swapLibraries, tagKey, tagSet, takeBack, takeBackIgnore, toInput, toStored, unignoreEdit, unignorePinned, unignoredNote, unpinFeature, unpinnedNote, whyOf, whyText, withFolders, withIgnored, withPin, withoutIgnored };
package/dist/index.js CHANGED
@@ -1028,14 +1028,15 @@ var takeBackIgnore = (plan, saved, regions, context) => ({
1028
1028
  ...ignoredAsSaved(plan, saved, regions, context.kernel)
1029
1029
  });
1030
1030
  var ignoreClick = ({
1031
- region,
1032
1031
  ignored,
1033
- regions
1032
+ regions,
1033
+ remove
1034
1034
  }) => {
1035
- if (ignored.has(region)) {
1036
- return { kind: "unignore", regions: regions.filter((each) => ignored.has(each)) };
1035
+ if (remove) {
1036
+ const going = regions.filter((each) => ignored.has(each));
1037
+ return going.length > 0 ? { kind: "unignore", regions: going } : null;
1037
1038
  }
1038
- return { kind: "ignore", regions: [...regions] };
1039
+ return regions.every((each) => ignored.has(each)) ? null : { kind: "ignore", regions: [...regions] };
1039
1040
  };
1040
1041
 
1041
1042
  // src/engine-plan.ts
@@ -1466,44 +1467,27 @@ var pinHere = (plan, tag, folderId, context) => {
1466
1467
  const pinned2 = pinEdit(plan, tag, { folderId }, context);
1467
1468
  return "refused" in pinned2 ? { intent: plan, unignored: [] } : pinned2;
1468
1469
  };
1469
- var chooseReading = (plan, saved, line, reading, read, folder, context) => {
1470
- const choice = { plan, saved, line, reading, read, folder, context };
1471
- return line.target === "pin" ? chosenForPin(choice) : chosenForTakeOut(choice);
1472
- };
1473
- var chosenForPin = ({
1474
- plan,
1475
- saved,
1476
- line,
1477
- reading,
1478
- folder,
1479
- context
1480
- }) => {
1470
+ var chooseReading = (plan, saved, line, reading, folder, context) => {
1481
1471
  if (reading === line.tag) {
1482
1472
  return { intent: plan, chosen: [reading] };
1483
1473
  }
1484
- const left = leaving(plan, saved, line.tag, context);
1485
- return { intent: pinHere(left, reading, folder.id, context).intent, chosen: [reading] };
1474
+ const choose = CHOSEN_FOR[line.target];
1475
+ return { intent: choose({ plan, saved, line, reading, folder, context }), chosen: [reading] };
1486
1476
  };
1487
- var chosenForTakeOut = (choice) => {
1488
- const { plan, saved, line, reading, folder, context } = choice;
1489
- const cleared = chosenBefore(choice).reduce((all, tag) => leaving(all, saved, tag, context), plan);
1490
- const out = pinnedIn(cleared.setups, line.tag) === pinnedIn(plan.setups, line.tag) ? cleared : letGo(cleared, line.tag);
1491
- return {
1492
- intent: reading === line.tag ? out : pinHere(out, reading, folder.id, context).intent,
1493
- chosen: reading === line.tag ? [line.tag] : [reading, line.tag]
1494
- };
1477
+ var chosenForPin = ({ plan, saved, line, reading, folder, context }) => {
1478
+ const left = letGo(takeBack(plan, saved, line.tag, context), line.tag);
1479
+ return pinHere(left, reading, folder.id, context).intent;
1480
+ };
1481
+ var chosenForAdd = ({ plan, reading, folder, context }) => pinHere(plan, reading, folder.id, context).intent;
1482
+ var chosenForTakeOut = ({ plan, line, reading, folder, context }) => {
1483
+ const back = pinHere(plan, line.tag, folder.id, context).intent;
1484
+ return pinnedIn(back.setups, reading) === folder.id ? { ...back, setups: unpinFeature(back.setups, folder.id, reading) } : back;
1485
+ };
1486
+ var CHOSEN_FOR = {
1487
+ pin: chosenForPin,
1488
+ add: chosenForAdd,
1489
+ takeOut: chosenForTakeOut
1495
1490
  };
1496
- var leaving = (plan, saved, tag, context) => letGo(takeBack(plan, saved, tag, context), tag);
1497
- var chosenBefore = ({
1498
- plan,
1499
- saved,
1500
- line,
1501
- reading,
1502
- read,
1503
- folder
1504
- }) => read.filter(
1505
- (each) => each !== line.tag && each !== reading && pinnedIn(plan.setups, each) === folder.id && pinnedIn(saved.setups, each) !== folder.id
1506
- );
1507
1491
  var readingOf = (folders, coverage) => {
1508
1492
  const faces = facesByRegion(coverage);
1509
1493
  return { folders, kindOf: (region) => faces.get(region)?.kind ?? "open" };
@@ -1763,7 +1747,6 @@ var applyChoosePinReading = ({ draft, rules, saved }, action) => {
1763
1747
  saved,
1764
1748
  { tag: action.tag, target: action.target },
1765
1749
  action.reading,
1766
- action.readings,
1767
1750
  { id: action.folderId, direction: placed.direction },
1768
1751
  rules
1769
1752
  );
@@ -1771,7 +1754,7 @@ var applyChoosePinReading = ({ draft, rules, saved }, action) => {
1771
1754
  };
1772
1755
  var withClickStanding = (draft, action, placed, rules) => {
1773
1756
  const inFolder = pinnedIn(draft.setups, action.tag) === action.folderId;
1774
- const standing = inFolder !== (action.target === "takeOut");
1757
+ const standing = action.target === "add" || inFolder !== (action.target === "takeOut");
1775
1758
  if (standing) {
1776
1759
  return draft;
1777
1760
  }
@@ -2351,12 +2334,11 @@ var markOf = (key, notFinished, notMachined) => {
2351
2334
  }
2352
2335
  return notMachined.has(key) ? "notMachined" : false;
2353
2336
  };
2354
- var setupOf = (setups, tag) => {
2337
+ var machines = (setup, tag) => {
2355
2338
  const key = tag.toLowerCase();
2356
- return setups.find(
2357
- (setup) => setup.rows.some((row) => row.tag.toLowerCase() === key && row.mark !== "notMachined")
2358
- ) ?? null;
2339
+ return setup.rows.some((row) => row.tag.toLowerCase() === key && row.mark !== "notMachined");
2359
2340
  };
2341
+ var setupOf = (setups, tag) => setups.find((setup) => machines(setup, tag)) ?? null;
2360
2342
 
2361
2343
  // src/units.ts
2362
2344
  import { MM_PER_INCH } from "@toolpath/tool-support";
@@ -2867,6 +2849,7 @@ export {
2867
2849
  isUnits,
2868
2850
  liftLoneFolder,
2869
2851
  listsTag,
2852
+ machines,
2870
2853
  moveFeature,
2871
2854
  moveFolder,
2872
2855
  moveSetup,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolpath/plan",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Plan mode for Toolpath: the plan a person states (setups, folders, pinned features, ignored faces), every edit to it, and the plan Toolpath makes from it. Logic only; views belong in @toolpath/ui",
5
5
  "license": "MIT",
6
6
  "engines": {