| """ |
| Gerador de Memorial Descritivo - PSCIP NT-01/2025 CBMGO |
| Gera texto estruturado do memorial com todos os sistemas exigidos. |
| Com LLM (cbmgo/memorial-generator) ou template local (fallback). |
| """ |
| import os |
| import re |
| from datetime import datetime |
| from typing import Dict, List |
|
|
| try: |
| from transformers import pipeline |
| HAS_TRANSFORMERS = True |
| except ImportError: |
| HAS_TRANSFORMERS = False |
|
|
|
|
| class MemorialGenerator: |
| """ |
| Gerador de memorial descritivo para projetos PSCIP. |
| Usa LLM fine-tunado ou template estruturado como fallback. |
| """ |
|
|
| def __init__(self, model_id="cbmgo/memorial-generator", use_llm=False): |
| self.model_id = model_id |
| self.use_llm = use_llm and HAS_TRANSFORMERS |
| self._pipe = None |
|
|
| def _load_llm(self): |
| if self._pipe is None and self.use_llm: |
| print(f"Carregando modelo: {self.model_id}") |
| self._pipe = pipeline("text-generation", model=self.model_id, |
| device_map="auto", max_new_tokens=1500, temperature=0.2) |
|
|
| def gerar_llm(self, dados: Dict) -> str: |
| self._load_llm() |
| prompt = self._montar_prompt_llm(dados) |
| saida = self._pipe(prompt)[0]["generated_text"] |
| |
| if "MEMORIAL DESCRITIVO" in saida: |
| idx = saida.find("MEMORIAL DESCRITIVO") |
| return saida[idx:] |
| return saida |
|
|
| def _montar_prompt_llm(self, d: Dict) -> str: |
| exig = ", ".join(d.get("exigencias", [])) |
| return f"""Gere memorial descritivo completo de prevencao de incendio: |
| |
| Edificacao: {d.get("nome_edificacao","Edificio")} |
| Uso/Ocupacao: {d.get("ocupacao","comercial")} |
| Grupo NT-01: {d.get("grupo","D")} | Divisao: {d.get("divisao","D-1")} |
| Area total: {d.get("area_m2",0):.1f} m2 |
| Altura: {d.get("altura_m",0):.1f} m |
| Numero de pavimentos: {d.get("pavimentos",1)} |
| Lotacao estimada: {d.get("lotacao",50)} pessoas |
| Sistemas exigidos: {exig} |
| |
| MEMORIAL DESCRITIVO - PSCIP:""" |
|
|
| def gerar_template(self, dados: Dict) -> str: |
| """Gera memorial usando template estruturado (sem LLM).""" |
| d = dados |
| nome = d.get("nome_edificacao", "Edificacao") |
| ocupacao = d.get("ocupacao", "Comercial").title() |
| grupo = d.get("grupo", "D") |
| divisao = d.get("divisao", "D-1") |
| area = d.get("area_m2", 0) |
| altura = d.get("altura_m", 0) |
| pavimentos = d.get("pavimentos", 1) |
| lotacao = d.get("lotacao", 0) |
| exigencias = d.get("exigencias", []) |
| qtd_ext = d.get("qtd_extintores", max(1, int(area / 400))) |
| cap_ext = d.get("capacidade_extintor", "2-A:20-B:C") |
| sist_hid = d.get("sistema_hidrante", "Coluna Seca") |
| vazao = d.get("vazao_lpm", 300) |
| reserva = d.get("reserva_m3", round(vazao * 60 / 1000, 1)) |
| rt_nome = d.get("rt_nome", "___________________________") |
| rt_crea = d.get("rt_crea", "_______________") |
| data_hoje = datetime.now().strftime("%d/%m/%Y") |
|
|
| |
| sec_ilum = "" |
| if "iluminacao_emergencia" in exigencias: |
| sec_ilum = f""" |
| 6. ILUMINACAO DE EMERGENCIA |
| Sistema de iluminacao de emergencia instalado nas rotas de fuga, |
| saidas de emergencia e areas criticas. |
| - Autonomia minima: 1 (uma) hora |
| - Nivel de iluminamento rota de fuga: >= 3 lux |
| - Nivel de iluminamento areas de acesso: >= 10 lux |
| - Blocos autonomos com bateria selada, recarregavel |
| - Conforme ABNT NBR 10898 |
| Ref: NT-01/2025 CBMGO Art. 20 |
| """ |
|
|
| sec_spda = "" |
| if "spda" in exigencias: |
| sec_spda = f""" |
| 7. SPDA - SISTEMA DE PROTECAO CONTRA DESCARGAS ATMOSFERICAS |
| SPDA obrigatorio para esta edificacao (area > 1.000m2). |
| - Nivel de protecao: a definir conforme ABNT NBR 5419 |
| - Sistema captacao, descida e aterramento independente |
| - Projeto especifico assinado por profissional habilitado |
| Ref: NT-01/2025 CBMGO Art. 25 | ABNT NBR 5419 |
| """ |
|
|
| sec_alarme = "" |
| if "alarme_incendio" in exigencias: |
| sec_alarme = f""" |
| 8. SISTEMA DE ALARME E DETECCAO DE INCENDIO |
| Sistema de alarme de incendio com: |
| - Central de alarme endereçavel |
| - Acionadores manuais nas saidas de emergencia (espacamento <= 30m) |
| - Detectores de fumaca nos ambientes cobertos |
| - Sirenes audiovisuais |
| Conforme ABNT NBR 17240 |
| Ref: NT-01/2025 CBMGO Art. 22 |
| """ |
|
|
| sec_chuveiros = "" |
| if "chuveiros_automaticos" in exigencias: |
| sec_chuveiros = f""" |
| 9. SISTEMA DE CHUVEIROS AUTOMATICOS (SPRINKLERS) |
| Sistema de chuveiros automaticos cobrindo toda a area edificada. |
| - Tipo: Resposta rapida, temperatura de ativacao 68 graus C |
| - Densidade minima: 5 mm/min |
| - Area de atuacao: 144 m2 |
| - Reservatorio exclusivo para incendio |
| Conforme ABNT NBR 10897 |
| Ref: NT-01/2025 CBMGO |
| """ |
|
|
| memorial = f"""MEMORIAL DESCRITIVO |
| SISTEMA DE PREVENCAO E COMBATE A INCENDIO E PANICO - PSCIP |
| |
| Data de elaboracao: {data_hoje} |
| Referencia normativa principal: NT-01/2025 - Procedimentos Administrativos CBMGO |
| |
| ============================================================ |
| 1. IDENTIFICACAO DA EDIFICACAO |
| ============================================================ |
| Denominacao: {nome} |
| Uso/Ocupacao: {ocupacao} |
| Classificacao NT-01/2025: Grupo {grupo} - Divisao {divisao} |
| Endereco: _______________________________________________ |
| Area total construida: {area:.2f} m2 |
| Altura da edificacao: {altura:.2f} m |
| Numero de pavimentos: {pavimentos} |
| Lotacao maxima estimada: {lotacao} pessoas |
| |
| ============================================================ |
| 2. BASE LEGAL E NORMATIVA |
| ============================================================ |
| - NT-01/2025 - Procedimentos Administrativos - CBMGO |
| - ABNT NBR 12693:2013 - Sistemas de protecao por extintores |
| - ABNT NBR 13714:2003 - Sistemas de hidrantes e mangotinhos |
| - ABNT NBR 13434:2004 - Sinalizacao de seguranca contra incendio |
| - ABNT NBR 10898:2013 - Iluminacao de emergencia |
| - ABNT NBR 5419:2015 - SPDA |
| - ABNT NBR 17240:2010 - Deteccao e alarme de incendio |
| - ABNT NBR 9077:2001 - Saidas de emergencia |
| - Codigo de Obras e Postura Municipal vigente |
| |
| ============================================================ |
| 3. SISTEMAS DE PROTECAO EXIGIDOS |
| ============================================================ |
| Conforme classificacao Grupo {grupo} - NT-01/2025, para edificacao |
| com area de {area:.0f} m2 e altura de {altura:.1f} m, sao exigidos os |
| seguintes sistemas de protecao: |
| {chr(10).join([' - ' + e.replace('_',' ').title() for e in exigencias])} |
| |
| ============================================================ |
| 4. EXTINTORES PORTATEIS |
| ============================================================ |
| Quantidade minima instalada: {qtd_ext} (unidades) |
| Capacidade extintora: {cap_ext} |
| Distribuicao: instalados em locais visiveis, sinalizados e de |
| facil acesso, com distancia maxima de 15 metros entre eles. |
| Altura de instalacao: entre 1,0m e 1,60m do piso ao manometro. |
| Manutencao: anual conforme ABNT NBR 12962. |
| Conforme ABNT NBR 12693 e NT-01/2025 Anexo B - Grupo {grupo.upper()} |
| |
| ============================================================ |
| 5. SISTEMA DE HIDRANTES E MANGOTINHOS |
| ============================================================ |
| Sistema instalado: {sist_hid} |
| Vazao minima: {vazao} L/min por hidrante |
| Pressao dinamica minima: 15 mca no hidrante mais desfavoravel |
| Reserva tecnica de incendio: {reserva} m3 (exclusiva para incendio) |
| Tubulacao: aco galvanizado/PRFV, DN 65mm (rede principal) |
| Registro de recalque externo para CBMGO |
| Conforme ABNT NBR 13714 e NT-01/2025 Art. 18 |
| {sec_ilum}{sec_spda}{sec_alarme}{sec_chuveiros} |
| ============================================================ |
| {len([e for e in exigencias if e not in ['iluminacao_emergencia','spda','alarme_incendio','chuveiros_automaticos']]) + 6}. SINALIZACAO DE EMERGENCIA |
| ============================================================ |
| Sinalizacao fotoluminescente instalada em: |
| - Saidas de emergencia (indicacao de saida e seta direcional) |
| - Rotas de fuga em todos os corredores |
| - Localizacao dos extintores e hidrantes |
| - Instrucoes de emergencia e prohibicoes |
| - Planta de localizacao com rotas de evacuacao |
| Conforme ABNT NBR 13434 Partes 1, 2 e 3 |
| |
| ============================================================ |
| ASSINATURAS |
| ============================================================ |
| |
| Responsavel Tecnico: {rt_nome} |
| CREA/CAU N.: {rt_crea} |
| Empresa: _____________________________________________ |
| Data: {data_hoje} |
| |
| Profissional habilitado conforme resolucao CONFEA/CREA. |
| Este memorial e parte integrante do projeto de PSCIP e |
| deve ser lido em conjunto com as pranchas tecnicas. |
| |
| ============================================================ |
| FIM DO MEMORIAL DESCRITIVO |
| ============================================================ |
| """ |
| return memorial |
|
|
| def gerar(self, dados: Dict) -> str: |
| """Interface principal: LLM se disponivel, template caso contrario.""" |
| if self.use_llm and self._pipe is not None: |
| return self.gerar_llm(dados) |
| return self.gerar_template(dados) |
|
|
|
|
| _memorial_gen = None |
|
|
| def get_memorial_generator(use_llm=False): |
| global _memorial_gen |
| if _memorial_gen is None: |
| _memorial_gen = MemorialGenerator(use_llm=use_llm) |
| return _memorial_gen |
|
|
|
|
| if __name__ == "__main__": |
| gen = MemorialGenerator() |
| dados = { |
| "nome_edificacao": "Edificio Comercial Exemplo", |
| "ocupacao": "comercial", |
| "grupo": "D", "divisao": "D-1", |
| "area_m2": 1200, "altura_m": 8, "pavimentos": 2, "lotacao": 120, |
| "exigencias": ["extintores_portateis", "hidrantes", "sinalizacao_emergencia", |
| "alarme_incendio", "spda"], |
| "qtd_extintores": 4, "capacidade_extintor": "2-A:20-B:C", |
| "sistema_hidrante": "Coluna Seca", "vazao_lpm": 300, "reserva_m3": 18.0, |
| "rt_nome": "Eng. Carlos Silva", "rt_crea": "GO-12345" |
| } |
| print(gen.gerar(dados)) |
|
|