diff --git a/.vscodeignore b/.vscodeignore index c0171a1..18d3cc4 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -7,6 +7,11 @@ node_modules/** src/** .gitignore .yarnrc +.prettierignore +.husky/** +.mypy_cache/** +.ruff_cache/** +**/__pycache__/** esbuild.js vsc-extension-quickstart.md **/tsconfig.json @@ -14,10 +19,18 @@ vsc-extension-quickstart.md **/*.map **/*.ts **/.vscode-test.* +CITATION.cff +ROADMAP.md +pyproject.toml +tailwind.config.js .venv noxfile.py requirements.txt python/data +python/cmake/** +python/bundled/.gitkeep +python/requirements.txt +python/datamodel/test/** python/lsp/.venv python/.venv webviews/viewer/src/** diff --git a/CHANGELOG.md b/CHANGELOG.md index afe3605..51d2c36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ 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.2] - 2026-03-23 + +Various fixes and improvements. + +### Added +- Export form now auto-increments unit numbers to avoid duplicates when adding new files +- Files named `export` (without extension) are now detected as export files + +### Fixed +- Mesh viewer now correctly resolves .med file paths containing subdirectories (e.g. `Mesh/mesh.med`) relative to the .export file location ([#13](https://github.com/simvia-tech/vs-code-aster/issues/13)) +- Selecting text no longer resets manually hidden objects in the mesh viewer ([#14](https://github.com/simvia-tech/vs-code-aster/issues/14)) +- Fixed issues when two meshes share groups with the same name ([#15](https://github.com/simvia-tech/vs-code-aster/issues/15)) +- Fixed error in mesh viewer ([#16](https://github.com/simvia-tech/vs-code-aster/issues/16)) +- Reduced extension package size by excluding unnecessary files + ## [1.5.1] - 2026-03-16 Various fixes and optimizations. diff --git a/CITATION.cff b/CITATION.cff index 76cf02a..a5034a0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,4 +1,4 @@ -cff-version: 1.5.1 +cff-version: 1.5.2 title: VS Code Aster message: >- If you use this software, please cite it using the diff --git a/README.md b/README.md index 58fc2be..bbbfb6d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

Simvia Logo

- Version + Version License

diff --git a/ROADMAP.md b/ROADMAP.md index 44f5abe..f7ad02f 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -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.1) +## Current Capabilities (v1.5.2) - `.export` file generator - 3D mesh viewer diff --git a/package-lock.json b/package-lock.json index 618b7dd..3417108 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vs-code-aster", - "version": "1.5.1", + "version": "1.5.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vs-code-aster", - "version": "1.5.1", + "version": "1.5.2", "license": "GPL-3.0", "dependencies": { "@tailwindcss/cli": "^4.1.17", diff --git a/package.json b/package.json index c998a2a..d4f1f75 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vs-code-aster", "displayName": "VS Code Aster", - "version": "1.5.1", + "version": "1.5.2", "description": "VS Code extension for code_aster", "publisher": "simvia", "license": "GPL-3.0", diff --git a/src/VisuManager.ts b/src/VisuManager.ts index f0dd0aa..94a0cba 100644 --- a/src/VisuManager.ts +++ b/src/VisuManager.ts @@ -208,7 +208,7 @@ export function findMedFiles(commFilePath: string): string[] { try { const dir = path.dirname(commFilePath); const commFileName = path.basename(commFilePath); - const exportFiles = fs.readdirSync(dir).filter((f) => f.endsWith('.export')); + const exportFiles = fs.readdirSync(dir).filter((f) => f === 'export' || f.endsWith('.export')); if (exportFiles.length === 0) { vscode.window.showErrorMessage(`No .export file found in directory: ${dir}`); @@ -240,15 +240,15 @@ export function findMedFiles(commFilePath: string): string[] { continue; } + const medPath = path.isAbsolute(name) ? name : path.join(dir, name); const medFileName = path.basename(name); - const medPath = path.join(dir, medFileName); if (fs.existsSync(medPath)) { console.log(`[findMedFiles] found med file: ${medFileName}`); foundMedFiles.push(medPath); } else { vscode.window.showErrorMessage( - `The file "${medFileName}" mentioned in "${exportFile}" does not exist in the current directory (${path.basename(dir)}/).` + `The file "${name}" mentioned in "${exportFile}" does not exist.` ); } } diff --git a/src/WebviewVisu.ts b/src/WebviewVisu.ts index 46a32a0..4676bc8 100644 --- a/src/WebviewVisu.ts +++ b/src/WebviewVisu.ts @@ -189,6 +189,8 @@ export class WebviewVisu implements vscode.Disposable { // Parse the text to find object names // Object keys are like "all_mesh.obj"; match against the stem (no "all_" prefix, no extension) + // Only send showOnlyObjects when a mesh name is explicitly selected, to avoid + // resetting user-hidden meshes on every text selection change. const selectedObjects = this.objects?.filter((objectKey) => { const withoutPrefix = objectKey.startsWith('all_') ? objectKey.slice(4) : objectKey; @@ -196,10 +198,12 @@ export class WebviewVisu implements vscode.Disposable { return this.makeWholeTokenRegex(shortName).test(text); }) || []; - this.panel.webview.postMessage({ - type: 'showOnlyObjects', - body: { objects: selectedObjects }, - }); + if (selectedObjects.length > 0) { + this.panel.webview.postMessage({ + type: 'showOnlyObjects', + body: { objects: selectedObjects }, + }); + } } /** diff --git a/webviews/export/export.js b/webviews/export/export.js index 80a1953..c0c7e9f 100644 --- a/webviews/export/export.js +++ b/webviews/export/export.js @@ -30,6 +30,24 @@ const defaultUnits = { libr: '16', }; +function getNextAvailableUnit(defaultUnit) { + const usedUnits = new Set(); + for (const f of formData.inputFiles) { + usedUnits.add(String(f.unit)); + } + for (const f of formData.outputFiles) { + usedUnits.add(String(f.unit)); + } + let unit = Number(defaultUnit); + if (unit === 0) { + return String(unit); + } + while (usedUnits.has(String(unit))) { + unit++; + } + return String(unit); +} + const formData = { name: '', parameters: { @@ -179,14 +197,15 @@ function addFileRow(container, targetArray, fileObj) { inputName.value = fileObj.name; inputUnit.value = fileObj.unit; } else { - fileObj = { type: 'nom', name: '', unit: '0' }; + const unit = getNextAvailableUnit('0'); + fileObj = { type: 'nom', name: '', unit: unit }; inputName.placeholder = 'File Name : '; - inputUnit.value = '0'; + inputUnit.value = unit; } select.addEventListener('input', () => { fileObj.type = select.value.trim(); - const unit = defaultUnits[fileObj.type]; + const unit = getNextAvailableUnit(defaultUnits[fileObj.type]); inputUnit.value = unit; fileObj.unit = unit; }); diff --git a/webviews/viewer/src/lib/commands/VisibilityManager.ts b/webviews/viewer/src/lib/commands/VisibilityManager.ts index 39c0cb9..08b64c2 100644 --- a/webviews/viewer/src/lib/commands/VisibilityManager.ts +++ b/webviews/viewer/src/lib/commands/VisibilityManager.ts @@ -63,6 +63,11 @@ export class VisibilityManager { const wasHighlighted = this.highlightedGroupsSet.has(groupName); const isHighlighted = typeof visible === 'boolean' ? visible : !wasHighlighted; + // Don't highlight groups on hidden objects + if (isHighlighted && this.hiddenObjects[object]) { + return; + } + if (isHighlighted) { this.highlightedGroupsSet.add(groupName); highlightedGroups.update((map) => { diff --git a/webviews/viewer/src/lib/data/create/FaceActorCreator.ts b/webviews/viewer/src/lib/data/create/FaceActorCreator.ts index a8bca45..5cfb2c1 100644 --- a/webviews/viewer/src/lib/data/create/FaceActorCreator.ts +++ b/webviews/viewer/src/lib/data/create/FaceActorCreator.ts @@ -26,6 +26,10 @@ export class FaceActorCreator { const mapper = vtk.Rendering.Core.vtkMapper.newInstance(); mapper.setInputData(polyData); + if (!groupName.includes('all_')) { + mapper.setResolveCoincidentTopology(true); + mapper.setRelativeCoincidentTopologyPolygonOffsetParameters(-2, -2); + } actor.setMapper(mapper); const { colorIndex, isObjectActor } = this.setProperty(actor, groupName, cellCount);