download
raw
8.85 kB
import { useState, useEffect, useRef } from 'react';
import { poissonApi } from '../../api';
import PoissonForm from './PoissonForm';
import MeshViewer3D from './MeshViewer3D';
import SolutionViewer from './SolutionViewer';
import AnimationPlayer from './AnimationPlayer';
import SimulationHistory from './SimulationHistory';
import '../../styles/poisson.css';
export default function PoissonApp({ onBack }) {
const [simulations, setSimulations] = useState([]);
const [selectedSimulation, setSelectedSimulation] = useState(null);
const [loading, setLoading] = useState(false);
const [viewMode, setViewMode] = useState('mesh'); // 'mesh', 'solution', 'animation'
const [meshPreview, setMeshPreview] = useState(null);
// Charger les simulations existantes
useEffect(() => {
loadSimulations();
}, []);
const loadSimulations = async () => {
try {
const data = await poissonApi.getSimulations();
setSimulations(data);
} catch (err) {
console.error('Erreur chargement simulations:', err);
}
};
const handlePreviewMesh = async (params) => {
try {
const preview = await poissonApi.previewMesh(params);
setMeshPreview(preview);
setViewMode('mesh');
} catch (err) {
console.error('Erreur preview:', err);
}
};
const handleSimulationCreated = async (simulation) => {
setSelectedSimulation(simulation);
setMeshPreview(null);
setViewMode('solution');
await loadSimulations();
};
const handleSelectSimulation = async (sim) => {
setLoading(true);
try {
const full = await poissonApi.getSimulation(sim.id);
setSelectedSimulation(full);
setMeshPreview(null);
setViewMode('solution');
} catch (err) {
console.error('Erreur:', err);
}
setLoading(false);
};
const handleDeleteSimulation = async (id) => {
try {
await poissonApi.deleteSimulation(id);
if (selectedSimulation?.id === id) {
setSelectedSimulation(null);
}
await loadSimulations();
} catch (err) {
console.error('Erreur suppression:', err);
}
};
const getCurrentMeshData = () => {
if (meshPreview) return meshPreview;
if (selectedSimulation?.mesh_data) return selectedSimulation.mesh_data;
return null;
};
const getCurrentSolutionData = () => {
console.log('getCurrentSolutionData called');
console.log('selectedSimulation:', selectedSimulation);
console.log('result_data:', selectedSimulation?.result_data);
console.log('mesh_data:', selectedSimulation?.mesh_data);
if (selectedSimulation?.result_data) {
const data = {
mesh: selectedSimulation.mesh_data,
solution: selectedSimulation.result_data,
};
console.log('Returning solution data:', data);
return data;
}
console.log('No result_data, returning null');
return null;
};
return (
<div className="poisson-app">
<header className="poisson-header">
<button className="back-btn" onClick={onBack}>← Retour</button>
<h1>Simulation de l'Équation de Poisson</h1>
<p className="subtitle">-Δu = f avec conditions aux limites</p>
</header>
<main className="poisson-main">
{/* Panneau de contrôle */}
<aside className="control-panel">
<PoissonForm
onPreviewMesh={handlePreviewMesh}
onSimulationCreated={handleSimulationCreated}
loading={loading}
setLoading={setLoading}
/>
<SimulationHistory
simulations={simulations}
selectedId={selectedSimulation?.id}
onSelect={handleSelectSimulation}
onDelete={handleDeleteSimulation}
/>
</aside>
{/* Zone de visualisation */}
<section className="visualization-panel">
{/* Onglets de visualisation */}
<div className="view-tabs">
<button
className={`tab ${viewMode === 'mesh' ? 'active' : ''}`}
onClick={() => setViewMode('mesh')}
>
Maillage 3D
</button>
<button
className={`tab ${viewMode === 'solution' ? 'active' : ''}`}
onClick={() => setViewMode('solution')}
disabled={!selectedSimulation?.result_data}
>
Solution
</button>
<button
className={`tab ${viewMode === 'animation' ? 'active' : ''}`}
onClick={() => setViewMode('animation')}
disabled={!selectedSimulation?.animation_frames}
>
Animation
</button>
</div>
{/* Conteneur de visualisation */}
<div className="viewer-container">
{loading && (
<div className="loading-overlay">
<div className="spinner"></div>
<p>Calcul en cours...</p>
</div>
)}
{viewMode === 'mesh' && getCurrentMeshData() && (
<MeshViewer3D meshData={getCurrentMeshData()} />
)}
{viewMode === 'solution' && getCurrentSolutionData() && (
<SolutionViewer data={getCurrentSolutionData()} />
)}
{viewMode === 'animation' && selectedSimulation?.animation_frames && (
<AnimationPlayer
meshData={selectedSimulation.mesh_data}
frames={selectedSimulation.animation_frames}
solutionRange={{
min: selectedSimulation.solution_min,
max: selectedSimulation.solution_max,
}}
/>
)}
{!getCurrentMeshData() && !loading && (
<div className="placeholder">
<p>Configurez les paramètres et cliquez sur</p>
<p><strong>"Aperçu du maillage"</strong> ou <strong>"Lancer la simulation"</strong></p>
</div>
)}
</div>
{/* Statistiques */}
{selectedSimulation?.status === 'completed' && (
<div className="stats-bar">
<div className="stat">
<span className="label">Min</span>
<span className="value">{selectedSimulation.solution_min?.toFixed(6)}</span>
</div>
<div className="stat">
<span className="label">Max</span>
<span className="value">{selectedSimulation.solution_max?.toFixed(6)}</span>
</div>
<div className="stat">
<span className="label">Temps</span>
<span className="value">{selectedSimulation.computation_time?.toFixed(3)}s</span>
</div>
<div className="stat">
<span className="label">DDL</span>
<span className="value">{selectedSimulation.mesh_data?.num_vertices}</span>
</div>
</div>
)}
</section>
</main>
</div>
);
}

Xet Storage Details

Size:
8.85 kB
·
Xet hash:
4931c2cf69894ad1510a8b38c212e0cf983b71c6f2d17999847eaeed61bb502d

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.