Preciso encontrar uma solução para que consiga encontrar os limites de cada componente de forma global para que e compare se existe intersecção de usinagens dentro do me cubo, considerando que minhas usinagem podem estar agrupadas ou não. Alguém pode me ajudar para melhorar me script para que ele consiga transformar e trazer as cordenadas globais independente da hierarquia que cada componente está?
# Função para detectar componentes com atributo "int_cat" e valor "usi_col"
def find_usi_col_components(entities)
usi_col_components = []
entities.each do |entity|
if entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
if entity.definition.get_attribute("dynamic_attributes", "int_cat") == "usi_col"
usi_col_components << entity
end
# Recursivamente procurar em grupos e componentes aninhados
usi_col_components.concat(find_usi_col_components(entity.definition.entities))
end
end
usi_col_components
end
# Função para verificar se o grupo pai tem o atributo "int_cat" com valor "usi_group"
def parent_has_usi_group_attribute?(component_instance)
parent = component_instance.parent
return false unless parent.is_a?(Sketchup::Model) || parent.is_a?(Sketchup::ComponentDefinition)
parent_instance = parent.instances.first
return false unless parent_instance
parent_instance.definition.get_attribute("dynamic_attributes", "int_cat") == "usi_group"
end
# Função para obter as coordenadas globais exatas do ponto de origem da usinagem
def get_usinagem_origin(component)
origin = component.transformation.origin
{
x: (origin.x * 25.4).round(1), # Convertendo de polegadas para milímetros
y: (origin.y * 25.4).round(1),
z: (origin.z * 25.4).round(1)
}
end
# Função para obter as coordenadas mínimas e máximas do BoundingBox do MDF (em milímetros)
def get_bounding_box_coordinates(component)
bounds = component.bounds
# Obter os limites mínimos e máximos diretamente sem transformação
{
min_x: (bounds.min.x * 25.4).round(1), # Convertendo de polegadas para milímetros
min_y: (bounds.min.y * 25.4).round(1),
min_z: (bounds.min.z * 25.4).round(1),
max_x: (bounds.max.x * 25.4).round(1),
max_y: (bounds.max.y * 25.4).round(1),
max_z: (bounds.max.z * 25.4).round(1)
}
end
# Função para formatar as coordenadas de forma clara
def format_origin_coordinates(description, coordinates)
"#{description} {x=#{coordinates[:x]}, y=#{coordinates[:y]}, z=#{coordinates[:z]}}"
end
# Função para formatar o BoundingBox de forma clara
def format_bounding_box(description, coordinates)
"#{description} {min_x=#{coordinates[:min_x]}, min_y=#{coordinates[:min_y]}, min_z=#{coordinates[:min_z]}, max_x=#{coordinates[:max_x]}, max_y=#{coordinates[:max_y]}, max_z=#{coordinates[:max_z]}}"
end
# Função principal para verificar se os pontos dos eixos globais estão dentro de algum BoundingBox
def check_usinagem_within_components(usi_col_component, entities)
detected_intersections = []
# Verifica se o grupo pai tem o atributo "int_cat" com valor "usi_group"
return false, detected_intersections if parent_has_usi_group_attribute?(usi_col_component)
usinagem_origin = get_usinagem_origin(usi_col_component)
entities.each do |entity|
next unless entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
next if entity == usi_col_component
# Verifica se o componente tem o atributo "int_cat" com valor "MDF"
next unless entity.definition.get_attribute("dynamic_attributes", "int_cat") == "MDF"
bounding_box_coords = get_bounding_box_coordinates(entity)
# Verifica se os pontos de origem da usinagem (x, y, z) estão dentro dos intervalos do BoundingBox do componente MDF
colisao_x = usinagem_origin[:x] >= bounding_box_coords[:min_x] && usinagem_origin[:x] <= bounding_box_coords[:max_x]
colisao_y = usinagem_origin[:y] >= bounding_box_coords[:min_y] && usinagem_origin[:y] <= bounding_box_coords[:max_y]
colisao_z = usinagem_origin[:z] >= bounding_box_coords[:min_z] && usinagem_origin[:z] <= bounding_box_coords[:max_z]
if colisao_x && colisao_y && colisao_z
detected_intersections << {
usi_component_desc: usi_col_component.definition.get_attribute("dynamic_attributes", "int_desc"),
intersecting_component_desc: entity.definition.get_attribute("dynamic_attributes", "int_desc"),
usinagem_origin: usinagem_origin,
component_bounds: bounding_box_coords
}
else
puts "Colisão não detectada: X=#{colisao_x}, Y=#{colisao_y}, Z=#{colisao_z}"
end
end
[!detected_intersections.empty?, detected_intersections]
end
# Função principal para executar o script
def run_collision_detection
model = Sketchup.active_model
entities = model.entities
usi_col_components = find_usi_col_components(entities)
collision_found = false
all_intersections = []
usi_col_components.each do |usi_col_component|
found_collision, detected_intersections = check_usinagem_within_components(usi_col_component, entities)
all_intersections.concat(detected_intersections) if found_collision
collision_found ||= found_collision
end
if collision_found
intersection_details = all_intersections.map do |intersection|
"Colisão detectada!\n" \
"Usinagem: #{format_origin_coordinates(intersection[:usi_component_desc], intersection[:usinagem_origin])}\n" \
"Colidiu com: #{format_bounding_box(intersection[:intersecting_component_desc], intersection[:component_bounds])}"
end.join("\n\n")
UI.messagebox("Colisões Detectadas:\n\n#{intersection_details}")
else
usinagem_details = usi_col_components.map do |usi|
usinagem_origin = get_usinagem_origin(usi)
format_origin_coordinates(usi.definition.get_attribute("dynamic_attributes", "int_desc"), usinagem_origin)
end.join("\n")
components_details = entities.grep(Sketchup::ComponentInstance).map do |comp|
next unless comp.definition.get_attribute("dynamic_attributes", "int_cat") == "MDF"
bounding_box_coords = get_bounding_box_coordinates(comp)
format_bounding_box(comp.definition.get_attribute("dynamic_attributes", "int_desc"), bounding_box_coords)
end.compact.join("\n")
UI.messagebox("Nenhuma colisão detectada.\n\nUsinagens encontradas:\n#{usinagem_details}\n\nComponentes analisados:\n#{components_details}")
end
model.commit_operation
end
# Iniciar a detecção
Sketchup.active_model.start_operation('Detect Usinagem Collisions', true)
run_collision_detection
Procurei por artigos com o mesmo tópico mais nenhum deles tiveram esclarecimento.
Obrigado.