Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ All notable changes to the **VS Code Aster** extension will be documented in thi
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.9.1] - 2026-04-23

New viewer toolbar actions (auto-rotate, video recording), a reorganized settings popup with a dedicated Toolbar tab, and a round of `.export` editor fixes.

### Added
- **Auto-rotate** toolbar button with a right-click popover for session-only speed and reverse-direction; persistent defaults in `Settings → Toolbar`.
- **Record** toolbar button (mp4/h264 when supported, else webm, saved to `.vs-code-aster/recordings/`). Right-click menu offers whole-webview or without-sidebar variants. Whole-webview rasterizes the DOM and may briefly freeze the viewer on UI changes.
- **Settings → Toolbar tab** grouping each toolbar action with its persisted defaults.
- `.export` base directory support (`R extension name D/DC/RC unit`).
- `.export` `max_base`, `testlist`, `expected_diag` form fields.
- `.export` split basename / extension inputs, smarter default unit, and preservation of unknown lines.

### Changed
- **Viewer settings** reorganized into `Rendering`, `Groups`, `Visibility`, `Toolbar` tabs.
- **Dream background** on by default.
- **Screenshot right-click** now opens a menu (was a direct full-webview capture).
- **Canvas screenshots and recordings** crop out the sidebar region so the mesh is centered in the output.
- **Export form error/warning panel** merged into one clickable list with per-field jumps.

### Fixed
- `.export` file name / extension inputs no longer silently revert due to a state-sync feedback loop.
- Optional integer parameters no longer flagged as invalid when left empty.

## [1.9.0] - 2026-04-21

Volume and edge groups now appear in the viewer alongside face and node groups, a new "Groups" settings tab exposes per-kind display tweaks, the bundled vtk.js is replaced by the tree-shaken npm package, and an optional animated background adds a cosmetic touch.
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cff-version: 1.9.0
cff-version: 1.9.1
title: VS Code Aster
message: >-
If you use this software, please cite it using the
Expand Down
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<p align="center"><img src="https://raw.githubusercontent.com/simvia-tech/vs-code-aster/main/media/images/simvia.png" alt="Simvia Logo" width="50%" /></p>

<p align="center">
<a href="/"><img src="https://img.shields.io/badge/version-1.9.0-blue" alt="Version" /></a>
<a href="/"><img src="https://img.shields.io/badge/version-1.9.1-blue" alt="Version" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-GPL%203.0-green" alt="License" /></a>
<a href="https://github.com/simvia-tech/vs-code-aster/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/simvia-tech/vs-code-aster/ci.yml?branch=main&label=CI" alt="CI Status" /></a>
<a href="https://github.com/simvia-tech/vs-code-aster/issues"><img src="https://img.shields.io/github/issues/simvia-tech/vs-code-aster?label=issues" alt="GitHub issues" /></a>
Expand Down Expand Up @@ -210,9 +210,12 @@ There are two ways to open the visualizer :
- Control the camera by rotating or panning it
- **Bounding box** : toggle a wireframe cube with colored axes (X red, Y green, Z blue), corner dots, and dimension labels to quickly read the characteristic size of the structure
- **Wireframe mode** : switch between solid surface and wireframe rendering to inspect mesh density
- **Screenshot** : save the current 3D view as a PNG file next to your mesh and copy it to the clipboard
- **Auto-rotate** : hands-free turntable that spins the camera around the current view-up; right-click the button to reveal a popover with a speed slider (5–180 °/s) and a reverse-direction toggle — changes there apply to the current view only, persistent defaults live in _Settings → Toolbar_
- **Screenshot** : save the current 3D view as a PNG file next to your mesh and copy it to the clipboard; right-click for a menu to capture the whole webview (toolbar + sidebar baked in)
- **Record** : capture a video of the view (mp4 when the runtime supports h264, webm otherwise), saved to `.vs-code-aster/recordings/`; left-click to start/stop, right-click for whole-webview or without-sidebar variants. The button pulses red with an elapsed-time indicator while recording
- **Per-kind settings** : Settings popup exposes edge-group line thickness, edge-group depth offset (to avoid z-fighting), node-group point size, and the sidebar sort order — plus a toggle to bucket groups by kind or mix them into a single list
- **Dream background** : optional cosmetic setting that animates EDF orange and blue light blobs behind the mesh for a more vibrant workspace
- **Remembered toolbar defaults** : every toolbar button (bounding box, wireframe, auto-rotate) is session-only by default — toggling it changes the current view only. Persistent defaults are set in _Settings → Toolbar_, grouped per feature (Bounding box, Wireframe, Auto-rotate with default speed and default direction)
- **Dream background** : on by default, animates EDF orange and blue light blobs behind the mesh for a more vibrant workspace; can be disabled from _Settings → Rendering_

#### Usage tips

