🚀 Auto-deploy: BrainWind atualizado em 13/07/2026 18:05:59

This commit is contained in:
2026-07-13 18:05:59 +00:00
parent a4ad48b6b5
commit af49dc395d
5 changed files with 116 additions and 29 deletions
+22 -4
View File
@@ -23,6 +23,24 @@ const styles = StyleSheet.create({
sceneCaption: { fontSize: 8, color: '#666', fontStyle: 'italic', textAlign: 'center', marginBottom: 8 },
});
export function appendKgf(val: string | number): string {
if (typeof val === 'number') return String(val);
return val.replace(/(-?\d+(?:[.,]\d+)?)\s*(kN(?:\/m²|\/m2|\/m|·m|\.m|m)?)/g, (match, numStr, unit) => {
const num = parseFloat(numStr.replace(',', '.'));
if (isNaN(num)) return match;
const kgf = num * 101.9716;
let kgfUnit = 'kgf';
if (unit.includes('/m²') || unit.includes('/m2')) kgfUnit = 'kgf/m²';
else if (unit.includes('/m')) kgfUnit = 'kgf/m';
else if (unit.includes('·m') || unit.includes('.m') || unit === 'kNm') kgfUnit = 'kgf·m';
const kgfStr = kgf.toFixed(1);
const kgfFormatted = numStr.includes(',') ? kgfStr.replace('.', ',') : kgfStr;
return `${match} (${kgfFormatted} ${kgfUnit})`;
});
}
export interface GenericPDFSection {
title: string;
type: 'table' | 'text' | 'grid';
@@ -80,7 +98,7 @@ const GenericReportDocument = ({ moduleName, sections, wind, sceneImage }: Gener
q = 0,613 × (Vₖ)²
</Text>
<Text style={{ fontSize: 10, fontFamily: 'Courier', color: '#4b5563' }}>
q = 0,613 × ({wind.vk.toFixed(2)})² = {(0.613 * Math.pow(wind.vk, 2) / 1000).toFixed(4)} kN/m²
{appendKgf(`q = 0,613 × (${wind.vk.toFixed(2)})² = ${(0.613 * Math.pow(wind.vk, 2) / 1000).toFixed(4)} kN/m²`)}
</Text>
</View>
</View>
@@ -102,14 +120,14 @@ const GenericReportDocument = ({ moduleName, sections, wind, sceneImage }: Gener
</Text>
{sec.type === 'text' && sec.content && (
<Text style={styles.text}>{sec.content}</Text>
<Text style={styles.text}>{appendKgf(sec.content)}</Text>
)}
{sec.type === 'grid' && sec.gridItems && (
sec.gridItems.map((item, i) => (
<View style={styles.row} key={i}>
<Text style={styles.label}>{item.label}:</Text>
<Text style={styles.value}>{item.value}</Text>
<Text style={styles.value}>{appendKgf(item.value)}</Text>
</View>
))
)}
@@ -127,7 +145,7 @@ const GenericReportDocument = ({ moduleName, sections, wind, sceneImage }: Gener
<View style={styles.tableRow} key={rIdx}>
{tr.map((tc, cIdx) => (
<Text key={cIdx} style={cIdx === 0 ? styles.tableCellFirst : styles.tableCell}>
{tc}
{appendKgf(tc)}
</Text>
))}
</View>
+12 -11
View File
@@ -9,6 +9,7 @@ import {
getDragForce,
} from './line-loads';
import { getWallCpeOfficial, getRoofCpeOfficial } from './coefficients';
import { appendKgf } from './export-generic-pdf';
const styles = StyleSheet.create({
page: {
@@ -138,7 +139,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
q = 0,613 × (Vₖ)²
</Text>
<Text style={{ fontSize: 10, fontFamily: 'Courier', color: '#4b5563' }}>
q = 0,613 × ({wind.vk.toFixed(2)})² = {(0.613 * Math.pow(wind.vk, 2) / 1000).toFixed(4)} kN/m²
{appendKgf(`q = 0,613 × (${wind.vk.toFixed(2)})² = ${(0.613 * Math.pow(wind.vk, 2) / 1000).toFixed(4)} kN/m²`)}
</Text>
</View>
</View>
@@ -201,14 +202,14 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<Text style={styles.tableCellFirst}>Elemento / Região</Text>
<Text style={styles.tableCell}>Cpe</Text>
<Text style={styles.tableCell}>Cpi</Text>
<Text style={styles.tableCell}>p [kN/m²]</Text>
<Text style={styles.tableCell}>p [kN/m² (kgf/m²)]</Text>
</View>
{Object.entries(wCpe).map(([face, cpeVal]) => (
<View style={styles.tableRow} key={`wall-${face}`}>
<Text style={styles.tableCellFirst}>Parede {face}</Text>
<Text style={styles.tableCell}>{(cpeVal as number).toFixed(2)}</Text>
<Text style={styles.tableCell}>{cpi}</Text>
<Text style={styles.tableCell}>{pressure(cpeVal as number)}</Text>
<Text style={styles.tableCell}>{pressure(cpeVal as number)} ({(parseFloat(pressure(cpeVal as number)) * 101.9716).toFixed(1)})</Text>
</View>
))}
{Object.entries(rCpe).map(([face, cpeVal]) => (
@@ -216,7 +217,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<Text style={styles.tableCellFirst}>Telhado {face}</Text>
<Text style={styles.tableCell}>{(cpeVal as number).toFixed(2)}</Text>
<Text style={styles.tableCell}>{cpi}</Text>
<Text style={styles.tableCell}>{pressure(cpeVal as number)}</Text>
<Text style={styles.tableCell}>{pressure(cpeVal as number)} ({(parseFloat(pressure(cpeVal as number)) * 101.9716).toFixed(1)})</Text>
</View>
))}
</View>
@@ -224,7 +225,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<View style={styles.section}>
<Text style={styles.sectionTitle}>
{secBase + 1}. Cargas Lineares (kN/m)
{secBase + 1}. Cargas Lineares (kN/m (kgf/m))
</Text>
<Text style={{ fontSize: 9, marginBottom: 6 }}>
Pórticos: {FRAME_SPACING} m | Terças: {PURLIN_SPACING} m
@@ -234,7 +235,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<View style={[styles.tableRow, styles.tableHeader]}>
<Text style={styles.tableCellFirst}>Pilar</Text>
<Text style={styles.tableCell}>Cpe</Text>
<Text style={styles.tableCell}>w [kN/m]</Text>
<Text style={styles.tableCell}>w [kN/m (kgf/m)]</Text>
</View>
{([
['Barlavento', angle === 0 ? wCpe.C : wCpe.A, colLoads.windward],
@@ -245,7 +246,7 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<View style={styles.tableRow} key={`col-${label}`}>
<Text style={styles.tableCellFirst}>{label}</Text>
<Text style={styles.tableCell}>{cpeVal.toFixed(2)}</Text>
<Text style={styles.tableCell}>{fmtSigned(w)}</Text>
<Text style={styles.tableCell}>{fmtSigned(w)} ({fmtSigned(w * 101.9716, 1)})</Text>
</View>
))}
</View>
@@ -254,20 +255,20 @@ const ReportDocument = ({ galpao, wind, sceneImage }: ReportProps) => {
<View style={[styles.tableRow, styles.tableHeader]}>
<Text style={styles.tableCellFirst}>Terça (Zona)</Text>
<Text style={styles.tableCell}>Cpe</Text>
<Text style={styles.tableCell}>w [kN/m]</Text>
<Text style={styles.tableCell}>w [kN/m (kgf/m)]</Text>
</View>
{(['E', 'F', 'G', 'H', 'I', 'J'] as const).map((z) => (
<View style={styles.tableRow} key={`roof-${z}`}>
<Text style={styles.tableCellFirst}>{z}</Text>
<Text style={styles.tableCell}>{rCpe[z].toFixed(2)}</Text>
<Text style={styles.tableCell}>{fmtSigned(rLoads[z])}</Text>
<Text style={styles.tableCell}>{fmtSigned(rLoads[z])} ({fmtSigned(rLoads[z] * 101.9716, 1)})</Text>
</View>
))}
</View>
<View style={{ marginTop: 6, fontSize: 9 }}>
<Text>Reação global na base: <Text style={{ fontWeight: 'bold' }}>{fmtSigned(rxns.total, 3)} kN</Text></Text>
<Text>Força de arrasto global (Cₐ): <Text style={{ fontWeight: 'bold' }}>{dForce.forceKN.toFixed(3)} kN</Text></Text>
<Text>Reação global na base: <Text style={{ fontWeight: 'bold' }}>{fmtSigned(rxns.total, 3)} kN ({fmtSigned(rxns.total * 101.9716, 1)} kgf)</Text></Text>
<Text>Força de arrasto global (Cₐ): <Text style={{ fontWeight: 'bold' }}>{dForce.forceKN.toFixed(3)} kN ({(dForce.forceKN * 101.9716).toFixed(1)} kgf)</Text></Text>
</View>
</View>
</View>
+1
View File
@@ -58,6 +58,7 @@ const translations: Dict = {
nav_bar: { 'pt-BR': 'Barras', 'en-US': 'Bars' },
nav_bridge: { 'pt-BR': 'Pontes', 'en-US': 'Bridges' },
nav_tower: { 'pt-BR': 'Torres', 'en-US': 'Towers' },
nav_piperack: { 'pt-BR': 'Pipe-rack', 'en-US': 'Pipe-rack' },
nav_dynamics: { 'pt-BR': 'Dinâmica + Vórtices', 'en-US': 'Dynamics + Vortex' },
nav_settings: { 'pt-BR': 'Preferências', 'en-US': 'Preferences' },
nav_collapse: { 'pt-BR': 'Recolher sidebar', 'en-US': 'Collapse sidebar' },