Auto-Ajuste de Dobradiças em Colisão com Prateleiras (JavaScript)
Versão: CV2025.4
Descrição:
Este UCS tem a função de analisar a comparação dos diversos atributos entre os componentes de dobradiças (HNG) e calços de dobradiça (S_HNGPLT) e os três tipos de prateleiras existentes: prateleiras (SH), prateleiras fixas (FS) e prateleiras ajustáveis (AS) de forma a que quando a sua posição seja coincidente, dentro de uma zona de colisão definida, seja detectada a colisão e, de forma automática, decida mover a dobradiça para cima ou para baixo conforme seja mais próximo, dentro de uma margem de segurança em relação à caixa.
Existem zonas de colisão existem em altura (Y), em profundidade (Z) e margem à estrutura que vêm como padrão 50mm cada uma. No entanto, após a ativação da movimentação automática, podemos manipular estes valores para aumentar ou diminuir a nossa fronteira de colisão.
Instalação:
Opção 1
Download e Importação do Pacote com o UCS:
Opção 2
Criar um novo UCS em JavaScript e configurar da seguinte maneira para funcionar, uma vez que trabalha ao nível do módulo (CAB):

Copiar o seguinte código para dentro do UCS criado (substituir tudo):
// UCS: AUTO-AJUSTE DE DOBRADIÇAS EM COLISÃO (DOBRADIÇAS VS PRATELEIRAS)
// Versão: 06012026
// Compatibilidade: CV2025.4
// --- 1. INICIALIZAÇÃO DE PARÂMETROS E ATRIBUTOS ---
// Define se o recurso está ativo e cria os campos na aba de Atributos do Gabinete.
if (_this.Evaluate('_MOVE_HNG_AUTO') == null) {
_this.SetParameter('_MOVE_HNG_AUTO', 0, VAL_BOOL);
_this.ModifyParameter('_MOVE_HNG_AUTO', PARMOD_STYLE, PARSTYLE_ATTRIBUTE);
_this.ModifyParameter('_MOVE_HNG_AUTO', PARMOD_DESC, 'Auto-Ajustar Dobradiças em Colisão?');
}
// Cláusula de saída: Se desativado, remove os parâmetros auxiliares e para a execução.
if (_this.GetParameterValue('_MOVE_HNG_AUTO') == 0) {
_this.RemoveParameter('_MOVE_HNG_ZONA_COLISAO_Y');
_this.RemoveParameter('_MOVE_HNG_ZONA_COLISAO_Z');
_this.RemoveParameter('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA');
return;
}
var INCH_TO_MM = 25.4;
// Definição das distâncias de segurança (Zonas de Colisão)
if (_this.Evaluate('_MOVE_HNG_ZONA_COLISAO_Y') == null) {
_this.SetParameter('_MOVE_HNG_ZONA_COLISAO_Y', (50/INCH_TO_MM), VAL_MEASUREMENT);
_this.ModifyParameter('_MOVE_HNG_ZONA_COLISAO_Y', PARMOD_STYLE, PARSTYLE_ATTRIBUTE);
_this.ModifyParameter('_MOVE_HNG_ZONA_COLISAO_Y', PARMOD_DESC, 'Auto-Ajustar Dobradiças.a - Zona de Colisao (Y)?');
}
if (_this.Evaluate('_MOVE_HNG_ZONA_COLISAO_Z') == null) {
_this.SetParameter('_MOVE_HNG_ZONA_COLISAO_Z', (50/INCH_TO_MM), VAL_MEASUREMENT);
_this.ModifyParameter('_MOVE_HNG_ZONA_COLISAO_Z', PARMOD_STYLE, PARSTYLE_ATTRIBUTE);
_this.ModifyParameter('_MOVE_HNG_ZONA_COLISAO_Z', PARMOD_DESC, 'Auto-Ajustar Dobradiças.b - Zona de Colisao (Z)?');
}
if (_this.Evaluate('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA') == null) {
_this.SetParameter('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA', (80/INCH_TO_MM), VAL_MEASUREMENT);
_this.ModifyParameter('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA', PARMOD_STYLE, PARSTYLE_ATTRIBUTE);
_this.ModifyParameter('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA', PARMOD_DESC, 'Auto-Ajustar Dobradiças.c - Margem Limite Caixa?');
}
// --- 2. CONFIGURAÇÕES EM MILÍMETROS (CONVERSÃO INICIAL) ---
// Criamos variáveis locais em MM para facilitar a leitura da lógica matemática abaixo.
var CONF_ZONA_Y_MM = _this.GetParameterValue('_MOVE_HNG_ZONA_COLISAO_Y') * INCH_TO_MM;
var CONF_ZONA_Z_MM = _this.GetParameterValue('_MOVE_HNG_ZONA_COLISAO_Z') * INCH_TO_MM;
var CONF_MARGEM_MM = _this.GetParameterValue('_MOVE_HNG_MARGEM_LIMITE_ESTRUTURA') * INCH_TO_MM;
var CONF_ALTURA_MAX_MM = _cab.DY * INCH_TO_MM;
var listaHng = [];
var listaPlt = [];
var listaShelves = [];
var prefixosShelves = ["FS", "SH", "AS"]; // Fixas, Soltas e Ajustáveis
// --- 3. COLETA DE DADOS (CONVERTENDO TUDO PARA MM NO MAPEAMENTO) ---
// Esta função recursiva varre o cab
function coletarTudo(pai) {
var filhos = pai.GetChildren();
if (filhos == null) return;
for (var i = 0; i < filhos.Count; i++) {
var obj = filhos(i);
var nomeUpr = obj.NAME.toUpperCase();
// Coleta de Dobradiças
if ((nomeUpr.indexOf("HNG") === 0 || nomeUpr.indexOf(".HNG") !== -1) && nomeUpr.indexOf("PLT") === -1) {
listaHng.push({
obj: obj,
x: Number(obj.GetParameterValue("PABSX")) * INCH_TO_MM,
y: Number(obj.GetParameterValue("PABSY")) * INCH_TO_MM,
z: Number(obj.GetParameterValue("PABSZ")) * INCH_TO_MM
});
}
// Coleta de Calços
if (nomeUpr.indexOf("PLT") !== -1) {
listaPlt.push({
obj: obj,
x: Number(obj.GetParameterValue("PABSX")) * INCH_TO_MM,
y: Number(obj.GetParameterValue("PABSY")) * INCH_TO_MM,
z: Number(obj.GetParameterValue("PABSZ")) * INCH_TO_MM
});
}
// Coleta de Prateleiras baseada nos prefixos definidos
var eShelf = false;
for (var p = 0; p < prefixosShelves.length; p++) {
if (nomeUpr.indexOf(prefixosShelves[p]) === 0 || nomeUpr.indexOf("." + prefixosShelves[p]) !== -1) {
eShelf = true; break;
}
}
// IsShaped() filtra prateleiras com recortes complexos que poderiam invalidar a lógica
if (eShelf && !obj.IsShaped()) {
listaShelves.push({
obj: obj,
x: Number(obj.GetParameterValue("PABSX")) * INCH_TO_MM,
y: Number(obj.GetParameterValue("PABSY")) * INCH_TO_MM,
z: Number(obj.GetParameterValue("PABSZ")) * INCH_TO_MM,
dy: Number(obj.GetParameterValue("DY")) * INCH_TO_MM,
dx: Number(obj.GetParameterValue("DX")) * INCH_TO_MM,
dz: Number(obj.GetParameterValue("DZ")) * INCH_TO_MM
});
}
if (obj.GetChildren().Count > 0) { coletarTudo(obj); }
}
}
coletarTudo(_cab);
// --- 4. LÓGICA DE DETECÇÃO EM MM ---
// Triplo loop comparativo: Dobradiça vs Prateleira -> Movimento -> Calço
for (var h = 0; h < listaHng.length; h++) {
var hng = listaHng[h];
for (var s = 0; s < listaShelves.length; s++) {
var shf = listaShelves[s];
// PASSO 1: Filtro X - Verifica se a dobradiça está montada no mesmo alinhamento da prateleira (lateral)
if (hng.x >= (shf.x - 5) && hng.x <= (shf.x + shf.dy + 5)) {
var centroShelfY = shf.y + (shf.dz / 2); // DZ em prateleiras horizontais refere-se à profundidade
var difY = hng.y - centroShelfY;
// PASSO 2: Filtro Y - Verifica se a dobradiça está dentro da zona de colisão vertical
if (Math.abs(difY) < CONF_ZONA_Y_MM) {
var frentePratZ = shf.z + shf.dx;
// PASSO 3: Filtro Z - Verifica se a profundidade da prateleira atinge a ferragem
if (frentePratZ > (hng.z - CONF_ZONA_Z_MM)) {
// Cálculo de posições de escape (Acima ou Abaixo)
var posSeguraAcima = centroShelfY + CONF_ZONA_Y_MM + 2;
var posSeguraAbaixo = centroShelfY - CONF_ZONA_Y_MM - 2;
// Validação de limites físicos (Não sair para fora do gabinete)
var podeSubir = (posSeguraAcima < (CONF_ALTURA_MAX_MM - CONF_MARGEM_MM));
var podeDescer = (posSeguraAbaixo > CONF_MARGEM_MM);
var novoYAbs_MM;
// Lógica de desvio pelo caminho mais curto
if (Math.abs(hng.y - posSeguraAcima) <= Math.abs(hng.y - posSeguraAbaixo)) {
novoYAbs_MM = podeSubir ? posSeguraAcima : posSeguraAbaixo;
} else {
novoYAbs_MM = podeDescer ? posSeguraAbaixo : posSeguraAcima;
}
// ARREDONDAMENTO: Garante que o destino seja um número inteiro em milímetros
novoYAbs_MM = Math.round(novoYAbs_MM);
// Cálculo do deslocamento necessário (Delta)
var deltaY_MM = novoYAbs_MM - hng.y;
// Aplicação do movimento se o deslocamento for superior a 0.1mm
if (Math.abs(deltaY_MM) > 0.1) {
// Converte o delta de MM para Inch para o motor do Cabinet Vision
var deltaY_Inch = deltaY_MM / INCH_TO_MM;
// Move o objeto Dobradiça
hng.obj.Y += deltaY_Inch;
// BUSCA DO CALÇO: Localiza o calço que estava na mesma posição Y original
var menorDistX = 999;
var calcoAlvo = null;
for (var k = 0; k < listaPlt.length; k++) {
var plt = listaPlt[k];
// Critério: Mesmo Y (tolerância 2mm) e mesmo Z
if (Math.abs(plt.y - hng.y) < 2 && Math.abs(plt.z - hng.z) < 50) {
var dX = Math.abs(plt.x - hng.x);
if (dX < menorDistX) {
menorDistX = dX;
calcoAlvo = plt;
}
}
}
// Se o calço for encontrado, move-o na mesma proporção
if (calcoAlvo != null) {
calcoAlvo.obj.Y += deltaY_Inch;
calcoAlvo.y += deltaY_MM; // Atualiza cache para próxima prateleira no loop
}
// Atualiza cache da dobradiça para o caso de múltiplas colisões na mesma peça
hng.y += deltaY_MM;
}
}
}
}
}
}