Expand All @@ -228,12 +231,17 @@ There are two ways to open the visualizer :
- Use the `Mouse wheel` to zoom in and out
- Click on the `X`, `Y`, and `Z` buttons at the bottom of the sidebar to quickly align the camera along an axis
- Toolbar :
- The top toolbar provides quick access to the bounding box, wireframe, and screenshot features
- Right-click the screenshot button to capture the full viewer including the sidebar
- The top toolbar provides quick access to the bounding box, wireframe, auto-rotate, screenshot, and record features
- Left-click toggles a feature for the current view only; remembered defaults live in _Settings → Toolbar_
- Right-click the **auto-rotate** button for a session-only speed slider and reverse-direction toggle
- Right-click the **screenshot** button for a menu to capture the whole webview (sidebar included)
- Right-click the **record** button for options: whole webview, or without the sidebar
- Settings tabs : _Rendering_ (mesh-edge mode, orientation widget, dream background), _Groups_ (per-kind display), _Visibility_ (ghosted objects, highlight transparency), _Toolbar_ (default state for toolbar buttons)
- File management :
- Files generated by the extension are stored in a hidden `.vs-code-aster/` folder next to your project files:
- `mesh_cache/` — converted `.obj` files from your `.*med` meshes, reused on subsequent opens
- `screenshots/` — PNGs saved from the viewer's screenshot button
- `recordings/` — video files saved from the viewer's record button (mp4 / webm)
- `run_logs/` — one timestamped log per code_aster run (oldest pruned, see `vs-code-aster.maxRunLogs`)

## Troubleshooting
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The extension aims to reduce friction between modeling, validation, execution, and analysis by bringing **code_aster** native workflows into the editor.

## Current Capabilities (v1.9.0)
## Current Capabilities (v1.9.1)

