-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Update print statement from 'Hello' to 'Goodbye' #7148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
+1,060
−139
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Здесь сделай чтоб присадку делал согласно локальных координат компонентов, так как сейчас на повёрнутых под определённый градус угла компонентах не делает присадок потому что делает присадку согласно мировых координат что не допустимо. Пиши полный код целиком.
require 'sketchup.rb'
require 'extensions.rb'
module ABFStyleDrill
# Настройки по умолчанию
DEFAULTS = {
:cam_diameter => 8.0, # Диаметр отверстия в пласть (Cam)
:screw_diameter => 5.0, # Диаметр отверстия в торец (Screw)
:offset => 50.0, # Отступ от края детали для присадки
:hole_count => 2, # Количество присадочных отверстий
:marker_length => 15.0, # Длина проекции (маркера) для торцевого отверстия
# --- НОВЫЕ НАСТРОЙКИ ДЛЯ ПЕТЕЛЬ ---
:hinge_diameter => 35.0, # Диаметр отверстия под чашку петли (35мм)
:hinge_offset => 100.0, # Отступ от края детали для первой петли (100мм) - Смещение по длине
:hinge_count => 2, # Количество петель
:hinge_side_offset => 21.5, # Смещение от бокового края компонента (21.5мм)
:hinge_screw_diameter => 5.0, # Диаметр отверстий под саморезы (5мм)
:hinge_screw_spacing => 45.0, # Расстояние между центрами отверстий под саморезы (45мм)
:hinge_screw_vertical_offset => 9.5, # НОВОЕ: Смещение отверстий под саморезы от центра чашки (9.5мм)
# --- НОВЫЕ НАСТРОЙКИ ДЛЯ ПЛАНКИ ---
:strip_diameter => 5.0, # Диаметр отверстия под планку (5мм)
:strip_spacing => 32.0, # Межосевое расстояние (32мм)
:strip_side_offset => 37.0, # Смещение от края боковины (37мм)
:strip_offset => 100.0 # НОВОЕ: Отступ от короткого края (100мм)
}
# Константа для зазора между деталями при раскладке
GAP = 500.0.mm
# Переменная для отслеживания состояния аннотаций
@annotations_visible = false
# --- МЕТОД: Очистка ранее созданных аннотаций (размеров) ---
def self.cleanup_annotations(entities)
entities_to_remove = []
entities.each do |e|
if e.is_a?(Sketchup::DimensionLinear) && e.get_attribute('ABFDrill', 'Type') == 'Dimension'
entities_to_remove << e
end
end
entities.erase_entities(entities_to_remove) if entities_to_remove.any?
end
# --- МЕТОД: Очистка только стандартных присадочных отверстий и маркеров ---
def self.cleanup_standard_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
defn.entities.each do |e|
# Удаляем всё, что помечено как DrillHole
type = e.get_attribute('ABFDrill', 'Type')
if type == 'DrillHole'
entities_to_remove << e
end
end
defn.entities.erase_entities(entities_to_remove) if entities_to_remove.any?
end
# --- МЕТОД: Очистка только отверстий под петли ---
def self.cleanup_hinge_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
defn.entities.each do |e|
# Удаляем всё, что помечено как HingeHole
type = e.get_attribute('ABFDrill', 'Type')
if type == 'HingeHole'
entities_to_remove << e
end
end
defn.entities.erase_entities(entities_to_remove) if entities_to_remove.any?
end
# --- НОВЫЙ МЕТОД: Очистка только отверстий под планку ---
def self.cleanup_strip_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
defn.entities.each do |e|
# Удаляем всё, что помечено как StripHole (включая новую точку)
type = e.get_attribute('ABFDrill', 'Type')
if type == 'StripHole'
entities_to_remove << e
end
end
defn.entities.erase_entities(entities_to_remove) if entities_to_remove.any?
end
# --- МЕТОД: Отображение диалогового окна (Обновлено для передачи параметров петель в планку) ---
def self.show_dialog
dialog = UI::HtmlDialog.new(
{
:dialog_title => "ABF Style Drill & Hinges",
:preferences_key => "com.abfstyle.drill",
:scrollable => true,
:resizable => true,
:width => 350,
:height => 850, # Увеличена высота для новых настроек
:style => UI::HtmlDialog::STYLE_DIALOG
}
)
html_content = <<-HTML
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; background-color: microsoft#333; color: white; }
h3 { margin-top: 20px; color: #ff9800; border-bottom: 1px solid microsoft#555; padding-bottom: 10px; }
.control { margin-bottom: 15px; }
label { display: flex; justify-content: space-between; align-items: center; font-size: 14px; }
input { width: 80px; padding: 5px; border-radius: 4px; border: none; text-align: center; }
button {
width: 100%; padding: 12px; margin-top: 10px;
background-color: #ff9800; color: white; border: none;
border-radius: 4px; cursor: pointer; font-weight: bold; font-size: 16px;
transition: background 0.3s;
}
button:hover { background-color: #e68900; }
.hint { font-size: 11px; color: #aaa; margin-top: 5px; }
.secondary-button { background-color: microsoft#555; }
.secondary-button:hover { background-color: microsoft#777; }
.annotation-button { background-color: #00bcd4; }
.annotation-button:hover { background-color: #0097a7; }
.hinge-button { background-color: #4CAF50; }
.hinge-button:hover { background-color: #45a049; }
/* НОВЫЙ СТИЛЬ ДЛЯ КНОПКИ ПЛАНКИ */
.strip-button { background-color: #9c27b0; }
.strip-button:hover { background-color: #7b1fa2; }
</style>
</head>
<body>
<!-- --- НОВАЯ СЕКЦИЯ ДЛЯ ПЛАНКИ (ПЕРЕМЕЩЕНА ВЫШЕ) --- -->
<h3>Присадка планки</h3>
<div class="control">
<label>Диаметр отверстий (мм) <input type="number" id="strip_dia" value="#{DEFAULTS[:strip_diameter]}" step="0.5"></label>
</div>
<div class="control">
<label>Межосевое (мм) <input type="number" id="strip_spacing" value="#{DEFAULTS[:strip_spacing]}" step="1.0"></label>
</div>
<div class="control">
<label>Смещение от края (мм) <input type="number" id="strip_side_off" value="#{DEFAULTS[:strip_side_offset]}" step="1.0"></label>
</div>
<!-- НОВЫЙ ИНПУТ ДЛЯ СМЕЩЕНИЯ ПЛАНКИ -->
<div class="control">
<label>Смещение по длине (мм) <input type="number" id="strip_off" value="#{DEFAULTS[:strip_offset]}" step="1.0"></label>
<div class="hint">Отступ первой планки от короткого края.</div>
</div>
<button class="strip-button" onclick="run_strip_drill()">ПРИСАДКА ПЛАНКИ</button>
<!-- --- КОНЕЦ НОВОЙ СЕКЦИИ --- -->
<h3>Настройки присадки (Minifix)</h3>
<div class="control">
<label>Количество отверстий <input type="number" id="hole_count" value="#{DEFAULTS[:hole_count]}" step="1" min="1" oninput="update_model_realtime()"></label>
<div class="hint">Общее количество на стык.</div>
</div>
<div class="control">
<label>Диаметр (Пласть/Cam) <input type="number" id="cam_dia" value="#{DEFAULTS[:cam_diameter]}" step="0.5" oninput="update_model_realtime()"></label>
</div>
<div class="control">
<label>Диаметр (Торец/Screw) <input type="number" id="screw_dia" value="#{DEFAULTS[:screw_diameter]}" step="0.5" oninput="update_model_realtime()"></label>
</div>
<div class="control">
<label>Длина маркера (мм) <input type="number" id="marker_len" value="#{DEFAULTS[:marker_length]}" step="1.0" min="0" oninput="update_model_realtime()"></label>
<div class="hint">Длина проекции торцевого отверстия.</div>
</div>
<div class="control">
<label>Отступ от края (мм) <input type="number" id="off" value="#{DEFAULTS[:offset]}" step="1" oninput="update_model_realtime()"></label>
</div>
<button onclick="run()">ПРИСАДИТЬ (Auto)</button>
<!-- --- НОВАЯ СЕКЦИЯ ДЛЯ ПЕТЕЛЬ --- -->
<h3>Настройки петель</h3>
<div class="control">
<label>Количество кругов <input type="number" id="hinge_count" value="#{DEFAULTS[:hinge_count]}" step="1" min="1"></label>
</div>
<div class="control">
<label>Диаметр чашки (мм) <input type="number" id="hinge_dia" value="#{DEFAULTS[:hinge_diameter]}" step="1.0"></label>
</div>
<!-- НОВЫЕ ИНПУТЫ ДЛЯ ОТВЕРСТИЙ ПОД САМОРЕЗЫ -->
<div class="control">
<label>Диаметр саморезов (мм) <input type="number" id="hinge_screw_dia" value="#{DEFAULTS[:hinge_screw_diameter]}" step="0.5"></label>
</div>
<div class="control">
<label>Расстояние между (мм) <input type="number" id="hinge_screw_spacing" value="#{DEFAULTS[:hinge_screw_spacing]}" step="1.0"></label>
<div class="hint">Расстояние между центрами отверстий под саморезы (45мм).</div>
</div>
<!-- НОВЫЙ ИНПУТ ДЛЯ СМЕЩЕНИЯ САМОРЕЗОВ ОТНОСИТЕЛЬНО ЧАШКИ -->
<div class="control">
<label>Смещение саморезов (мм) <input type="number" id="hinge_screw_vert_off" value="#{DEFAULTS[:hinge_screw_vertical_offset]}" step="0.5"></label>
<div class="hint">Смещение отверстий от центра чашки (вдоль 21.5мм оси).</div>
</div>
<!-- КОНЕЦ НОВЫХ ИНПУТОВ -->
<div class="control">
<label>Смещение по длине (мм) <input type="number" id="hinge_off" value="#{DEFAULTS[:hinge_offset]}" step="1.0"></label>
<div class="hint">Отступ первой петли от короткого края.</div>
</div>
<div class="control">
<label>Смещение от края компонента (мм) <input type="number" id="hinge_side_off" value="#{DEFAULTS[:hinge_side_offset]}" step="0.5"></label>
<div class="hint">Смещение центра чашки от бокового края (21.5мм).</div>
</div>
<button class="hinge-button" onclick="run_hinges()">ПЕТЛИ</button>
<!-- --- КОНЕЦ НОВОЙ СЕКЦИИ --- -->
<button class="secondary-button" onclick="line_up()">РАЗЛОЖИТЬ</button>
<button class="annotation-button" onclick="show_annotations()">АННОТАЦИИ</button>
<script>
function debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => { func.apply(this, args); }, timeout);
};
}
function get_input_values() {
return {
cam_dia: parseFloat(document.getElementById('cam_dia').value),
screw_dia: parseFloat(document.getElementById('screw_dia').value),
off: parseFloat(document.getElementById('off').value),
hole_count: parseInt(document.getElementById('hole_count').value),
marker_len: parseFloat(document.getElementById('marker_len').value)
};
}
// --- НОВАЯ ФУНКЦИЯ ДЛЯ ПОЛУЧЕНИЯ ЗНАЧЕНИЙ ПЕТЕЛЬ (ОБНОВЛЕНО) ---
function get_hinge_values() {
return {
hinge_count: parseInt(document.getElementById('hinge_count').value),
hinge_dia: parseFloat(document.getElementById('hinge_dia').value),
hinge_off: parseFloat(document.getElementById('hinge_off').value),
hinge_side_off: parseFloat(document.getElementById('hinge_side_off').value),
// НОВЫЕ ЗНАЧЕНИЯ
hinge_screw_dia: parseFloat(document.getElementById('hinge_screw_dia').value),
hinge_screw_spacing: parseFloat(document.getElementById('hinge_screw_spacing').value),
hinge_screw_vertical_offset: parseFloat(document.getElementById('hinge_screw_vert_off').value)
};
}
// --- НОВАЯ ФУНКЦИЯ ДЛЯ ПОЛУЧЕНИЯ ЗНАЧЕНИЙ ПЛАНКИ (ОБНОВЛЕНО) ---
function get_strip_values() {
return {
strip_dia: parseFloat(document.getElementById('strip_dia').value),
strip_spacing: parseFloat(document.getElementById('strip_spacing').value),
strip_side_off: parseFloat(document.getElementById('strip_side_off').value),
strip_offset: parseFloat(document.getElementById('strip_off').value), // ДОБАВЛЕНО
// ДОБАВЛЕНЫ ЗНАЧЕНИЯ ПЕТЕЛЬ ДЛЯ ПОЗИЦИОНИРОВАНИЯ ПЛАНКИ
hinge_count: parseInt(document.getElementById('hinge_count').value)
};
}
function run() {
var values = get_input_values();
sketchup.do_drill(values.cam_dia, values.screw_dia, values.off, values.hole_count, values.marker_len);
}
// --- НОВАЯ ФУНКЦИЯ ДЛЯ ЗАПУСКА ПЕТЕЛЬ (ОБНОВЛЕНО) ---
function run_hinges() {
var values = get_hinge_values();
// Передаем новые значения
sketchup.do_hinges(
values.hinge_count,
values.hinge_dia,
values.hinge_off,
values.hinge_side_off,
values.hinge_screw_dia,
values.hinge_screw_spacing,
values.hinge_screw_vertical_offset
);
}
// --- НОВАЯ ФУНКЦИЯ ДЛЯ ЗАПУСКА ПЛАНКИ (ОБНОВЛЕНО) ---
function run_strip_drill() {
var values = get_strip_values();
sketchup.do_strip_drill(
values.strip_dia,
values.strip_spacing,
values.strip_side_off,
// ПЕРЕДАЕМ ПАРАМЕТРЫ ДЛЯ ПОЗИЦИОНИРОВАНИЯ
values.hinge_count,
values.strip_offset // ИСПОЛЬЗУЕМ НОВОЕ СМЕЩЕНИЕ
);
}
const debounced_update_callback = debounce(function() {
var values = get_input_values();
sketchup.update_drill_realtime(values.cam_dia, values.screw_dia, values.off, values.hole_count, values.marker_len);
}, 300);
function update_model_realtime() { debounced_update_callback(); }
function line_up() { sketchup.line_up_components(); }
function show_annotations() { sketchup.show_drill_annotations(); }
window.onload = function() { update_model_realtime(); };
</script>
</body>
</html>
HTML
dialog.set_html(html_content)
dialog.center
dialog.add_action_callback("do_drill") do |ctx, cam_dia, screw_dia, off, hole_count, marker_len|
self.process_model(cam_dia, screw_dia, off, hole_count, marker_len)
end
dialog.add_action_callback("update_drill_realtime") do |ctx, cam_dia, screw_dia, off, hole_count, marker_len|
self.process_model(cam_dia, screw_dia, off, hole_count, marker_len)
end
# --- CALLBACK ДЛЯ ПЕТЕЛЬ ---
dialog.add_action_callback("do_hinges") do |ctx, count, diameter, length_offset, side_offset, screw_diameter, screw_spacing, screw_vert_offset|
self.process_hinge_holes(count, diameter, length_offset, side_offset, screw_diameter, screw_spacing, screw_vert_offset)
end
# --- НОВЫЙ CALLBACK ДЛЯ ПЛАНКИ (ОБНОВЛЕНО) ---
# Изменено: hinge_offset заменен на length_offset (который теперь strip_offset)
dialog.add_action_callback("do_strip_drill") do |ctx, diameter, spacing, side_offset, count, length_offset|
self.process_strip_holes(diameter, spacing, side_offset, count, length_offset)
end
dialog.add_action_callback("line_up_components") { |ctx| self.line_up_components }
dialog.add_action_callback("show_drill_annotations") { |ctx| self.show_drill_annotations }
dialog.show
end
# --- ГЛАВНЫЙ ПРОЦЕСС ПРИСАДКИ (Minifix) ---
def self.process_model(cam_diameter_mm, screw_diameter_mm, offset_mm, hole_count, marker_length_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
# Если выделено меньше 2-х, очищаем присадки только на выделенных и выходим
if items.length < 2
model.start_operation("ABF Drill Cleanup", true)
items.each { |ent| self.cleanup_standard_drill_geometry(ent) }
model.commit_operation
return
end
model.start_operation("ABF Style Drill Update", true)
# Очищаем только стандартные присадки на выделенных компонентах
items.each { |ent| self.cleanup_standard_drill_geometry(ent) }
processed_pairs = 0
(0...items.length).each do |i|
((i + 1)...items.length).each do |j|
ent1 = items[i]
ent2 = items[j]
# Проверяем пересечение
if ent1.bounds.intersect(ent2.bounds).valid?
if self.apply_drill_to_pair(ent1, ent2, cam_diameter_mm.mm, screw_diameter_mm.mm, offset_mm.mm, hole_count, marker_length_mm.mm)
processed_pairs += 1
end
end
end
end
model.commit_operation
end
# ... (get_diameter остается без изменений)
def self.get_diameter(entity, global_drill_axis, cam_dia, screw_dia)
trans_inv = entity.transformation.inverse
local_drill_axis = global_drill_axis.transform(trans_inv)
bb_local = entity.bounds
w, h, d = bb_local.width, bb_local.height, bb_local.depth
dims = { w => Geom::Vector3d.new(1, 0, 0), h => Geom::Vector3d.new(0, 1, 0), d => Geom::Vector3d.new(0, 0, 1) }
min_dim = dims.keys.min
local_thickness_axis = dims[min_dim]
dot_product = local_drill_axis.dot(local_thickness_axis).abs
return (dot_product > 0.999) ? cam_dia : screw_dia
end
# --- ОСНОВНАЯ ЛОГИКА ПРИСАДКИ И ГЕОМЕТРИИ (Minifix) ---
def self.apply_drill_to_pair(ent1, ent2, cam_diameter, screw_diameter, offset, hole_count, marker_length)
bb1 = ent1.bounds
bb2 = ent2.bounds
intersect = bb1.intersect(bb2)
return false if intersect.empty?
w, h, d = intersect.width, intersect.height, intersect.depth
dims = [w, h, d]
min_dim = dims.min
return false if dims.max < 10.mm
drill_axis = Geom::Vector3d.new(0,0,1)
long_axis_vec = Geom::Vector3d.new(1,0,0)
center = intersect.center
if min_dim == w
drill_axis = Geom::Vector3d.new(1, 0, 0)
long_axis_vec = (h > d) ? Geom::Vector3d.new(0, 1, 0) : Geom::Vector3d.new(0, 0, 1)
len = [h, d].max
elsif min_dim == h
drill_axis = Geom::Vector3d.new(0, 1, 0)
long_axis_vec = (w > d) ? Geom::Vector3d.new(1, 0, 0) : Geom::Vector3d.new(0, 0, 1)
len = [w, d].max
else
drill_axis = Geom::Vector3d.new(0, 0, 1)
long_axis_vec = (w > h) ? Geom::Vector3d.new(1, 0, 0) : Geom::Vector3d.new(0, 1, 0)
len = [w, h].max
end
drill_points = []
hole_count = [1, hole_count.to_i].max
max_drill_length = len - (offset * 2)
if hole_count == 1 || max_drill_length < 0.mm
drill_points << center
else
spacing = max_drill_length / (hole_count - 1).to_f
start_dist_from_center = (len / 2.0) - offset
start_point = center - long_axis_vec.clone.tap { |v| v.length = start_dist_from_center }
(0...hole_count).each do |i|
current_offset = long_axis_vec.clone.tap { |v| v.length = i * spacing }
drill_points << start_point + current_offset
end
end
[ent1, ent2].each do |ent|
defn = ent.respond_to?(:definition) ? ent.definition : ent.entities.parent
trans_inv = ent.transformation.inverse
current_diameter = self.get_diameter(ent, drill_axis, cam_diameter, screw_diameter)
drill_points.each do |global_pt|
local_pt = global_pt.transform(trans_inv)
local_axis = drill_axis.transform(trans_inv)
# Вынос на внешнюю сторону для отверстий в пласть
if current_diameter == cam_diameter
bounds = defn.bounds
bounds_center = bounds.center
axis_idx = local_axis.to_a.map(&:abs).each_with_index.max[1]
dir_val = bounds_center[axis_idx] - local_pt[axis_idx]
dir_val = 1.0 if dir_val.abs < 0.0001
target_coordinate = (dir_val > 0) ? bounds.max[axis_idx] : bounds.min[axis_idx]
local_pt[axis_idx] = target_coordinate
end
# 1. Создаем само отверстие (круг)
circle = defn.entities.add_circle(local_pt, local_axis, current_diameter / 2.0)
cpoint = defn.entities.add_cpoint(local_pt)
circle.each { |e| e.set_attribute('ABFDrill', 'Type', 'DrillHole') }
cpoint.set_attribute('ABFDrill', 'Type', 'DrillHole')
# 2. Логика для рисования прямоугольника-проекции (только линии)
if current_diameter == screw_diameter && marker_length > 0.0.mm
bounds = defn.bounds
# Определяем ось толщины (самая короткая сторона)
b_dims = [bounds.width, bounds.height, bounds.depth]
min_b_dim = b_dims.min
thick_axis_idx = b_dims.index(min_b_dim)
# Вектор нормали к грани (ось толщины)
face_normal = Geom::Vector3d.new(0,0,0)
face_normal[thick_axis_idx] = 1
# Вектор "ширины" прямоугольника
width_vec = local_axis.cross(face_normal)
if width_vec.length > 0.001
width_vec.length = current_diameter / 2.0
# Вектор "длины" маркера, используем значение из инпута
marker_len_vec = local_axis.clone
# Направление: Внутрь детали
vec_to_center = bounds.center - local_pt
if vec_to_center.dot(marker_len_vec) < 0
marker_len_vec.reverse!
end
marker_len_vec.length = marker_length
# Рисуем прямоугольники на обеих плоскостях
faces_coords = [bounds.min[thick_axis_idx], bounds.max[thick_axis_idx]]
faces_coords.each do |z_coord|
pt_on_face = local_pt.clone
pt_on_face[thick_axis_idx] = z_coord
# 4 точки прямоугольника
p1 = pt_on_face + width_vec
p2 = pt_on_face - width_vec
p3 = p2 + marker_len_vec
p4 = p1 + marker_len_vec
# Создаем группу для маркера
m_group = defn.entities.add_group
# Создаем Face, чтобы потом его удалить, но сохранить Edges
m_face = m_group.entities.add_face(p1, p2, p3, p4)
if m_face
# УДАЛЯЕМ ГРАНЬ, ОСТАВЛЯЯ ТОЛЬКО ЛИНИИ (Edges)
m_face.erase!
# Метим группу как DrillHole для очистки
m_group.set_attribute('ABFDrill', 'Type', 'DrillHole')
else
# Если грань не создалась, удаляем пустую группу
m_group.erase!
end
end
end
end
# --- КОНЕЦ ЛОГИКИ ПРЯМОУГОЛЬНИКА ---
end
end
return true
end
# --- ИСПРАВЛЕННЫЙ МЕТОД: Рисование компенсированного круга ---
# Этот метод создает круг, который останется кругом даже после не-униформного масштабирования
def self.draw_drill_hole_geometry(entity, center_pt, radius, normal_axis, type_tag)
defn_entities = entity.respond_to?(:definition) ? entity.definition.entities : entity.entities
trans = entity.transformation
# 1. Получаем обратную трансформацию для компенсации масштабирования
inv_trans = trans.inverse
# 2. Получаем мировые оси, преобразованные в локальные координаты определения
world_axes = [
Geom::Vector3d.new(1, 0, 0),
Geom::Vector3d.new(0, 1, 0),
Geom::Vector3d.new(0, 0, 1)
]
# 3. Преобразуем нормаль в мировые координаты
world_normal = normal_axis.transform(trans)
# 4. Находим две оси, ортогональные нормали (в мировых координатах)
world_axes_in_plane = world_axes.reject { |axis| axis.parallel?(world_normal) }
if world_axes_in_plane.length < 2
# Если не можем найти оси, используем альтернативный метод
world_axes_in_plane = [
world_normal.axes[0],
world_normal.axes[1]
]
end
axis1 = world_axes_in_plane[0]
axis2 = world_axes_in_plane[1]
# 5. Преобразуем оси обратно в локальные координаты определения
local_axis1 = axis1.transform(inv_trans)
local_axis2 = axis2.transform(inv_trans)
# 6. Нормализуем оси
local_axis1.normalize!
local_axis2.normalize!
# 7. Убеждаемся, что оси ортогональны
if local_axis1.dot(local_axis2) > 0.001
# Делаем axis2 ортогональным axis1
local_axis2 = local_axis2 - local_axis1 * local_axis1.dot(local_axis2)
local_axis2.normalize!
end
# 8. Создаем круг с использованием add_circle (который Sketchup корректно масштабирует)
# Вместо попытки компенсировать масштабирование, мы рисуем круг в определении,
# и Sketchup сам правильно масштабирует его при любом трансформировании экземпляра
circle = defn_entities.add_circle(center_pt, normal_axis, radius)
circle.each { |e| e.set_attribute('ABFDrill', 'Type', type_tag) }
# 9. Добавляем CPoint
cpoint = defn_entities.add_cpoint(center_pt)
cpoint.set_attribute('ABFDrill', 'Type', type_tag)
return true
end
# --- ГЛАВНЫЙ ПРОЦЕСС ДЛЯ ПЕТЕЛЬ ---
def self.process_hinge_holes(count, diameter_mm, length_offset_mm, side_offset_mm, screw_diameter_mm, screw_spacing_mm, screw_vert_offset_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
if items.empty?
UI.messagebox("Выберите один или несколько компонентов для установки петель.")
return
end
model.start_operation("ABF Style Add Hinges", true)
# Очищаем только петли на выделенных компонентах
items.each { |ent| self.cleanup_hinge_drill_geometry(ent) }
items.each do |entity|
self.apply_hinge_holes(entity, count.to_i, diameter_mm.mm, length_offset_mm.mm, side_offset_mm.mm, screw_diameter_mm.mm, screw_spacing_mm.mm, screw_vert_offset_mm.mm)
end
model.commit_operation
rescue => e
UI.messagebox("Ошибка при создании петель: #{e.message}")
model.abort_operation
end
# --- ЛОГИКА ДЛЯ СОЗДАНИЯ ОТВЕРСТИЙ ПОД ПЕТЛИ ---
def self.apply_hinge_holes(entity, count, diameter, length_offset, side_offset, screw_diameter, screw_spacing, screw_vert_offset)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
bounds = defn.bounds
# 1. Определяем оси компонента в локальных координатах
dims = [bounds.width, bounds.height, bounds.depth]
# Ось толщины (самая короткая) - Нормаль круга
min_dim = dims.min
thick_axis_idx = dims.index(min_dim)
thick_axis = Geom::Vector3d.new(0,0,0)
thick_axis[thick_axis_idx] = 1.0
# Ось длины (самая длинная) - Ось для распределения петель
max_dim = dims.max
long_axis_idx = dims.index(max_dim)
long_axis = Geom::Vector3d.new(0,0,0)
long_axis[long_axis_idx] = 1.0
# Ось ширины (средняя) - Ось для смещения 21.5мм и смещения саморезов
mid_dim = dims.sort[1]
mid_axis_idx = dims.index(mid_dim)
mid_axis = Geom::Vector3d.new(0,0,0)
mid_axis[mid_axis_idx] = 1.0
# 2. Определяем плоскость для отверстий (по центру толщины)
center_point = bounds.center.clone
# 3. Определяем начальную точку и направление (Вдоль длинной оси)
# Начальная координата для смещения по длине
start_coord_length = bounds.min[long_axis_idx]
offset_vec_length = long_axis.clone
offset_vec_length.length = length_offset
start_point_length = center_point.clone
start_point_length[long_axis_idx] = start_coord_length
start_point_length = start_point_length + offset_vec_length
# 4. Рассчитываем точки для всех петель (Вдоль длинной оси)
hole_points_length = []
length = max_dim
count = [1, count].max
if count == 1
hole_points_length << center_point
else
# Расстояние между центрами петель
remaining_length = length - (length_offset * 2)
if remaining_length < 0.mm
hole_points_length << center_point
else
spacing = remaining_length / (count - 1).to_f
(0...count).each do |i|
current_point = start_point_length + long_axis.clone.tap { |v| v.length = i * spacing }
hole_points_length << current_point
end
end
end
# 5. Применяем смещение по боковой оси (side_offset)
# Начальная координата по средней оси (от которой отсчитываем 21.5мм)
start_coord_side = bounds.min[mid_axis_idx]
# Вектор смещения по средней оси
side_offset_vec = mid_axis.clone
side_offset_vec.length = side_offset
# Точка, смещенная от края по средней оси
side_offset_point = center_point.clone
side_offset_point[mid_axis_idx] = start_coord_side
side_offset_point = side_offset_point + side_offset_vec
# Координата поверхности (max координата по оси толщины)
surface_coord = bounds.max[thick_axis_idx]
hole_points_length.each do |local_pt_length|
final_pt = local_pt_length.clone
# Устанавливаем координату по средней оси (смещение 21.5мм)
final_pt[mid_axis_idx] = side_offset_point[mid_axis_idx]
# Устанавливаем координату по оси толщины (на поверхность)
final_pt[thick_axis_idx] = surface_coord
# 1. Создаем отверстие под чашку (круг 35мм) - ИСПОЛЬЗУЕМ КОМПЕНСАЦИЮ
self.draw_drill_hole_geometry(entity, final_pt, diameter / 2.0, thick_axis, 'HingeHole')
# --- ЛОГИКА ДЛЯ ОТВЕРСТИЙ ПОД САМОРЕЗЫ ---
half_spacing = screw_spacing / 2.0
# Вектор смещения "выше чашки" (вдоль mid_axis)
shift_vec = mid_axis.clone
shift_vec.length = screw_vert_offset
# Базовые точки вдоль длинной оси (long_axis), центрированные на final_pt
pt1_base = final_pt - long_axis.clone.tap { |v| v.length = half_spacing }
pt2_base = final_pt + long_axis.clone.tap { |v| v.length = half_spacing }
# Применяем вертикальное смещение (shift_vec) к обеим точкам
pt1 = pt1_base + shift_vec
pt2 = pt2_base + shift_vec
[pt1, pt2].each do |screw_pt|
# Создаем отверстие под саморез (круг) - ИСПОЛЬЗУЕМ КОМПЕНСАЦИЮ
self.draw_drill_hole_geometry(entity, screw_pt, screw_diameter / 2.0, thick_axis, 'HingeHole')
end
# --- КОНЕЦ ЛОГИКИ САМОРЕЗОВ ---
end
end
# --- НОВЫЙ ГЛАВНЫЙ ПРОЦЕСС ДЛЯ ПЛАНКИ (ОБНОВЛЕНО) ---
# Изменено: hinge_count и hinge_offset_mm заменены на count и length_offset_mm
def self.process_strip_holes(diameter_mm, spacing_mm, side_offset_mm, count, length_offset_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
if items.length != 1
UI.messagebox("Выберите ОДИН компонент для установки отверстий под планку.")
# Очищаем на всех выделенных, если их больше одного, или если ничего не выбрано
model.start_operation("ABF Strip Drill Cleanup", true)
items.each { |ent| self.cleanup_strip_drill_geometry(ent) }
model.commit_operation
return
end
entity = items.first
model.start_operation("ABF Style Add Strip Holes", true)
self.cleanup_strip_drill_geometry(entity) # Очистка перед созданием
# Передаем параметры для позиционирования
self.apply_strip_holes(entity, diameter_mm.mm, spacing_mm.mm, side_offset_mm.mm, count.to_i, length_offset_mm.mm)
model.commit_operation
rescue => e
UI.messagebox("Ошибка при создании отверстий под планку: #{e.message}")
model.abort_operation
end
# --- НОВАЯ ЛОГИКА ДЛЯ СОЗДАНИЯ ОТВЕРСТИЙ ПОД ПЛАНКУ (ОБНОВЛЕНО) ---
# Изменено: hinge_count и hinge_offset заменены на count и length_offset
def self.apply_strip_holes(entity, diameter, spacing, side_offset, count, length_offset)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
bounds = defn.bounds
# 1. Определяем оси компонента в локальных координатах
dims = [bounds.width, bounds.height, bounds.depth]
# Ось толщины (самая короткая) - Ось сверления (Normal)
min_dim = dims.min
thick_axis_idx = dims.index(min_dim)
thick_axis = Geom::Vector3d.new(0,0,0)
thick_axis[thick_axis_idx] = 1.0
# Ось длины (самая длинная) - Ось для распределения петель/планок
max_dim = dims.max
long_axis_idx = dims.index(max_dim)
long_axis = Geom::Vector3d.new(0,0,0)
long_axis[long_axis_idx] = 1.0
# Ось ширины (средняя) - Ось для смещения от края (Side Offset)
mid_dim = dims.sort[1]
mid_axis_idx = dims.index(mid_dim)
mid_axis = Geom::Vector3d.new(0,0,0)
mid_axis[mid_axis_idx] = 1.0
# 2. Расчет позиций центров планок вдоль длинной оси (long_axis)
center_point = bounds.center.clone
length = max_dim
count = [1, count].max
hole_points_length = [] # Это будут центры пар отверстий планки
if count == 1
# Если одна планка, то центр планки совпадает с центром компонента по длине
hole_points_length << center_point
else
# Начальная координата для смещения по длине (от короткого края)
start_coord_length = bounds.min[long_axis_idx]
offset_vec_length = long_axis.clone
offset_vec_length.length = length_offset # Используем новое смещение
start_point_length = center_point.clone
start_point_length[long_axis_idx] = start_coord_length
start_point_length = start_point_length + offset_vec_length
# Расстояние между центрами планок
remaining_length = length - (length_offset * 2) # Используем новое смещение
if remaining_length < 0.mm
hole_points_length << center_point
else
spacing_strip = remaining_length / (count - 1).to_f
(0...count).each do |i|
# current_point - это центр пары планки по длинной оси
current_point = start_point_length + long_axis.clone.tap { |v| v.length = i * spacing_strip }
hole_points_length << current_point
end
end
end
# 3. Определяем координаты для смещения 37мм (Side Offset)
# Начальная координата по средней оси (от которой отсчитываем 37мм)
start_coord_side = bounds.min[mid_axis_idx]
# Координата центра отверстий по средней оси (37мм от края)
side_coord = start_coord_side + side_offset
# 4. Определяем координату поверхности (по оси толщины)
# Отверстия сверлятся в пласть, поэтому берем max координату по оси толщины
surface_coord = bounds.max[thick_axis_idx]
# 5. Создаем точки и отверстия
half_spacing = spacing / 2.0 # Половина межосевого расстояния планки (32/2 = 16мм)
# hole_points_length - это центры пар планок
hole_points_length.each do |center_pt_long_axis|
# Координата центра пары отверстий по длинной оси
center_coord_length = center_pt_long_axis[long_axis_idx]
# --- НОВОЕ: Создание точки в центре между отверстиями планки ---
final_center_pt = Geom::Point3d.new(0, 0, 0)
final_center_pt[long_axis_idx] = center_coord_length
final_center_pt[mid_axis_idx] = side_coord
final_center_pt[thick_axis_idx] = surface_coord
cpoint = defn.entities.add_cpoint(final_center_pt)
cpoint.set_attribute('ABFDrill', 'Type', 'StripHole')
# --- КОНЕЦ НОВОГО БЛОКА ---
# Координаты центров отверстий по длинной оси (смещение +/- 16мм)
length_coord_1 = center_coord_length - half_spacing
length_coord_2 = center_coord_length + half_spacing
hole_coords_length = [length_coord_1, length_coord_2]
# Создаем пару отверстий
hole_coords_length.each do |length_coord|
final_pt = Geom::Point3d.new(0, 0, 0)
# Устанавливаем координаты
final_pt[long_axis_idx] = length_coord # Смещение +/- 16мм от центра
final_pt[mid_axis_idx] = side_coord # Смещение 37мм от края
final_pt[thick_axis_idx] = surface_coord # На поверхности
# Создаем отверстие - ИСПОЛЬЗУЕМ КОМПЕНСАЦИЮ
self.draw_drill_hole_geometry(entity, final_pt, diameter / 2.0, thick_axis, 'StripHole')
end
end
end
# --- МЕТОД: Аннотации (обновлен для включения StripHole) ---
def self.show_drill_annotations
model = Sketchup.active_model
entities = model.active_entities
selection = model.selection
model.start_operation('Проставить/Удалить Аннотации Присадок', true)
if @annotations_visible
self.cleanup_annotations(entities)
@annotations_visible = false
model.commit_operation
UI.messagebox("Аннотации размеров удалены.")
return
end
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
if items.empty?
UI.messagebox("Выберите компоненты.")
model.abort_operation
return
end
self.cleanup_annotations(entities)
base_offset_distance = 50.mm
step_size = 50.mm
items.each do |entity|
bb = entity.bounds
bb_center = bb.center
defn_entities = entity.respond_to?(:definition) ? entity.definition.entities : entity.entities
# Общие размеры
overall_offset_y = -350.mm
start_pt_x = Geom::Point3d.new(bb.min.x, bb.min.y, bb.min.z)
end_pt_x = Geom::Point3d.new(bb.max.x, bb.min.y, bb.min.z)
offset_x = Geom::Vector3d.new(0, overall_offset_y, 0)
dim_overall_x = entities.add_dimension_linear(start_pt_x, end_pt_x, offset_x)
dim_overall_x.set_attribute('ABFDrill', 'Type', 'Dimension')
overall_offset_x = -350.mm
start_pt_y = Geom::Point3d.new(bb.min.x, bb.min.y, bb.min.z)
end_pt_y = Geom::Point3d.new(bb.min.x, bb.max.y, bb.min.z)
offset_y = Geom::Vector3d.new(overall_offset_x, 0, 0)
dim_overall_y = entities.add_dimension_linear(start_pt_y, end_pt_y, offset_y)
dim_overall_y.set_attribute('ABFDrill', 'Type', 'Dimension')
# Размеры до отверстий
# Собираем все точки присадки, петель и планки
drill_cpoints = defn_entities.grep(Sketchup::ConstructionPoint).select do |e|
type = e.get_attribute('ABFDrill', 'Type')
type == 'DrillHole' || type == 'HingeHole' || type == 'StripHole'
end
dimensions_to_place = []
drill_cpoints.each do |cpoint|
hole_pt = cpoint.position.transform(entity.transformation)
# X Dimension
dist_from_min_x = hole_pt.x - bb.min.x
dist_from_max_x = bb.max.x - hole_pt.x
if dist_from_min_x <= dist_from_max_x
start_pt_x = Geom::Point3d.new(bb.min.x, hole_pt.y, hole_pt.z)
value_x = dist_from_min_x
else
start_pt_x = Geom::Point3d.new(bb.max.x, hole_pt.y, hole_pt.z)
value_x = dist_from_max_x
end
direction_x = (hole_pt.y > bb_center.y) ? :Up : :Down
if value_x.abs > 0.001.mm
dimensions_to_place << { :type => :X, :value => value_x, :start_pt => start_pt_x, :end_pt => hole_pt, :direction => direction_x }
end
# Y Dimension
dist_from_min_y = hole_pt.y - bb.min.y
dist_from_max_y = bb.max.y - hole_pt.y
if dist_from_min_y <= dist_from_max_y
start_pt_y = Geom::Point3d.new(hole_pt.x, bb.min.y, hole_pt.z)
value_y = dist_from_min_y
else
start_pt_y = Geom::Point3d.new(hole_pt.x, bb.max.y, hole_pt.z)
value_y = dist_from_max_y
end
direction_y = (hole_pt.x > bb_center.x) ? :Right : :Left
if value_y.abs > 0.001.mm
dimensions_to_place << { :type => :Y, :value => value_y, :start_pt => start_pt_y, :end_pt => hole_pt, :direction => direction_y }
end
end
grouped_dims = dimensions_to_place.group_by { |d| d[:direction] }
step_counters = { :Up => 0, :Down => 0, :Right => 0, :Left => 0 }
grouped_dims.each do |direction, dims|
dims.sort_by! { |d| d[:value] }
dims.each do |d|
step = step_counters[direction]
offset_val = base_offset_distance + step * step_size
offset_vec = case direction
when :Up then Geom::Vector3d.new(0, offset_val, 0)
when :Down then Geom::Vector3d.new(0, -offset_val, 0)
when :Right then Geom::Vector3d.new(offset_val, 0, 0)
when :Left then Geom::Vector3d.new(-offset_val, 0, 0)
end
dim = entities.add_dimension_linear(d[:start_pt], d[:end_pt], offset_vec)
dim.set_attribute('ABFDrill', 'Type', 'Dimension')
step_counters[direction] += 1
end
end
end
@annotations_visible = true
model.commit_operation
UI.messagebox("Аннотации проставлены.")
rescue => e
UI.messagebox("Ошибка: #{e.message}")
model.abort_operation
end
# --- МЕТОД: Раскладка (без изменений) ---
def self.line_up_components
model = Sketchup.active_model
selection = model.selection
entities_to_line_up = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
if entities_to_line_up.empty?
UI.messagebox("Выберите компоненты.")
return
end
model.start_operation('Разложить в линию', true)
begin
self.cleanup_annotations(model.active_entities)
@annotations_visible = false
entities_to_line_up.sort_by! do |e|
b = e.bounds
[b.width, b.height, b.depth].max
end
cursor_x = 0.0
gap = GAP
entities_to_line_up.each do |entity|
# Сброс трансформации (включая масштабирование) - это гарантирует,
# что круги, нарисованные в определении, будут выглядеть как круги.
entity.transformation = Geom::Transformation.new
bounds = entity.bounds
dims = [bounds.width, bounds.height, bounds.depth]
smallest_idx = dims.each_with_index.min[1]
rot_flat = Geom::Transformation.new
if smallest_idx == 0
rot_flat = Geom::Transformation.rotation(bounds.center, Geom::Vector3d.new(0, 1, 0), -90.degrees)
elsif smallest_idx == 1
rot_flat = Geom::Transformation.rotation(bounds.center, Geom::Vector3d.new(1, 0, 0), 90.degrees)
end
entity.transform!(rot_flat)
bounds = entity.bounds
rot_orient = Geom::Transformation.new
if bounds.width < bounds.height
rot_orient = Geom::Transformation.rotation(bounds.center, Geom::Vector3d.new(0, 0, 1), 90.degrees)
end
entity.transform!(rot_orient)
bounds = entity.bounds
move_vec = Geom::Vector3d.new(cursor_x - bounds.min.x, -bounds.min.y, -bounds.min.z)
entity.transform!(Geom::Transformation.translation(move_vec))
cursor_x = entity.bounds.max.x + gap
end
model.active_view.zoom(entities_to_line_up)
rescue => e
UI.messagebox("Ошибка: #{e.message}")
ensure
model.commit_operation
end
end
unless file_loaded?(__FILE__)
menu = UI.menu('Plugins')
menu.add_item('ABF Style Drill & Hinges') { self.show_dialog }
file_loaded(__FILE__)
end
end
Collaborator
|
Closing due to errors, no explanations and apparent bot automation. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Здесь сделай чтоб присадку делал согласно локальных координат компонентов, так как сейчас на повёрнутых под определённый градус угла компонентах не делает присадок потому что делает присадку согласно мировых координат что не допустимо. Пиши полный код целиком.
require 'sketchup.rb'
require 'extensions.rb'
module ABFStyleDrill
Настройки по умолчанию
DEFAULTS = {
:cam_diameter => 8.0, # Диаметр отверстия в пласть (Cam)
:screw_diameter => 5.0, # Диаметр отверстия в торец (Screw)
:offset => 50.0, # Отступ от края детали для присадки
:hole_count => 2, # Количество присадочных отверстий
:marker_length => 15.0, # Длина проекции (маркера) для торцевого отверстия
}
Константа для зазора между деталями при раскладке
GAP = 500.0.mm
Переменная для отслеживания состояния аннотаций
@annotations_visible = false
--- МЕТОД: Очистка ранее созданных аннотаций (размеров) ---
def self.cleanup_annotations(entities)
entities_to_remove = []
entities.each do |e|
if e.is_a?(Sketchup::DimensionLinear) && e.get_attribute('ABFDrill', 'Type') == 'Dimension'
entities_to_remove << e
end
end
entities.erase_entities(entities_to_remove) if entities_to_remove.any?
end
--- МЕТОД: Очистка только стандартных присадочных отверстий и маркеров ---
def self.cleanup_standard_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
end
--- МЕТОД: Очистка только отверстий под петли ---
def self.cleanup_hinge_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
end
--- НОВЫЙ МЕТОД: Очистка только отверстий под планку ---
def self.cleanup_strip_drill_geometry(entity)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
entities_to_remove = []
end
--- МЕТОД: Отображение диалогового окна (Обновлено для передачи параметров петель в планку) ---
def self.show_dialog
dialog = UI::HtmlDialog.new(
{
:dialog_title => "ABF Style Drill & Hinges",
:preferences_key => "com.abfstyle.drill",
:scrollable => true,
:resizable => true,
:width => 350,
:height => 850, # Увеличена высота для новых настроек
:style => UI::HtmlDialog::STYLE_DIALOG
}
)
end
--- ГЛАВНЫЙ ПРОЦЕСС ПРИСАДКИ (Minifix) ---
def self.process_model(cam_diameter_mm, screw_diameter_mm, offset_mm, hole_count, marker_length_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
end
... (get_diameter остается без изменений)
def self.get_diameter(entity, global_drill_axis, cam_dia, screw_dia)
trans_inv = entity.transformation.inverse
local_drill_axis = global_drill_axis.transform(trans_inv)
bb_local = entity.bounds
w, h, d = bb_local.width, bb_local.height, bb_local.depth
dims = { w => Geom::Vector3d.new(1, 0, 0), h => Geom::Vector3d.new(0, 1, 0), d => Geom::Vector3d.new(0, 0, 1) }
min_dim = dims.keys.min
local_thickness_axis = dims[min_dim]
dot_product = local_drill_axis.dot(local_thickness_axis).abs
return (dot_product > 0.999) ? cam_dia : screw_dia
end
--- ОСНОВНАЯ ЛОГИКА ПРИСАДКИ И ГЕОМЕТРИИ (Minifix) ---
def self.apply_drill_to_pair(ent1, ent2, cam_diameter, screw_diameter, offset, hole_count, marker_length)
bb1 = ent1.bounds
bb2 = ent2.bounds
intersect = bb1.intersect(bb2)
return false if intersect.empty?
end
--- ИСПРАВЛЕННЫЙ МЕТОД: Рисование компенсированного круга ---
Этот метод создает круг, который останется кругом даже после не-униформного масштабирования
def self.draw_drill_hole_geometry(entity, center_pt, radius, normal_axis, type_tag)
defn_entities = entity.respond_to?(:definition) ? entity.definition.entities : entity.entities
trans = entity.transformation
end
--- ГЛАВНЫЙ ПРОЦЕСС ДЛЯ ПЕТЕЛЬ ---
def self.process_hinge_holes(count, diameter_mm, length_offset_mm, side_offset_mm, screw_diameter_mm, screw_spacing_mm, screw_vert_offset_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
rescue => e
UI.messagebox("Ошибка при создании петель: #{e.message}")
model.abort_operation
end
--- ЛОГИКА ДЛЯ СОЗДАНИЯ ОТВЕРСТИЙ ПОД ПЕТЛИ ---
def self.apply_hinge_holes(entity, count, diameter, length_offset, side_offset, screw_diameter, screw_spacing, screw_vert_offset)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
bounds = defn.bounds
end
--- НОВЫЙ ГЛАВНЫЙ ПРОЦЕСС ДЛЯ ПЛАНКИ (ОБНОВЛЕНО) ---
Изменено: hinge_count и hinge_offset_mm заменены на count и length_offset_mm
def self.process_strip_holes(diameter_mm, spacing_mm, side_offset_mm, count, length_offset_mm)
model = Sketchup.active_model
selection = model.selection
items = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
rescue => e
UI.messagebox("Ошибка при создании отверстий под планку: #{e.message}")
model.abort_operation
end
--- НОВАЯ ЛОГИКА ДЛЯ СОЗДАНИЯ ОТВЕРСТИЙ ПОД ПЛАНКУ (ОБНОВЛЕНО) ---
Изменено: hinge_count и hinge_offset заменены на count и length_offset
def self.apply_strip_holes(entity, diameter, spacing, side_offset, count, length_offset)
defn = entity.respond_to?(:definition) ? entity.definition : entity.entities.parent
bounds = defn.bounds
end
--- МЕТОД: Аннотации (обновлен для включения StripHole) ---
def self.show_drill_annotations
model = Sketchup.active_model
entities = model.active_entities
selection = model.selection
rescue => e
UI.messagebox("Ошибка: #{e.message}")
model.abort_operation
end
--- МЕТОД: Раскладка (без изменений) ---
def self.line_up_components
model = Sketchup.active_model
selection = model.selection
entities_to_line_up = selection.grep(Sketchup::ComponentInstance) + selection.grep(Sketchup::Group)
end
unless file_loaded?(FILE)
menu = UI.menu('Plugins')
menu.add_item('ABF Style Drill & Hinges') { self.show_dialog }
file_loaded(FILE)
end
end
Why are these changes needed?
Related issue number
Checks