From 5fc01b1b231f334ea7d94d00e6bde8fbb3e26a7b Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Tue, 7 Jul 2026 17:00:06 +0200 Subject: [PATCH 1/2] feat(attributes): Update attribute metadata to support vectorial attributes --- .../EdgedCurve/SpecificEdgesOptions.vue | 14 ++-- .../Viewer/Generic/Mesh/CellsOptions.vue | 14 ++-- .../Viewer/Generic/Mesh/PointsOptions.vue | 7 +- .../Viewer/Generic/Mesh/PolyhedraOptions.vue | 14 ++-- .../Viewer/Generic/Model/BlocksOptions.vue | 28 +++++--- .../Viewer/Generic/Model/CornersOptions.vue | 14 ++-- .../Viewer/Generic/Model/LinesOptions.vue | 28 +++++--- .../Viewer/Generic/Model/SurfacesOptions.vue | 28 +++++--- .../Viewer/Options/AttributeSelector.vue | 64 +++++++++++++++---- .../Viewer/Options/ColoringTypeSelector.vue | 32 +++++----- .../Viewer/PointSet/SpecificPointsOptions.vue | 7 +- .../Viewer/Solid/SpecificPolyhedraOptions.vue | 14 ++-- .../Viewer/Surface/PolygonsOptions.vue | 14 ++-- app/utils/default_styles/meshes.js | 9 +++ app/utils/default_styles/models.js | 7 ++ internal/stores/data_style/mesh/cells/cell.js | 12 +++- .../stores/data_style/mesh/cells/vertex.js | 12 +++- internal/stores/data_style/mesh/edges/edge.js | 12 +++- .../stores/data_style/mesh/edges/vertex.js | 12 +++- .../stores/data_style/mesh/points/vertex.js | 12 +++- .../data_style/mesh/polygons/polygon.js | 12 +++- .../stores/data_style/mesh/polygons/vertex.js | 12 +++- .../data_style/mesh/polyhedra/polyhedron.js | 12 +++- .../data_style/mesh/polyhedra/vertex.js | 12 +++- .../data_style/model/blocks/polyhedron.js | 12 +++- .../stores/data_style/model/blocks/vertex.js | 12 +++- .../stores/data_style/model/corners/vertex.js | 12 +++- .../stores/data_style/model/lines/edge.js | 12 +++- .../stores/data_style/model/lines/vertex.js | 12 +++- .../data_style/model/surfaces/polygon.js | 12 +++- .../data_style/model/surfaces/vertex.js | 12 +++- .../stores/data_style/mesh/cells.nuxt.test.js | 4 +- .../stores/data_style/mesh/edges.nuxt.test.js | 4 +- .../data_style/mesh/points.nuxt.test.js | 2 +- .../data_style/mesh/polygons.nuxt.test.js | 4 +- .../data_style/mesh/polyhedra.nuxt.test.js | 4 +- .../data_style/model/blocks.nuxt.test.js | 2 + .../data_style/model/corners.nuxt.test.js | 1 + .../data_style/model/lines.nuxt.test.js | 2 + .../data_style/model/surfaces.nuxt.test.js | 2 + 40 files changed, 373 insertions(+), 138 deletions(-) diff --git a/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue b/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue index dd1c1282..1bebe1e2 100644 --- a/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +++ b/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue @@ -56,10 +56,13 @@ const color = computed({ }, }); const vertex_attribute_name = computed({ - get: () => dataStyleStore.meshEdgesVertexAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshEdgesVertexAttributeName(id.value), + item: dataStyleStore.meshEdgesVertexAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshEdgesVertexAttributeName(targetId, newValue), + dataStyleStore.setMeshEdgesVertexAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, @@ -83,10 +86,13 @@ const vertex_attribute_color_map = computed({ }, }); const edge_attribute_name = computed({ - get: () => dataStyleStore.meshEdgesEdgeAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshEdgesEdgeAttributeName(id.value), + item: dataStyleStore.meshEdgesEdgeAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshEdgesEdgeAttributeName(targetId, newValue), + dataStyleStore.setMeshEdgesEdgeAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, diff --git a/app/components/Viewer/Generic/Mesh/CellsOptions.vue b/app/components/Viewer/Generic/Mesh/CellsOptions.vue index 6048f667..d58de3dc 100644 --- a/app/components/Viewer/Generic/Mesh/CellsOptions.vue +++ b/app/components/Viewer/Generic/Mesh/CellsOptions.vue @@ -56,10 +56,13 @@ const textures = computed({ }, }); const vertex_attribute_name = computed({ - get: () => dataStyleStore.meshCellsVertexAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshCellsVertexAttributeName(id.value), + item: dataStyleStore.meshCellsVertexAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshCellsVertexAttributeName(targetId, newValue), + dataStyleStore.setMeshCellsVertexAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, @@ -83,10 +86,13 @@ const vertex_attribute_color_map = computed({ }, }); const cell_attribute_name = computed({ - get: () => dataStyleStore.meshCellsCellAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshCellsCellAttributeName(id.value), + item: dataStyleStore.meshCellsCellAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshCellsCellAttributeName(targetId, newValue), + dataStyleStore.setMeshCellsCellAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, diff --git a/app/components/Viewer/Generic/Mesh/PointsOptions.vue b/app/components/Viewer/Generic/Mesh/PointsOptions.vue index 6e3d6f3b..83664b67 100644 --- a/app/components/Viewer/Generic/Mesh/PointsOptions.vue +++ b/app/components/Viewer/Generic/Mesh/PointsOptions.vue @@ -57,10 +57,13 @@ const color = computed({ }, }); const vertex_attribute_name = computed({ - get: () => dataStyleStore.meshPointsVertexAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshPointsVertexAttributeName(id.value), + item: dataStyleStore.meshPointsVertexAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshPointsVertexAttributeName(targetId, newValue), + dataStyleStore.setMeshPointsVertexAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, diff --git a/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue b/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue index dcfabc0b..a7b12164 100644 --- a/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +++ b/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue @@ -47,10 +47,13 @@ const color = computed({ }, }); const vertex_attribute_name = computed({ - get: () => dataStyleStore.meshPolyhedraVertexAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshPolyhedraVertexAttributeName(id.value), + item: dataStyleStore.meshPolyhedraVertexAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshPolyhedraVertexAttributeName(targetId, newValue), + dataStyleStore.setMeshPolyhedraVertexAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, @@ -74,10 +77,13 @@ const vertex_attribute_color_map = computed({ }, }); const polyhedron_attribute_name = computed({ - get: () => dataStyleStore.meshPolyhedraPolyhedronAttributeName(id.value), + get: () => ({ + name: dataStyleStore.meshPolyhedraPolyhedronAttributeName(id.value), + item: dataStyleStore.meshPolyhedraPolyhedronAttributeValue(id.value).item, + }), set: async (newValue) => { await applyBatchStyle(id.value, (targetId) => - dataStyleStore.setMeshPolyhedraPolyhedronAttributeName(targetId, newValue), + dataStyleStore.setMeshPolyhedraPolyhedronAttributeName(targetId, newValue.name, newValue.item), ); hybridViewerStore.remoteRender(); }, diff --git a/app/components/Viewer/Generic/Model/BlocksOptions.vue b/app/components/Viewer/Generic/Model/BlocksOptions.vue index 6e84c2cc..30c5e2b0 100644 --- a/app/components/Viewer/Generic/Model/BlocksOptions.vue +++ b/app/components/Viewer/Generic/Model/BlocksOptions.vue @@ -67,9 +67,12 @@ const blockActiveColoring = computed({ // Group Attributes const blocksVertexAttributeName = computed({ - get: () => dataStyleStore.modelBlocksVertexAttributeName(modelId, targetBlockIds[0]), + get: () => ({ + name: dataStyleStore.modelBlocksVertexAttributeName(modelId, targetBlockIds[0]), + item: dataStyleStore.modelBlocksVertexAttributeValue(modelId, targetBlockIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelBlocksVertexAttributeName(modelId, targetBlockIds, newValue); + await dataStyleStore.setModelBlocksVertexAttributeName(modelId, targetBlockIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -96,9 +99,12 @@ const blocksVertexAttributeColorMap = computed({ }); const blocksPolyhedronAttributeName = computed({ - get: () => dataStyleStore.modelBlocksPolyhedronAttributeName(modelId, targetBlockIds[0]), + get: () => ({ + name: dataStyleStore.modelBlocksPolyhedronAttributeName(modelId, targetBlockIds[0]), + item: dataStyleStore.modelBlocksPolyhedronAttributeValue(modelId, targetBlockIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelBlocksPolyhedronAttributeName(modelId, targetBlockIds, newValue); + await dataStyleStore.setModelBlocksPolyhedronAttributeName(modelId, targetBlockIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -130,9 +136,12 @@ const blocksPolyhedronAttributeColorMap = computed({ // Individual Attributes const vertexAttributeName = computed({ - get: () => dataStyleStore.modelBlocksVertexAttributeName(modelId, blockId), + get: () => ({ + name: dataStyleStore.modelBlocksVertexAttributeName(modelId, blockId), + item: dataStyleStore.modelBlocksVertexAttributeValue(modelId, blockId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelBlocksVertexAttributeName(modelId, [blockId], newValue); + await dataStyleStore.setModelBlocksVertexAttributeName(modelId, [blockId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -159,9 +168,12 @@ const vertexAttributeColorMap = computed({ }); const polyhedronAttributeName = computed({ - get: () => dataStyleStore.modelBlocksPolyhedronAttributeName(modelId, blockId), + get: () => ({ + name: dataStyleStore.modelBlocksPolyhedronAttributeName(modelId, blockId), + item: dataStyleStore.modelBlocksPolyhedronAttributeValue(modelId, blockId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelBlocksPolyhedronAttributeName(modelId, [blockId], newValue); + await dataStyleStore.setModelBlocksPolyhedronAttributeName(modelId, [blockId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); diff --git a/app/components/Viewer/Generic/Model/CornersOptions.vue b/app/components/Viewer/Generic/Model/CornersOptions.vue index f08688f0..2ca169a1 100644 --- a/app/components/Viewer/Generic/Model/CornersOptions.vue +++ b/app/components/Viewer/Generic/Model/CornersOptions.vue @@ -68,9 +68,12 @@ const cornerActiveColoring = computed({ // Group Attributes const cornersVertexAttributeName = computed({ - get: () => dataStyleStore.modelCornersVertexAttributeName(modelId, targetCornerIds[0]), + get: () => ({ + name: dataStyleStore.modelCornersVertexAttributeName(modelId, targetCornerIds[0]), + item: dataStyleStore.modelCornersVertexAttributeValue(modelId, targetCornerIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelCornersVertexAttributeName(modelId, targetCornerIds, newValue); + await dataStyleStore.setModelCornersVertexAttributeName(modelId, targetCornerIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -98,9 +101,12 @@ const cornersVertexAttributeColorMap = computed({ // Individual Attributes const vertexAttributeName = computed({ - get: () => dataStyleStore.modelCornersVertexAttributeName(modelId, cornerId), + get: () => ({ + name: dataStyleStore.modelCornersVertexAttributeName(modelId, cornerId), + item: dataStyleStore.modelCornersVertexAttributeValue(modelId, cornerId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelCornersVertexAttributeName(modelId, [cornerId], newValue); + await dataStyleStore.setModelCornersVertexAttributeName(modelId, [cornerId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); diff --git a/app/components/Viewer/Generic/Model/LinesOptions.vue b/app/components/Viewer/Generic/Model/LinesOptions.vue index 6c0e7f47..986f72db 100644 --- a/app/components/Viewer/Generic/Model/LinesOptions.vue +++ b/app/components/Viewer/Generic/Model/LinesOptions.vue @@ -67,9 +67,12 @@ const lineActiveColoring = computed({ // Group Attributes const linesVertexAttributeName = computed({ - get: () => dataStyleStore.modelLinesVertexAttributeName(modelId, targetLineIds[0]), + get: () => ({ + name: dataStyleStore.modelLinesVertexAttributeName(modelId, targetLineIds[0]), + item: dataStyleStore.modelLinesVertexAttributeValue(modelId, targetLineIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelLinesVertexAttributeName(modelId, targetLineIds, newValue); + await dataStyleStore.setModelLinesVertexAttributeName(modelId, targetLineIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -96,9 +99,12 @@ const linesVertexAttributeColorMap = computed({ }); const linesEdgeAttributeName = computed({ - get: () => dataStyleStore.modelLinesEdgeAttributeName(modelId, targetLineIds[0]), + get: () => ({ + name: dataStyleStore.modelLinesEdgeAttributeName(modelId, targetLineIds[0]), + item: dataStyleStore.modelLinesEdgeAttributeValue(modelId, targetLineIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelLinesEdgeAttributeName(modelId, targetLineIds, newValue); + await dataStyleStore.setModelLinesEdgeAttributeName(modelId, targetLineIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -126,9 +132,12 @@ const linesEdgeAttributeColorMap = computed({ // Individual Attributes const vertexAttributeName = computed({ - get: () => dataStyleStore.modelLinesVertexAttributeName(modelId, lineId), + get: () => ({ + name: dataStyleStore.modelLinesVertexAttributeName(modelId, lineId), + item: dataStyleStore.modelLinesVertexAttributeValue(modelId, lineId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelLinesVertexAttributeName(modelId, [lineId], newValue); + await dataStyleStore.setModelLinesVertexAttributeName(modelId, [lineId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -155,9 +164,12 @@ const vertexAttributeColorMap = computed({ }); const edgeAttributeName = computed({ - get: () => dataStyleStore.modelLinesEdgeAttributeName(modelId, lineId), + get: () => ({ + name: dataStyleStore.modelLinesEdgeAttributeName(modelId, lineId), + item: dataStyleStore.modelLinesEdgeAttributeValue(modelId, lineId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelLinesEdgeAttributeName(modelId, [lineId], newValue); + await dataStyleStore.setModelLinesEdgeAttributeName(modelId, [lineId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); diff --git a/app/components/Viewer/Generic/Model/SurfacesOptions.vue b/app/components/Viewer/Generic/Model/SurfacesOptions.vue index b282ad24..11b72dfd 100644 --- a/app/components/Viewer/Generic/Model/SurfacesOptions.vue +++ b/app/components/Viewer/Generic/Model/SurfacesOptions.vue @@ -67,9 +67,12 @@ const surfaceActiveColoring = computed({ // Group Attributes const surfacesVertexAttributeName = computed({ - get: () => dataStyleStore.modelSurfacesVertexAttributeName(modelId, targetSurfaceIds[0]), + get: () => ({ + name: dataStyleStore.modelSurfacesVertexAttributeName(modelId, targetSurfaceIds[0]), + item: dataStyleStore.modelSurfacesVertexAttributeValue(modelId, targetSurfaceIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelSurfacesVertexAttributeName(modelId, targetSurfaceIds, newValue); + await dataStyleStore.setModelSurfacesVertexAttributeName(modelId, targetSurfaceIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -100,9 +103,12 @@ const surfacesVertexAttributeColorMap = computed({ }); const surfacesPolygonAttributeName = computed({ - get: () => dataStyleStore.modelSurfacesPolygonAttributeName(modelId, targetSurfaceIds[0]), + get: () => ({ + name: dataStyleStore.modelSurfacesPolygonAttributeName(modelId, targetSurfaceIds[0]), + item: dataStyleStore.modelSurfacesPolygonAttributeValue(modelId, targetSurfaceIds[0]).item, + }), set: async (newValue) => { - await dataStyleStore.setModelSurfacesPolygonAttributeName(modelId, targetSurfaceIds, newValue); + await dataStyleStore.setModelSurfacesPolygonAttributeName(modelId, targetSurfaceIds, newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -134,9 +140,12 @@ const surfacesPolygonAttributeColorMap = computed({ // Individual Attributes const vertexAttributeName = computed({ - get: () => dataStyleStore.modelSurfacesVertexAttributeName(modelId, surfaceId), + get: () => ({ + name: dataStyleStore.modelSurfacesVertexAttributeName(modelId, surfaceId), + item: dataStyleStore.modelSurfacesVertexAttributeValue(modelId, surfaceId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelSurfacesVertexAttributeName(modelId, [surfaceId], newValue); + await dataStyleStore.setModelSurfacesVertexAttributeName(modelId, [surfaceId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); @@ -163,9 +172,12 @@ const vertexAttributeColorMap = computed({ }); const polygonAttributeName = computed({ - get: () => dataStyleStore.modelSurfacesPolygonAttributeName(modelId, surfaceId), + get: () => ({ + name: dataStyleStore.modelSurfacesPolygonAttributeName(modelId, surfaceId), + item: dataStyleStore.modelSurfacesPolygonAttributeValue(modelId, surfaceId).item, + }), set: async (newValue) => { - await dataStyleStore.setModelSurfacesPolygonAttributeName(modelId, [surfaceId], newValue); + await dataStyleStore.setModelSurfacesPolygonAttributeName(modelId, [surfaceId], newValue.name, newValue.item); hybridViewerStore.remoteRender(); }, }); diff --git a/app/components/Viewer/Options/AttributeSelector.vue b/app/components/Viewer/Options/AttributeSelector.vue index 62e8a35d..e01b1b5f 100644 --- a/app/components/Viewer/Options/AttributeSelector.vue +++ b/app/components/Viewer/Options/AttributeSelector.vue @@ -4,10 +4,9 @@ import { useBackStore } from "@ogw_front/stores/back"; const backStore = useBackStore(); -const name = defineModel("name", { - type: String, +const attribute = defineModel("attribute", { + type: Object, default: undefined, - set: (value) => value ?? name.value, }); const range = defineModel("range", { type: Array }); @@ -44,18 +43,46 @@ const rangeMax = computed({ }, }); +const selectedAttributeName = computed({ + get: () => (attribute.value ? attribute.value.name : undefined), + set: (val) => { + attribute.value = { name: val, item: 0 }; + }, +}); + +const selectedComponent = computed({ + get: () => (attribute.value ? attribute.value.item : 0), + set: (val) => { + attribute.value = { name: selectedAttributeName.value, item: val }; + }, +}); + +const componentItems = computed(() => { + if (!currentAttribute.value) { + return []; + } + return Array.from({ length: currentAttribute.value.nb_items }, (_, index) => ({ + title: `Component ${index}`, + value: index, + })); +}); + const currentAttribute = computed(() => - attributes.value.find((attr) => attr.attribute_name === name.value), + attributes.value.find((attr) => attr.attribute_name === selectedAttributeName.value), ); function resetRange() { if (currentAttribute.value) { - range.value = [currentAttribute.value.min_value, currentAttribute.value.max_value]; + const comp = attribute.value ? attribute.value.item : 0; + range.value = [ + currentAttribute.value.min_values[comp], + currentAttribute.value.max_values[comp], + ]; } } function getAttributes() { - if (schema.properties?.component_id && componentId === undefined) { + if (schema.properties.component_id && componentId === undefined) { return; } const params = { id }; @@ -84,10 +111,10 @@ watch( ); watch( - () => [name.value, attributes.value], + () => [selectedAttributeName.value, attributes.value], () => { if ( - name.value && + selectedAttributeName.value && attributes.value.length > 0 && (range.value === undefined || range.value[0] === undefined || colorMap.value === undefined) ) { @@ -99,17 +126,15 @@ watch( }, ); -watch(name, (newName, oldName) => { - if (newName !== oldName) { - resetRange(); - } +watch([selectedAttributeName, selectedComponent], () => { + resetRange(); });