### JSON: Example pairs for path resolution Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_pairs.html Example JSON array of pairs for path resolution. Each pair has id, startPoint, and endPoint. The third and fourth pairs lack an id, which is allowed. ```json [ { "id" : "path1", "startPoint": "p1", "endPoint": "p2" }, { "id" : "path2", "startPoint": "p2", "endPoint": "p3" }, { "startPoint": "p3", "endPoint": "p2" }, { "startPoint": "other1", "endPoint": "other2" } ] ``` -------------------------------- ### JSON: Example segments for A/B graph Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_pairs.html Example JSON array of segments for an A/B graph. Each segment has id, firstPoint, firstSide, secondPoint, secondSide, and weight. This data is used as input for the demo. ```json [ { "id": "seg1", "firstPoint": "p1", "firstSide": "A", "secondPoint": "p2", "secondSide": "A", "weight": 8}, { "id": "seg2", "firstPoint": "p1", "firstSide": "B", "secondPoint": "p3", "secondSide": "A", "weight": 2}, { "id": "seg3", "firstPoint": "p1", "firstSide": "B", "secondPoint": "p2", "secondSide": "A", "weight": 3}, { "id": "seg11", "firstPoint": "p1", "firstSide": "A", "secondPoint": "p5", "secondSide": "A", "weight": 10.1}, { "id": "seg12", "firstPoint": "p1", "firstSide": "A", "secondPoint": "p5", "secondSide": "B", "weight": 10.1}, { "id": "seg21", "firstPoint": "p2", "firstSide": "B", "secondPoint": "p3", "secondSide": "B", "weight": 15}, { "id": "otherSeg1", "firstPoint": "other1", "firstSide": "A", "secondPoint": "other2", "secondSide": "B", "weight": 115} ] ``` -------------------------------- ### Example index.ts file for Extrude operation Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Full example of an index.ts file for a feature command. It imports required libraries, defines an OperationDescriptor with id, label, icon, info, paramsInfo, run, and form. The run function uses the OpenCASCADE command interface to create extrusions and applies boolean modifiers. ```typescript import {roundValueForPresentation as r} from 'cad/craft/operationHelper'; import {MFace} from "cad/model/mface"; import {ApplicationContext} from "cad/context"; import {EntityKind} from "cad/model/entities"; import {BooleanDefinition} from "cad/craft/schema/common/BooleanDefinition"; import {UnitVector} from "math/vector"; import {OperationDescriptor} from "cad/craft/operationPlugin"; interface ExtrudeParams { length: number; doubleSided:boolean, face: MFace; direction?: UnitVector, boolean: BooleanDefinition } export const ExtrudeOperation: OperationDescriptor = { id: 'EXTRUDE', label: 'Extrude', icon: 'img/cad/extrude', info: 'extrudes 2D sketch', paramsInfo: ({length}) => `(${r(length)})`, run: (params: ExtrudeParams, ctx: ApplicationContext) => { let occ = ctx.occService; const oci = occ.commandInterface; const face = params.face; let occFaces = []; let sketch = ctx.sketchStorageService.readSketch(face.id); if (!sketch) { occFaces.push(params.face); } else { occFaces = occ.utils.sketchToFaces(sketch, face.csys); } const dir: UnitVector = params.direction || face.normal(); const extrusionVector = dir.normalize()._multiply(params.length).data(); const extrusionVectorFliped = dir.normalize()._multiply(params.length).negate().data(); const tools = occFaces.map((faceName, i) => { const shapeName = "Tool/" + i; oci.prism(shapeName, faceName, ...extrusionVector); if(params.doubleSided){ oci.prism(shapeName + "B", faceName, ...extrusionVectorFliped); oci.bop(shapeName, shapeName + "B"); oci.bopfuse(shapeName); } return shapeName; }); return occ.utils.applyBooleanModifier(tools, params.boolean); }, form: [ { type: 'number', label: 'length', name: 'length', defaultValue: 50, }, { type: 'checkbox', label: 'Double Sided', name: 'doubleSided', defaultValue: false, }, { type: 'selection', name: 'face', capture: [EntityKind.FACE], label: 'face', multi: false, defaultValue: { usePreselection: true, preselectionIndex: 0 }, }, { type: 'direction', name: 'direction', label: 'direction', optional: true }, { type: 'boolean', name: 'boolean', label: 'boolean', optional: true, } ], } ``` -------------------------------- ### Choice widget dropdown example Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A choice widget with dropdown style. Options are provided as an array of values. The style property can be either "dropdown" or "radio". ```javascript { type: 'choice', style: "dropdown", label: 'Corner Style', name: 'cornerStyle', values: ["Round", "Sharp"], defaultValue: "Round", }, ``` -------------------------------- ### Choice widget radio example Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A choice widget with dropdown style. Options are provided as an array of values. The style property can be either "dropdown" or "radio". ```javascript { type: 'choice', style: "dropdown", label: 'operationType', name: 'operationType', values: ["Fillet", "Champher"], defaultValue: "Fillet", }, ``` -------------------------------- ### Add a field to the schema Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Example of adding a field to the schema. The order of items in the schema determines the display order in the dialog. ```javascript export default { //. . . form: [ //fields go here { type: 'number', label: 'length', name: 'length', defaultValue: 50, }, //. . . } ``` -------------------------------- ### JavaScript: Simple and Grid Graph Shortest Path Demo Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/simple_demo.html Handles user input for simple digraph and grid graph tests, calls simpleResolve, and displays results. Includes commented-out code for debugging. ```javascript import {makeTestGridGraph, parseJsonAndPrintError, simpleResolve} from "./demo.js" function doSimple() { const startVertex = document.querySelector("#simpleStart").value; const endVertex = document.querySelector("#simpleEnd").value; const graphJson = parseJsonAndPrintError(document.querySelector("#graphJson").value, "simpleError"); // let node = simpleObjectToGraphNode("0", new Array(["1", "2"])); // document.querySelector("#simpleResults").innerHTML = JSON.stringify(node); // let g = simpleObjectToDigraph(graphJson); // document.querySelector("#simpleResults").innerHTML = JSON.stringify(Array.from(g.nodeMap.entries())); const report = simpleResolve(graphJson, startVertex, endVertex, "simpleError"); document.querySelector("#simpleResults").innerHTML = report; } function doGrid() { const startVertex = document.querySelector("#gridStart").value; const endVertex = document.querySelector("#gridEnd").value; const graphJson = makeTestGridGraph( document.querySelector("#gridWidth").value, document.querySelector("#gridHeight").value, document.querySelector("#straightWeight").value, document.querySelector("#diagonalWeight").value, document.querySelector("#includeDiagonals").checked); const report = simpleResolve(graphJson, startVertex, endVertex, "gridError"); document.querySelector("#gridResults").innerHTML = report; } document.querySelector("#doSimple").onclick = doSimple; document.querySelector("#doGrid").onclick = doGrid; ``` -------------------------------- ### File widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Defines a file widget that lets the user select a file from the local file system. The selected file's contents are made available to the feature. ```javascript { type: 'file', name: 'file', label: 'Select File', }, ``` -------------------------------- ### String widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A simple text entry field that returns a string. ```javascript { type: 'string', label: 'String Field', name: 'exampleString', defaultValue: "hello world", }, ``` -------------------------------- ### Image widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Use in a command dialog to insert an image that illustrates the command's intent. The image is referenced via an imported string variable. ```javascript { type: 'image', name: 'figure1', img: imageStringLoadedFromImport, } ``` -------------------------------- ### doGrid: Run grid A/B sided graph speed test Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_pairs_grid.html Sets up the grid-based A/B sided graph speed test. Reads UI values, generates segments and pairs, disables the button during processing, and calls sidedAdPairsResolve with progress reporting. ```javascript import {makeTestGridAbGraph, makeTestGridAbPointPairs, sidedAdPairsResolve} from "./demo.js" import {\_setUseMinHeap} from "./js/digraphs/spt.js" async function doGrid() { \_setUseMinHeap(document.querySelector("#useMinHeap").checked); // - for debugging needs (measuring speed); normally should be true const width = document.querySelector("#gridWidth").value; const height = document.querySelector("#gridHeight").value; const straightWeight = document.querySelector("#straightWeight").value; const diagonalWeight = document.querySelector("#diagonalWeight").value; const includeDiagonals = document.querySelector("#includeDiagonals").checked; const brief = document.querySelector("#brief").checked; const numberOfPairs = parseInt(document.querySelector("#numberOfPairs").value); const randomSeed = parseInt(document.querySelector("#randomSeed").value); const t1 = performance.now(); const segments = makeTestGridAbGraph(width, height, straightWeight, diagonalWeight, includeDiagonals); const pairs = makeTestGridAbPointPairs(width, height, numberOfPairs, randomSeed); document.querySelector("#segments").value = JSON.stringify(segments, null, 2); document.querySelector("#pairs").value = JSON.stringify(pairs, null, 2); const t2 = performance.now(); document.querySelector("#preparingTiming").innerHTML = "Preparing: " + (t2 - t1) + " ms"; document.querySelector("#doGrid").disabled = true; // - important to prevent starting new threads of calculations while processing is not finished const report = await sidedAdPairsResolve(segments, pairs, brief, "error", "timing", "progressBar"); document.querySelector("#doGrid").disabled = false; document.querySelector("#results").value = report; } document.querySelector("#doGrid").onclick = doGrid; ``` -------------------------------- ### Create bottle with OpenCascade oci commands Source: https://github.com/xibyte/jsketcher/blob/main/modules/debugger/bottleExample.txt Builds a bottle shape using the OpenCascade command interface (oci) in a JSketch environment. It creates primitives, performs boolean operations, blends edges, and constructs a threaded neck via thrusections. The final shell is added to the scene with ctx.services.exposure.addOnScene. ```javascript const ctx = __CAD_APP; const {commandInterface: oci, io} = ctx.occService; const height = 70; const width = 50; const thickness = 30; const neckradius = thickness / 4; const neckheight = height / 10; const major = 2 * Math.PI; const minor = neckheight / 10; let pi = Math.PI; oci.box("b1", "10.0", "15.0", "20.0"); oci.box("b2", "-min", "5.0", "7.5", "10.0", "-max", "20.0", "25.0", "30.0"); oci.bcut("resultOfCut", "b1", "b2"); oci.bfuse("resultOfUnion", "b1", "b2"); oci.bcommon("resultOfIntersection", "b1", "b2"); oci.vertex("v1", -width / 2, "0", "0") oci.vertex("v2", -width / 2, -thickness / 4, "0") oci.edge("e1", "v1", "v2") oci.point("p2", -width / 2, -thickness / 4, "0") oci.point("p3", "0", -thickness / 2, "0") oci.point("p4", width / 2, -thickness / 4, "0") oci.gcarc("arc", "cir", "p2", "p3", "p4") oci.mkedge("e2", "arc") oci.vertex("v4", width / 2, -thickness / 4, "0") oci.vertex("v5", width / 2, "0", "0") oci.edge("e3", "v4", "v5") oci.wire("w1", "e1", "e2", "e3") oci.copy("w1", "w2") oci.tmirror("w2", "0", "0", "0", "0", "1", "0") oci.wire("w3", "w1", "w2") oci.mkplane("f", "w3") oci.prism("p", "f", "0", "0", height) oci.explode("p", "e") oci.blend("b", "p", thickness / 12, "p_1", thickness / 12, "p_2", thickness / 12, "p_3", thickness / 12, "p_4", thickness / 12, "p_5", thickness / 12, "p_6", thickness / 12, "p_7", thickness / 12, "p_8", thickness / 12, "p_9", thickness / 12, "p_10", thickness / 12, "p_11", thickness / 12, "p_12", thickness / 12, "p_13", thickness / 12, "p_14", thickness / 12, "p_15", thickness / 12, "p_16", thickness / 12, "p_17", thickness / 12, "p_18") oci.pcylinder("c", neckradius, neckheight) oci.ttranslate("c", "0", "0", height) oci.bfuse("f", "b", "c") oci.explode("c", "f") oci.offsetshape("body", "f", -thickness / 50, "1.e-3", "c_2") oci.cylinder("c1", "0", "0", height, "0", "0", "1", neckradius * 0.99) oci.cylinder("c2", "0", "0", height, "0", "0", "1", neckradius * 1.05) oci.ellipse("el1", 2 * pi, neckheight / 2, 2 * pi, neckheight / 4, major, minor) oci.ellipse("el2", 2 * pi, neckheight / 2, 2 * pi, neckheight / 4, major, minor / 4) oci.trim("arc1", "el1", "0", pi) oci.trim("arc2", "el2", "0", pi) oci._2dcvalue("el1", "0", "x1", "y1") oci._2dcvalue("el1", pi, "x2", "y2") oci.line("l", "x1", "y1", "x2-x1", "y2-y1") oci.parameters("l", "x2", "y2", "1.e-9", "U") oci.trim("s", "l", "0", "U") oci.mkedge("E1OnS1", "arc1", "c1", "0", pi) oci.mkedge("E2OnS1", "s", "c1", "0", "U") oci.mkedge("E1OnS2", "arc2", "c2", "0", pi) oci.mkedge("E2OnS2", "s", "c2", "0", "U") oci.wire("tw1", "E1OnS1", "E2OnS1") oci.wire("tw2", "E1OnS2", "E2OnS2") oci.mkedgecurve("tw1", "1.e-5") oci.mkedgecurve("tw2", "1.e-5") oci.thrusections("-N", "thread", "1", "0", "tw1", "tw2") oci.bop("body", "thread") oci.bopfuse("bottle") ctx.services.exposure.addOnScene(io.getShell("bottle")); ``` -------------------------------- ### Import and simple test handler for sidedAdResolve Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_demo.html Imports parseJsonAndPrintError and sidedAdResolve from demo.js. The doSimple function reads start/end vertices and a JSON segments array from input fields, calls sidedAdResolve, and displays the report in the simpleResults element. The button with id 'doSimple' is wired to this handler. ```javascript import {parseJsonAndPrintError, sidedAdResolve} from "./demo.js" function doSimple() { const startVertex = document.querySelector("#simpleStart").value; const endVertex = document.querySelector("#simpleEnd").value; const segments = parseJsonAndPrintError(document.querySelector("#segments").value, "simpleError"); const report = sidedAdResolve(segments, startVertex, endVertex, "simpleError"); document.querySelector("#simpleResults").innerHTML = report; } ``` -------------------------------- ### Import image for image widget Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Add at the top of the command TypeScript file to import an image for use with the image widget. The import path is relative to the file. ```typescript import imageStringLoadedFromImport from './icon.svg'; ``` -------------------------------- ### Test MinHeap with insertion and removal Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/js/heap/test_heap.html Tests the MinHeap class by inserting nodes with increasing, negative, and random keys, then removing them to verify sorted order and heap integrity. The checkHeap function calls checkIntegrity() and throws an error if the removal order violates the heap property. The test is triggered by clicking the button with id "buttonTest" and writes the report to the element with id "report". ```javascript import {MinHeap} from "./min_heap.js" const n = 11; function newNode(x, y) { return {x: x, y: y}; } function less(a, b) { const result = a.x < b.x; // console.log(JSON.stringify(a) + " and " + JSON.stringify(b) + ": " + result); return result; } function testHeap() { const heap = new MinHeap(less); let report = ""; for (let k = 0; k < n; k++) { heap.insert(newNode(k, k)); } report += checkHeap(heap); report += "\n"; for (let k = 0; k < n; k++) { heap.insert(newNode(-5 * k, null)); } report += checkHeap(heap); report += "\n"; for (let k = 0; k < n; k++) { heap.insert(newNode(Math.random() * 100, 12)); } report += checkHeap(heap); report += "\n"; document.getElementById("report").innerHTML = "
" + report + "
"; } function checkHeap(heap) { try { heap.checkIntegrity(); let last = null; let report = ""; for (let k = 0; k < n; k++) { const a = heap.remove(); report += k + ": " + JSON.stringify(a) + "\n"; if (last != null && less(a, last)) { throw "Error: " + JSON.stringify(a) + " < " + JSON.stringify(last); } last = a; } return report; } catch (e) { document.getElementById("error").innerHTML = e; throw msg; } } document.getElementById("buttonTest").onclick = testHeap; ``` -------------------------------- ### Wire up doSimple button click Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_demo.html Assigns the doSimple function to the onclick event of the element with id 'doSimple'. ```javascript document.querySelector("#doSimple").onclick = doSimple; ``` -------------------------------- ### Selection widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A selection widget configuration. The multi property dictates if the user can select more than one object; when true an array is returned, when false a single object. The capture property is an array of permitted object types. Default value allows preselection to populate automatically. ```javascript { type: 'selection', name: 'face', capture: [EntityKind.FACE], label: 'face', multi: false, defaultValue: { usePreselection: true, preselectionIndex: 0, }, }, ``` -------------------------------- ### Checkbox widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A checkbox widget configuration object. Returns a true or false value. ```javascript { type: 'checkbox', label: 'Double Sided', name: 'doubleSided', defaultValue: false, }, ``` -------------------------------- ### Return object format for feature commands Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md The run function must return an object with this exact format, containing 'created' and 'consumed' arrays. ```typescript let resultsOfCommand ={ created:[], consumed:[] } return resultsOfCommand; ``` -------------------------------- ### Boolean widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Use in a command dialog to capture the boolean operation type and target shell from the user's 3D selection. The widget provides a drop-down with options 'None', 'Unite', 'Subtract', or 'Intersect'. ```javascript { type: 'boolean', name: 'boolean', label: 'boolean', optional: true, } ``` -------------------------------- ### Text widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Defines a text widget for a dialog. The 'name' property is used to reference the widget's value, and 'label' provides the text displayed to the user. ```javascript { type: 'text', name: 'descriptiveText', label: 'This is a custom text that can be used to show extra info about what particulart parts of the command are to be used.', } ``` -------------------------------- ### Vector widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Use in a command dialog to let the user pick a direction from a face, edge, sketch curve, or datum axis. A checkbox in the widget lets the user invert or flip the direction. ```javascript { type: 'vector', name: 'direction', label: 'direction', optional: true, }, ``` -------------------------------- ### Commented-out grid test handler for sidedAdResolve Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_demo.html Commented-out code for a grid-based test. It would read grid parameters (width, height, weights, includeDiagonals) and call sidedAdResolve, but it is not active. Note that the variable 'segments' is not defined in this block, so it would not work if uncommented. ```javascript /* function doGrid() { const startVertex = document.querySelector("#gridStart").value; const endVertex = document.querySelector("#gridEnd").value; const graphJson = makeTestGridGraph( document.querySelector("#gridWidth").value, document.querySelector("#gridHeight").value, document.querySelector("#straightWeight").value, document.querySelector("#diagonalWeight").value, document.querySelector("#includeDiagonals").checked); const report = sidedAdResolve(segments, startVertex, endVertex, "gridError"); document.querySelector("#gridResults").innerHTML = report; } */ ``` -------------------------------- ### JSON: Default Simple Digraph Graph Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/simple_demo.html Default graph for the simple digraph test. Expected results are shown below. ```json { "0": { "2" : 26, "4": 38 }, "1": { "3" : 29 }, "2": { "7" : 34 }, "3": { "6" : 52 }, "4": { "5" : 35, "7": 37 }, "5": { "7" : 28, "1": 32 }, "6": { "0" : 58, "2": 40, "4": 93 }, "7": { "3" : 39, "5": 28 }, "OtherA": {"OtherB" : 2 }, "OtherB": {} } ``` -------------------------------- ### paramsInfo tooltip definition Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Defines the paramsInfo tooltip string for a feature. It uses a template literal that references schema items (length, width, height) to display the tooltip text when hovering over the feature in the part history. ```javascript export default { //. . . paramsInfo: ({ length, width, height }) => `(Cube - Size: ${r(length)}, ${r(width)}, ${r(height)})`, //. . . } ``` -------------------------------- ### Number widget configuration Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md A numeric value entry field. The style property can be set to 'slider' or 'spinner' instead of the default textbox. ```javascript { type: 'number', label: 'length', style: 'slider', name: 'length', defaultValue: 50, }, ``` -------------------------------- ### JavaScript: Parse input and call sidedAdPairsResolve Source: https://github.com/xibyte/jsketcher/blob/main/modules/workbenches/routingElectrical/features/autoRoute/pathFinderLogic/sided_ab_pairs.html This script reads JSON from textareas, calls sidedAdPairsResolve with the parsed segments and pairs, and writes the report to a results textarea. It uses parseJsonAndPrintError to handle JSON parsing errors and displays timing information. ```javascript import {parseJsonAndPrintError, sidedAdPairsResolve} from "./demo.js" async function doAnalyse() { const segments = parseJsonAndPrintError(document.querySelector("#segments").value, "error"); const pairs = parseJsonAndPrintError(document.querySelector("#pairs").value, "error"); const report = await sidedAdPairsResolve(segments, pairs, false, "error", "timing"); document.querySelector("#results").value = report; } document.querySelector("#doAnalyse").onclick = doAnalyse; ``` -------------------------------- ### Apply boolean modifier in feature run Source: https://github.com/xibyte/jsketcher/blob/main/dev-guide/index.md Place as the return from the run section of feature code when using the boolean widget. It populates the consumed and created object arrays and is the preferred method for all boolean operations in JSketcher. ```javascript return occ.utils.applyBooleanModifier(tools, params.boolean); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.