# Function to transform faces in @new_faces to global coordinates
def transform_faces_to_global
return unless @new_faces # Ensure there is data to process
@new_faces.each do |face|
next unless face.valid? # Skip deleted faces
parent = face.parent
next unless parent.valid? # Skip if parent has also been deleted
# Get the appropriate transformation by iterating over the entire path of the face
transformation = case parent
when Sketchup::Model
Geom::Transformation.new # If the face is in the parent model
when Sketchup::Group, Sketchup::ComponentInstance
cumulative_transformation = parent.transformation
current = parent
# Iterate over parent objects if they exist and have transformation
while current.respond_to?(:parent) && current.parent.respond_to?(:transformation)
current = current.parent
cumulative_transformation = current.transformation * cumulative_transformation
end
cumulative_transformation
when Sketchup::ComponentDefinition
# Get the transformation from the first instance of ComponentDefinition (if any)
parent.instances.first&.transformation || Geom::Transformation.new
else
Geom::Transformation.new # Default if not recognized
end
# Transform face vertex coordinates to global coordinates
global_vertices = face.vertices.map { |v| v.position.transform(transformation) }
# Debugging log (if needed)
# puts "🔹 Face #{face} has global coordinates:"
# global_vertices.each_with_index do |point, index|
# puts " - Point #{index + 1}: (#{point.x.to_m}, #{point.y.to_m}, #{point.z.to_m})"
# end
end
end
def get_face_transformation(face)
return Geom::Transformation.new unless face&.valid? && @selected_faces.include?(face)
parent = face.parent
transformation = Geom::Transformation.new
case parent
when Sketchup::ComponentDefinition
# Get the transformation from the first instance of ComponentDefinition if there is one
instance = parent.instances.first
if instance && instance.valid?
transformation = instance.transformation
current = instance
while current.respond_to?(:parent) && current.parent.respond_to?(:transformation)
current = current.parent
transformation = current.transformation * transformation
end
end
when Sketchup::Group, Sketchup::ComponentInstance
transformation = parent.transformation
current = parent
while current.respond_to?(:parent) && current.parent.respond_to?(:transformation)
current = current.parent
transformation = current.transformation * transformation
end
else. else
transformation = Geom::Transformation.new
end
transformation. transformation
end
# --- Helper functions ---
# --- Draw Function ---
# --- Draw Function ---
def draw(view)
# 1) Redraw the main face (if any)
if @selected_face && @selected_face.valid?
draw_face_2d(view, @selected_face, @selected_transformation)
end
# 2) Check state to draw preview
preview_distance = nil
if @dragging # If dragging, prioritize @pushpull_distance and cancel @user_pull_distance
@user_pull_distance = nil # Cancel preview from user input
preview_distance = @pushpull_distance
elsif @user_pull_distance # If not dragging but has @user_pull_distance, use it
preview_distance = @user_pull_distance
end
# If there is a valid preview distance, draw preview
if @selected_face && preview_distance
draw_drag_preview(view, @selected_face, preview_distance, @selected_transformation)
end
return unless @selected_faces && !@selected_faces.empty?
transform_faces_to_global # Transform coordinates before drawing
# 3) Draw new faces created after Push/Pull
if @new_faces && !@new_faces.empty?
view.drawing_color = "blue"
@new_faces.each do |face|
next unless face.valid? && @selected_faces.include?(face)
transformation = get_face_transformation(face)
draw_face_2d(view, face, transformation)
# Check status to draw preview
preview_distance = nil
if @dragging
@user_pull_distance = nil # Remove preview from user input when dragging
preview_distance = @pushpull_distance
elsif @user_pull_distance
preview_distance = @user_pull_distance
end
if preview_distance
draw_drag_preview(view, face, preview_distance, transformation)
end
end
end
#4) Redraw all selected faces
@selected_faces.each do |face|
next unless face.valid?
transformation = get_face_transformation(face)
draw_face_2d(view, face, transformation)
# Check status to draw preview
preview_distance = nil
if @dragging
@user_pull_distance = nil # Remove preview from user input when dragging
preview_distance = @pushpull_distance
elsif @user_pull_distance
preview_distance = @user_pull_distance
end
if preview_distance
draw_drag_preview(view, face, preview_distance, transformation)
end
end
end
Post code correctly in the forum and please edit your previous post.
…
…
This when
clause will never be true as group and component instrances do not have an Entities
collection. Only their “parent” definitions do.
(a) Please make your topic title more concise and put the lenghty question or challenge statement in the opening post.
(b) You cannot build a composite transformation from the bottom back up to the model root. You need to build an InstanecPath
array from the root down to the leaf instance as the user “drills” down.
This has been covered multiple times here in this category.
1 Like
tks Dan, I modified the condition, the problem is that I only apply the transform to the parent group and ignore its child groups.