@sienci/gviewer 0.1.0 → 0.1.2

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
@@ -21,9 +21,9 @@ npm install react react-dom # required for the React component
21
21
 
22
22
  | Path | Contents |
23
23
  |---|---|
24
- | `@sienci/gviewer` | Parser, virtualizer, geometry builders, shared types |
25
- | `@sienci/gviewer/viewer` | `GCodeViewer` class, themes, viewer types |
26
- | `@sienci/gviewer/react` | `GCodeVisualizer` React component |
24
+ | `@sienci/gviewer` | Parser, virtualizer, geometry builders, `WorkerGeometryData`, shared types |
25
+ | `@sienci/gviewer/viewer` | `GCodeViewer`, `GCodeSVGRenderer`, themes, viewer types, `WorkerGeometryData` |
26
+ | `@sienci/gviewer/react` | `GCodeVisualizer`, `GCodeSVGVisualizer` React components |
27
27
  | `@sienci/gviewer/viewer/viewcube.css` | Stylesheet for the ViewCube overlay |
28
28
 
29
29
  ---
@@ -261,6 +261,34 @@ const result = await buildLaserGeometryFromLinesBatched(lines, {
261
261
  // result.buckets[i].prefixEndVertex
262
262
  ```
263
263
 
264
+ ##### `buildWorkerSegmentGroups`
265
+
266
+ Converts the pre-parsed payload from an external worker (e.g. gSender's `Visualize.worker`) into groups of stride-6 line segments, each with a hex color and opacity. Segments with the same color and opacity are merged into a single group. This is the conversion step used internally by `loadFromWorkerData()` on both the 3D viewer and the SVG renderer.
267
+
268
+ ```ts
269
+ import { buildWorkerSegmentGroups } from "@sienci/gviewer";
270
+ import type { WorkerGeometryData } from "@sienci/gviewer";
271
+
272
+ const groups = buildWorkerSegmentGroups(workerData);
273
+ // groups[i].hexColor — e.g. "#0ef6ae"
274
+ // groups[i].opacity — 0.5 for rapid moves, 1.0 for cutting moves
275
+ // groups[i].positions — Float32Array stride-6: [x0,y0,z0, x1,y1,z1, ...]
276
+ // groups[i].rgbColors — Float32Array stride-3 per vertex (2 per segment, same length as positions)
277
+ ```
278
+
279
+ `WorkerGeometryData` matches the relevant fields of the `geometryReady` worker message:
280
+
281
+ ```ts
282
+ type WorkerGeometryData = {
283
+ vertices: ArrayBuffer; // Float32Array stride-3: individual 3D points
284
+ frames: ArrayBuffer; // Uint32Array: vertex index at the start of each motion segment
285
+ colorArrayBuffer: ArrayBuffer; // Float32Array stride-4: r,g,b,opacity per vertex (values 0–1)
286
+ verticesLen: number;
287
+ framesLen: number;
288
+ colorLen: number;
289
+ };
290
+ ```
291
+
264
292
  ---
265
293
 
266
294
  ### `@sienci/gviewer/viewer` — Three.js viewer
@@ -298,6 +326,28 @@ await viewer.loadFromLines(["G21", "G0 X10 Y10"]);
298
326
  viewer.unload();
299
327
  ```
300
328
 
329
+ ##### Loading from pre-parsed worker data
330
+
331
+ If GCode has already been parsed by an external worker (e.g. gSender's `Visualize.worker`), pass the `geometryReady` payload directly to skip re-parsing. Per-vertex colors — including tool-change palette cycling — are preserved.
332
+
333
+ ```ts
334
+ import type { WorkerGeometryData } from "@sienci/gviewer/viewer";
335
+
336
+ // workerData comes from the worker's geometryReady message
337
+ const workerData: WorkerGeometryData = {
338
+ vertices: msg.vertices, // ArrayBuffer (Float32Array stride-3: x,y,z per point)
339
+ frames: msg.frames, // ArrayBuffer (Uint32Array: vertex index per motion segment)
340
+ colorArrayBuffer: msg.colorArrayBuffer, // ArrayBuffer (Float32Array stride-4: r,g,b,opacity per vertex)
341
+ verticesLen: msg.verticesLen,
342
+ framesLen: msg.framesLen,
343
+ colorLen: msg.colorLen,
344
+ };
345
+
346
+ await viewer.loadFromWorkerData(workerData);
347
+ ```
348
+
349
+ > **Note:** `seekToLine()` and `hideUntilLine()` are no-ops when data is loaded this way, because per-line vertex ranges are not included in the worker response. Pass GCode text to `loadFromLines()` if you need those features.
350
+
301
351
  ##### Camera
302
352
 
303
353
  ```ts
@@ -411,6 +461,66 @@ type GCodeViewerOptions = {
411
461
 
412
462
  ---
413
463
 
464
+ ### `GCodeSVGRenderer` — SVG viewer
465
+
466
+ Lightweight 2D/isometric SVG renderer. No Three.js dependency — works in any environment that has a DOM. Supports orbit (drag to rotate), pan (right-click drag or Shift+drag), and scroll-to-zoom.
467
+
468
+ ```ts
469
+ import { GCodeSVGRenderer } from "@sienci/gviewer/viewer";
470
+ import type { GCodeSVGOptions } from "@sienci/gviewer/viewer";
471
+
472
+ const renderer = new GCodeSVGRenderer(
473
+ document.getElementById("container")!,
474
+ { /* Partial<GCodeSVGOptions> */ }
475
+ );
476
+ ```
477
+
478
+ ##### Loading GCode
479
+
480
+ ```ts
481
+ renderer.loadFromText("G21\nG0 X10 Y10\n...");
482
+ renderer.loadFromLines(["G21", "G0 X10 Y10"]);
483
+ await renderer.loadFromFile(fileInputElement.files[0]);
484
+ renderer.clear();
485
+ ```
486
+
487
+ ##### Loading from pre-parsed worker data
488
+
489
+ Pass the `geometryReady` payload directly to avoid re-parsing. Tool-change colors from the worker are rendered as separate colored paths.
490
+
491
+ ```ts
492
+ import type { WorkerGeometryData } from "@sienci/gviewer/viewer";
493
+
494
+ renderer.loadFromWorkerData(workerData);
495
+ ```
496
+
497
+ ##### Controls
498
+
499
+ ```ts
500
+ renderer.resetView(); // reset rotation and re-fit
501
+ renderer.setProjectionMode("isometric"); // "isometric" (default) | "perspective"
502
+ renderer.getSVGElement(); // returns the <svg> element (for export, etc.)
503
+ renderer.dispose(); // remove event listeners and DOM element
504
+ ```
505
+
506
+ ##### Options
507
+
508
+ ```ts
509
+ renderer.setOptions({
510
+ rapidColor: "#0ef6ae", // G0 rapid move color
511
+ cutColor: "#3e85c7", // G1/G2/G3 cutting move color
512
+ boundingBoxColor: "#d0d0d0", // wireframe bounding box color
513
+ strokeWidth: 0.5, // path stroke width in SVG units
514
+ arcSegments: 30, // arc tessellation quality
515
+ padding: 5, // fixed padding around the fit view (SVG units)
516
+ projectionMode: "isometric", // "isometric" | "perspective"
517
+ });
518
+ ```
519
+
520
+ > **Note:** When data is loaded via `loadFromWorkerData()`, `rapidColor` and `cutColor` are ignored — colors come from the worker payload. Other options (stroke width, padding, projection mode) apply in both modes.
521
+
522
+ ---
523
+
414
524
  ### `@sienci/gviewer/react` — React component
415
525
 
416
526
  ```tsx
@@ -440,6 +550,7 @@ const ref = useRef<GCodeViewerHandle>(null);
440
550
 
441
551
  // Later:
442
552
  ref.current?.loadFromText(gcode);
553
+ ref.current?.loadFromWorkerData(workerData);
443
554
  ref.current?.focusToModel();
444
555
  ref.current?.hideUntilLine(currentLine, "grey");
445
556
  ref.current?.snapCameraToView("top");
@@ -448,6 +559,34 @@ ref.current?.setBitPosition({ x, y, z });
448
559
 
449
560
  `options` and `callbacks` props are synced to the viewer whenever they change (via `useEffect`).
450
561
 
562
+ #### `GCodeSVGVisualizer`
563
+
564
+ React wrapper for `GCodeSVGRenderer`.
565
+
566
+ ```tsx
567
+ import { GCodeSVGVisualizer } from "@sienci/gviewer/react";
568
+ import type { GCodeSVGRendererHandle } from "@sienci/gviewer/react";
569
+ import type { GCodeSVGOptions } from "@sienci/gviewer/viewer";
570
+
571
+ const ref = useRef<GCodeSVGRendererHandle>(null);
572
+
573
+ <GCodeSVGVisualizer
574
+ id="svg-viewer"
575
+ ref={ref}
576
+ options={{ strokeWidth: 0.5, projectionMode: "isometric" }}
577
+ style={{ width: "100%", height: "400px" }}
578
+ />
579
+
580
+ // Load via any method:
581
+ ref.current?.loadFromText(gcode);
582
+ ref.current?.loadFromWorkerData(workerData);
583
+ ref.current?.resetView();
584
+ ref.current?.setProjectionMode("perspective");
585
+ ref.current?.getSVGElement(); // access raw <svg> for export
586
+ ```
587
+
588
+ `GCodeSVGRendererHandle` exposes: `loadFromLines`, `loadFromFile`, `loadFromText`, `loadFromWorkerData`, `clear`, `resetView`, `setOptions`, `setProjectionMode`, `getSVGElement`, `dispose`.
589
+
451
590
  ---
452
591
 
453
592
  ## Development