概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
dxfエクスポーター、見つけたので、やってみた。
読み込みは、sketchup6でOK。
写真
サンプルコード
起動 dxf_export_mesh_file
require 'sketchup.rb'
def dxf_export_mesh_file
model = Sketchup.active_model
model_filename = File.basename(model.path)
if(model_filename == "")
model_filename = "model"
end
ss = model.selection
$stl_conv = 1.0
$group_count = 0
$component_count = 0
$face_count = 0
$line_count = 0
entities = model.entities
if ss.empty?
answer = UI.messagebox("No objects selected. Export entire model?", MB_YESNOCANCEL)
if(answer == 6)
export_ents = model.entities
else
export_ents = ss
end
else
export_ents = Sketchup.active_model.selection
end
if (export_ents.length > 0)
dxf_dxf_units_dialog
dxf_option = dxf_dxf_options_dialog
if (dxf_option == "stl")
file_type = "stl"
else
file_type = "dxf"
end
out_name = UI.savepanel(file_type.upcase + " file location", "" , "#{File.basename(model.path).split(".")[0]}untitled." + file_type)
if out_name
$mesh_file = File.new(out_name , "w")
model_name = model_filename.split(".")[0]
dxf_header(dxf_option, model_name)
others = dxf_find_faces(0, export_ents, Geom::Transformation.new(), model.active_layer.name, dxf_option)
dxf_end(dxf_option, model_name)
UI.messagebox($face_count.to_s + " faces exported " + $line_count.to_s + " lines exported\n" + others.to_s + " objects ignored")
end
end
model.commit_operation
end
def dxf_find_faces(others, entities, tform, layername, dxf_option)
entities.each do |entity|
if(entity.is_a?(Sketchup::Face))
case dxf_option
when "polylines"
dxf_write_polyline(entity, tform, layername)
when "polyface mesh"
dxf_write_polyface(entity, tform, layername)
when "triangular mesh"
dxf_write_face(entity, tform, layername)
when "stl"
dxf_write_stl(entity, tform)
end
elsif(entity.typename == "Edge") and((dxf_option == "lines") or (entity.faces.length == 0 and dxf_option != "stl"))
dxf_write_edge(entity, tform, layername)
elsif entity.is_a?(Sketchup::Group) || entity.is_a?(Sketchup::ComponentInstance)
if entity.is_a?(Sketchup::Group)
definition = entity.entities.parent
else
definition = entity.definition
end
layer = (entity.name.empty?) ? definition.name : entity.name
others = dxf_find_faces(others, definition.entities, tform * entity.transformation, layer, dxf_option)
else
others = others + 1
end
end
others
end
def dxf_transform_edge(edge, tform)
points = []
points.push(dxf_transform_vertex(edge.start, tform))
points.push(dxf_transform_vertex(edge.end, tform))
points
end
def dxf_transform_vertex(vertex, tform)
point = Geom::Point3d.new(vertex.position.x, vertex.position.y, vertex.position.z)
point.transform! tform
point
end
def dxf_write_edge(edge, tform, layername)
points = dxf_transform_edge(edge, tform)
$mesh_file.puts(" 0\nLINE\n 8\n" + layername + "\n")
for j in 0..1 do
$mesh_file.puts((10 + j).to_s + "\n" + (points[j].x.to_f * $stl_conv).to_s)
$mesh_file.puts((20 + j).to_s + "\n" + (points[j].y.to_f * $stl_conv).to_s)
$mesh_file.puts((30 + j).to_s + "\n" + (points[j].z.to_f * $stl_conv).to_s)
end
$line_count += 1
end
def dxf_write_polyline(face, tform, layername)
face.loops.each do |aloop|
$mesh_file.puts(" 0\nPOLYLINE\n 8\n" + layername + "\n 66\n 1")
$mesh_file.puts("70\n 8\n 10\n0.0\n 20\n 0.0\n 30\n0.0")
for j in 0..aloop.vertices.length do
if (j == aloop.vertices.length)
count = 0
else
count = j
end
point = dxf_transform_vertex(aloop.vertices[count], tform)
$mesh_file.puts(" 0\nVERTEX\n 8\nMY3DLAYER")
$mesh_file.puts("10\n" + (point.x.to_f * $stl_conv).to_s)
$mesh_file.puts("20\n" + (point.y.to_f * $stl_conv).to_s)
$mesh_file.puts("30\n" + (point.z.to_f * $stl_conv).to_s)
$mesh_file.puts(" 70\n 32")
end
if (aloop.vertices.length > 0)
$mesh_file.puts(" 0\nSEQEND")
end
end
$face_count += 1
end
def dxf_write_face(face, tform, layername)
mesh = face.mesh 0
mesh.transform! tform
polygons = mesh.polygons
polygons.each do |polygon|
if (polygon.length > 2)
flags = 0
$mesh_file.puts(" 0\n3DFACE\n 8\n" + layername)
for j in 0..polygon.length do
if (j == polygon.length)
count = polygon.length - 1
else
count = j
end
if ((polygon[count] < 0))
flags += 2 ** j
end
$mesh_file.puts((10 + j).to_s + "\n" + (mesh.point_at(polygon[count].abs).x.to_f * $stl_conv).to_s)
$mesh_file.puts((20 + j).to_s + "\n" + (mesh.point_at(polygon[count].abs).y.to_f * $stl_conv).to_s)
$mesh_file.puts((30 + j).to_s + "\n" + (mesh.point_at(polygon[count].abs).z.to_f * $stl_conv).to_s)
end
$mesh_file.puts("70\n" + flags.to_s)
end
end
$face_count += 1
end
def dxf_write_stl(face, tform)
mesh = face.mesh 7
mesh.transform! tform
polygons = mesh.polygons
polygons.each do |polygon|
if (polygon.length == 3)
$mesh_file.puts("facet normal " + mesh.normal_at(polygon[0].abs).x.to_s + " " + mesh.normal_at(polygon[0].abs).y.to_s + " " + mesh.normal_at(polygon[0].abs).z.to_s)
$mesh_file.puts("outer loop")
for j in 0..2 do
$mesh_file.puts("vertex " + (mesh.point_at(polygon[j].abs).x.to_f * $stl_conv).to_s + " " + (mesh.point_at(polygon[j].abs).y.to_f * $stl_conv).to_s + " " + (mesh.point_at(polygon[j].abs).z.to_f * $stl_conv).to_s)
end
$mesh_file.puts("endloop\nendfacet")
end
end
$face_count += 1
end
def dxf_write_polyface(face, tform, layername)
mesh = face.mesh 0
mesh.transform! tform
polygons = mesh.polygons
points = mesh.points
$mesh_file.puts(" 0\nPOLYLINE\n 8\n" + layername + "\n 66\n 1")
$mesh_file.puts("10\n0.0\n 20\n 0.0\n 30\n0.0\n")
$mesh_file.puts("70\n 64\n") #flag for 3D polyface
$mesh_file.puts("71\n" + mesh.count_points.to_s)
$mesh_file.puts("72\n 1")
points.each do |point|
$mesh_file.puts(" 0\nVERTEX\n 8\n" + layername)
$mesh_file.puts("10\n" + (point.x.to_f * $stl_conv).to_s)
$mesh_file.puts("20\n" + (point.y.to_f * $stl_conv).to_s)
$mesh_file.puts("30\n" + (point.z.to_f * $stl_conv).to_s)
$mesh_file.puts(" 70\n 192")
end
polygons.each do |polygon|
$mesh_file.puts(" 0\nVERTEX\n 8\n" + layername)
$mesh_file.puts("10\n0.0\n 20\n 0.0\n 30\n0.0\n")
$mesh_file.puts(" 70\n 128")
$mesh_file.puts(" 71\n" + polygon[0].to_s)
$mesh_file.puts(" 72\n" + polygon[1].to_s)
$mesh_file.puts(" 73\n" + polygon[2].to_s)
if (polygon.length == 4)
$mesh_file.puts(" 74\n" + polygon[3]..abs.to_s)
end
end
$mesh_file.puts(" 0\nSEQEND")
$face_count += 1
end
def dxf_dxf_options_dialog
options_list = ["polyface mesh", "polylines", "triangular mesh", "lines","stl"].join("|")
prompts = ["Export to DXF options"]
enums = [options_list]
values = ["polyface mesh"]
results = inputbox prompts, values, enums, "Choose which entities to export"
return if not results
results[0]
end
def dxf_dxf_units_dialog
cu = Sketchup.active_model.options['UnitsOptions']["LengthUnit"]
case cu
when 4
current_unit = "Meters"
when 3
current_unit = "Centimeters"
when 2
current_unit = "Millimeters"
when 1
current_unit = "Feet"
when 0
current_unit = "Inches"
end
units_list = ["Meters", "Centimeters", "Millimeters", "Inches", "Feet"].join("|")
prompts = ["Export unit: "]
enums = [units_list]
values = [current_unit]
results = inputbox prompts, values, enums, "Export units"
return if not results
case results[0]
when "Meters"
$stl_conv = 0.0254
when "Centimeters"
$stl_conv = 2.54
when "Millimeters"
$stl_conv = 25.4
when "Feet"
$stl_conv = 0.0833333333333333
when "Inches"
$stl_conv = 1
end
end
def dxf_header(dxf_option, model_name)
if (dxf_option == "stl")
$mesh_file.puts("solid " + model_name)
else
$mesh_file.puts(" 0\nSECTION\n 2\nENTITIES")
end
end
def dxf_end(dxf_option, model_name)
if (dxf_option == "stl")
$mesh_file.puts("endsolid " + model_name)
else
$mesh_file.puts(" 0\nENDSEC\n 0\nEOF")
end
$mesh_file.close
end
以上。