Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ yarn.lock
vsc-extension-quickstart.md

**/__pycache__/
.mypy_cache/
.ruff_cache/

# Fichiers temporaires ou backup
*.tmp
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ 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.5.1] - 2026-03-16

Various fixes and optimizations.

### Added
- Selecting object names in text editors hides all other objects (hence highlighting selected object)
- Progress bar for mesh loading

### Fixed
- Text selection now highlights groups again
- Group sorting order now handles alphanumerical sorting

## [1.5.0] - 2026-03-13

Rewrote the mesh viewer UI with Svelte, and added new viewer features.
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.5.0
cff-version: 1.5.1
title: VS Code Aster
message: >-
If you use this software, please cite it using the
Expand Down
2 changes: 1 addition & 1 deletion 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.5.0-blue" alt="Version" /></a>
<a href="/"><img src="https://img.shields.io/badge/version-1.5.1-blue" alt="Version" /></a>
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-GPL%203.0-green" alt="License" /></a>
</p>

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.5.0)
## Current Capabilities (v1.5.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.

2 changes: 1 addition & 1 deletion 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.5.0",
"version": "1.5.1",
"description": "VS Code extension for code_aster",
"publisher": "simvia",
"license": "GPL-3.0",
Expand Down
41 changes: 31 additions & 10 deletions src/WebviewVisu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export class WebviewVisu implements vscode.Disposable {
public readonly panel: vscode.WebviewPanel;

private groups?: string[];
private objects?: string[];
private selectedGroups: string[];

public get webview(): vscode.Webview {
Expand Down Expand Up @@ -120,6 +121,7 @@ export class WebviewVisu implements vscode.Disposable {
let groupList = e.groupList;
console.log('Group list : ', groupList);
this.groups = groupList;
this.objects = e.objectList;
this.panel.webview.postMessage({
type: 'addGroupButtons',
body: { groupList },
Expand All @@ -144,6 +146,11 @@ export class WebviewVisu implements vscode.Disposable {
* Groups present in the text will be displayed; others will be hidden.
* @param text The text to check for group names.
*/
private makeWholeTokenRegex(name: string): RegExp {
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return new RegExp(`(?<![a-zA-Z0-9_-])${escaped}(?![a-zA-Z0-9_-])`);
}

public showGroupsFromTextSelection(text: string) {
if (!this.panel) {
return;
Expand All @@ -153,15 +160,13 @@ export class WebviewVisu implements vscode.Disposable {
// Group keys are like "all_mesh.obj::SURFACE_1::type"; match against the short name only
const readGroups =
this.groups?.filter((groupName) => {
const shortName = groupName.includes('::') ? groupName.split('::')[2]! : groupName;
const regex = new RegExp(`\\b${shortName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`);
return regex.test(text);
const shortName = groupName.includes('::') ? groupName.split('::')[1]! : groupName;
return this.makeWholeTokenRegex(shortName).test(text);
}) || [];

// Hide groups that are no longer in the text
this.selectedGroups = this.selectedGroups.filter((oldGroup) => {
if (!readGroups.includes(oldGroup)) {
console.log('Hide group:', oldGroup);
this.panel.webview.postMessage({
type: 'displayGroup',
body: { group: oldGroup, visible: false },
Expand All @@ -174,14 +179,27 @@ export class WebviewVisu implements vscode.Disposable {
// Show groups that are new to the text
readGroups.forEach((group) => {
if (!this.selectedGroups.includes(group)) {
console.log('Display group:', group);
this.panel.webview.postMessage({
type: 'displayGroup',
body: { group, visible: true },
});
this.selectedGroups.push(group);
}
});

// Parse the text to find object names
// Object keys are like "all_mesh.obj"; match against the stem (no "all_" prefix, no extension)
const selectedObjects =
this.objects?.filter((objectKey) => {
const withoutPrefix = objectKey.startsWith('all_') ? objectKey.slice(4) : objectKey;
const shortName = withoutPrefix.replace(/\.[^.]+$/, '');
return this.makeWholeTokenRegex(shortName).test(text);
}) || [];

this.panel.webview.postMessage({
type: 'showOnlyObjects',
body: { objects: selectedObjects },
});
}

/**
Expand All @@ -206,11 +224,14 @@ export class WebviewVisu implements vscode.Disposable {
const htmlDir = path.dirname(htmlFilePath);

// Replace relative paths (href/src/img) with valid URIs for the webview
html = html.replace(/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g, (match, p1, p2) => {
const resourceFullPath = path.join(htmlDir, p2);
const uri = panel.webview.asWebviewUri(vscode.Uri.file(resourceFullPath));
return `${p1}${uri.toString()}"`;
});
html = html.replace(
/(<link.+?href="|<script.+?src="|<img.+?src=")(.+?)"/g,
(_match, p1, p2) => {
const resourceFullPath = path.join(htmlDir, p2);
const uri = panel.webview.asWebviewUri(vscode.Uri.file(resourceFullPath));
return `${p1}${uri.toString()}"`;
}
);

html = html.replace(/\${webview.cspSource}/g, panel.webview.cspSource);

Expand Down
10 changes: 0 additions & 10 deletions webviews/viewer/src/components/LoadingScreen.svelte

This file was deleted.

62 changes: 0 additions & 62 deletions webviews/viewer/src/components/ZoomWidget.svelte

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { groupHierarchy } from '../lib/state';
import { groupHierarchy } from '../../lib/state';
import Sidebar from './Sidebar.svelte';
import TopActions from './TopActions.svelte';
import ZoomWidget from './ZoomWidget.svelte';
import Popup from './popups/Popup.svelte';
import HelpPopup from './popups/HelpPopup.svelte';
import SettingsPopup from './popups/SettingsPopup.svelte';
import GroupsPopup from './popups/GroupsPopup.svelte';
import ZoomWidget from '../viewer/ZoomWidget.svelte';
import Popup from '../popups/Popup.svelte';
import HelpPopup from '../popups/HelpPopup.svelte';
import SettingsPopup from '../popups/SettingsPopup.svelte';
import GroupsPopup from '../popups/GroupsPopup.svelte';
import LoadingScreen from './LoadingScreen.svelte';

type PopupType = 'help' | 'settings' | 'groups' | null;
Expand Down
15 changes: 15 additions & 0 deletions webviews/viewer/src/components/layout/LoadingScreen.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import { loadingProgress, loadingMessage } from '../../lib/state';
</script>

<div
class="fixed inset-0 flex flex-col items-center justify-center gap-3 pointer-events-none text-ui-text-secondary"
>
<div class="h-0.5 w-48 overflow-hidden rounded-full bg-ui-text-muted/20">
<div
class="h-full rounded-full bg-ui-text-muted"
style="width: {$loadingProgress * 100}%"
></div>
</div>
<span class="text-xs">{$loadingMessage || 'Loading...'}</span>
</div>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import { onMount } from 'svelte';
import { groupHierarchy } from '../lib/state';
import { VtkApp } from '../lib/core/VtkApp';
import ObjectSection from './ObjectSection.svelte';
import ActionButtons from './ActionButtons.svelte';
import AxisButtons from './AxisButtons.svelte';
import { groupHierarchy } from '../../lib/state';
import { VtkApp } from '../../lib/core/VtkApp';
import ObjectSection from '../sidebar/ObjectSection.svelte';
import ActionButtons from '../sidebar/ActionButtons.svelte';
import AxisButtons from '../viewer/AxisButtons.svelte';

let { onOpenGroups }: { onOpenGroups: () => void } = $props();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import SettingsIcon from '../icons/SettingsIcon.svelte';
import QuestionIcon from '../icons/QuestionIcon.svelte';
import SettingsIcon from '../../icons/SettingsIcon.svelte';
import QuestionIcon from '../../icons/QuestionIcon.svelte';

let {
onOpenSettings,
Expand Down
24 changes: 6 additions & 18 deletions webviews/viewer/src/components/popups/GroupsPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import FaceIcon from '../../icons/FaceIcon.svelte';
import NodeIcon from '../../icons/NodeIcon.svelte';
import ObjectIcon from '../../icons/ObjectIcon.svelte';
import Toggle from '../ui/Toggle.svelte';

let { onclose }: { onclose: () => void } = $props();

Expand Down Expand Up @@ -107,25 +108,12 @@
>{group.name}</span
>

<button
role="switch"
aria-label="Show orientation widget"
aria-checked={isVisible(obj.key, group.name)}
class="relative inline-flex h-3 w-6 shrink-0 rounded-full transition-colors duration-150 focus:outline-none cursor-pointer {isVisible(
obj.key,
group.name
)
? 'bg-ui-link'
: 'bg-ui-border'}"
<Toggle
checked={isVisible(obj.key, group.name)}
onclick={() => toggleGroup(obj.key, group.name)}
>
<span
class="inline-block h-1.5 w-1.5 rounded-full bg-white shadow-sm transition-transform duration-150 mt-0.75"
style={isVisible(obj.key, group.name)
? 'transform: translateX(15px)'
: 'transform: translateX(3px)'}
></span>
</button>
ariaLabel="Toggle group visibility"
size="sm"
/>
</label>
{/each}
</div>
Expand Down
Loading
Loading