- `.export` file generator
- 3D mesh viewer
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vs-code-aster",
"displayName": "VS Code Aster",
"version": "1.9.0",
"version": "1.9.1",
"description": "VS Code extension for code_aster",
"publisher": "simvia",
"license": "GPL-3.0",
Expand Down Expand Up @@ -362,9 +362,29 @@
"vs-code-aster.viewer.dreamBackground": {
"order": 22,
"type": "boolean",
"default": false,
"default": true,
"markdownDescription": "Cosmetic animated EDF orange and blue light blobs slowly breathing behind the mesh. Purely decorative — does not affect mesh lighting."
},
"vs-code-aster.viewer.autoRotate": {
"order": 23,
"type": "boolean",
"default": false,
"markdownDescription": "Automatically rotate the view around the current vertical axis like a turntable."
},
"vs-code-aster.viewer.autoRotateSpeed": {
"order": 24,
"type": "number",
"default": 15,
"minimum": 5,
"maximum": 180,
"markdownDescription": "Default auto-rotation speed in degrees per second (between `5` and `180`). Transient overrides from the toolbar popover are not persisted."
},
"vs-code-aster.viewer.autoRotateReverse": {
"order": 25,
"type": "boolean",
"default": false,
"markdownDescription": "Default auto-rotation direction. When enabled, the view rotates the opposite way by default. Transient overrides from the toolbar popover are not persisted."
},
"vs-code-aster.enableTelemetry": {
"order": 100,
"type": "boolean",
Expand Down
22 changes: 20 additions & 2 deletions src/WebviewVisu.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import { getScreenshotsDir } from './projectPaths';
import { getScreenshotsDir, getRecordingsDir } from './projectPaths';

/**
* Provides basic dialog semantics over a VS Code webview panel for mesh visualization.
Expand Down Expand Up @@ -130,6 +130,9 @@ export class WebviewVisu implements vscode.Disposable {
'showBoundingBox',
'showWireframe',
'dreamBackground',
'autoRotate',
'autoRotateSpeed',
'autoRotateReverse',
];
for (const key of settingKeys) {
if (e.settings[key] !== undefined) {
Expand All @@ -147,6 +150,18 @@ export class WebviewVisu implements vscode.Disposable {
}
break;
}
case 'saveRecording': {
if (this.sourceDir) {
const dataUrl = e.dataUrl as string;
const commaIdx = dataUrl.indexOf(';base64,');
const base64 = commaIdx >= 0 ? dataUrl.slice(commaIdx + ';base64,'.length) : dataUrl;
const buffer = Buffer.from(base64, 'base64');
const recordingsDir = getRecordingsDir(this.sourceDir);
const filePath = path.join(recordingsDir, e.filename as string);
fs.writeFileSync(filePath, buffer);
}
break;
}
case 'debugPanel':
// Log debug messages from the webview
console.log('[WebviewVisu] Message received from webview:', e.text);
Expand Down Expand Up @@ -207,7 +222,10 @@ export class WebviewVisu implements vscode.Disposable {
showOrientationWidget: config.get<boolean>('viewer.showOrientationWidget', true),
showBoundingBox: config.get<boolean>('viewer.showBoundingBox', false),
showWireframe: config.get<boolean>('viewer.showWireframe', false),
dreamBackground: config.get<boolean>('viewer.dreamBackground', false),
dreamBackground: config.get<boolean>('viewer.dreamBackground', true),
autoRotate: config.get<boolean>('viewer.autoRotate', false),
autoRotateSpeed: config.get<number>('viewer.autoRotateSpeed', 15),
autoRotateReverse: config.get<boolean>('viewer.autoRotateReverse', false),
};
this.panel.webview.postMessage({
type: 'init',
Expand Down
4 changes: 4 additions & 0 deletions src/projectPaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export function getScreenshotsDir(projectDir: string): string {
return ensureDir(path.join(getProjectDir(projectDir), 'screenshots'));
}

export function getRecordingsDir(projectDir: string): string {
return ensureDir(path.join(getProjectDir(projectDir), 'recordings'));
}

export function getRunLogsDir(projectDir: string): string {
const dir = ensureDir(path.join(getProjectDir(projectDir), 'run_logs'));
migrateLegacyRunLog(projectDir, dir);
Expand Down
6 changes: 6 additions & 0 deletions webviews/viewer/src/components/layout/TopToolbar.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script lang="ts">
import BoundingBoxButton from '../viewer/BoundingBoxButton.svelte';
import WireframeButton from '../viewer/WireframeButton.svelte';
import AutoRotateButton from '../viewer/AutoRotateButton.svelte';
import ScreenshotButton from '../viewer/ScreenshotButton.svelte';
import RecordButton from '../viewer/RecordButton.svelte';
</script>

<div
Expand All @@ -12,5 +14,9 @@
<div class="w-px bg-ui-border"></div>
<WireframeButton />
<div class="w-px bg-ui-border"></div>
<AutoRotateButton />
<div class="w-px bg-ui-border"></div>
<ScreenshotButton />
<div class="w-px bg-ui-border"></div>
<RecordButton />
</div>
41 changes: 39 additions & 2 deletions webviews/viewer/src/components/popups/HelpPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import ObjectIcon from '../../icons/ObjectIcon.svelte';
import MouseScrollIcon from '../../icons/MouseScrollIcon.svelte';
import ResetIcon from '../../icons/ResetIcon.svelte';
import AutoRotateIcon from '../../icons/AutoRotateIcon.svelte';
import RecordIcon from '../../icons/RecordIcon.svelte';
import ScreenshotIcon from '../../icons/ScreenshotIcon.svelte';
import VolumeIcon from '../../icons/VolumeIcon.svelte';
import WireframeIcon from '../../icons/WireframeIcon.svelte';
Expand Down Expand Up @@ -132,15 +134,50 @@
inspect mesh density</span
>

<span
class="inline-flex items-center justify-center size-6 rounded-sm bg-ui-muted border border-ui-border text-ui-text-secondary"
>
<AutoRotateIcon class="size-3.5" />
</span>
<span
><strong>Auto-rotate</strong> the view like a turntable.
<strong>Right click</strong> to open a popover with a speed slider and a
<strong>reverse direction</strong> toggle — changes there apply to the current session
only; set the remembered defaults in <em>Settings → Toolbar</em>.</span
>

<span
class="inline-flex items-center justify-center size-6 rounded-sm bg-ui-muted border border-ui-border text-ui-text-secondary stroke-[1.75]"
>
<ScreenshotIcon class="size-3.5" />
</span>
<span
><strong>Left click</strong> — save the 3D view as PNG next to your file &amp; copy to
clipboard. <strong>Right click</strong> — capture the full viewer including the sidebar.</span
><strong>Screenshot</strong> the 3D view as PNG (saved next to your mesh &amp; copied to
clipboard). <strong>Left click</strong> — canvas only. <strong>Right click</strong> —
menu with <em>Screenshot whole screen</em> to include the toolbar and sidebar.</span
>

<span
class="inline-flex items-center justify-center size-6 rounded-sm bg-ui-muted border border-ui-border text-ui-text-secondary stroke-[1.75]"
>
<RecordIcon class="size-3.5" />
</span>
<span
><strong>Record</strong> a video of the 3D view (mp4 when the webview's Chromium
supports h264, webm otherwise; saved to <code>.vs-code-aster/recordings/</code>). The
button pulses red with an elapsed timer while recording. <strong>Left click</strong> —
start / stop a canvas-only recording. <strong>Right click</strong> — menu with
<em>Record whole webview</em> (bakes the toolbar, sidebar, popups, and labels into the
video) or <em>Record without sidebar</em>. The whole-webview mode rasterizes the DOM on
every real UI change, which can briefly freeze the viewer on each update — expect short
hitches when you click a toolbar button or toggle a group during recording. Skip the
sidebar if you have hundreds of groups and the hitches feel too long.</span
>

<span class="col-span-2 text-ui-text-secondary pt-1">
Toolbar toggles (bounding box, wireframe, auto-rotate) affect only the current viewer —
persistent defaults live in <em>Settings → Toolbar</em>.
</span>
</div>
{:else if activeTab === 'Objects'}
<div class="grid grid-cols-[auto_1fr] gap-x-5 gap-y-3 items-center">
Expand Down
Loading
Loading