0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

windows11で、sketchup6 その23

Last updated at Posted at 2025-03-29

概要

windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
dxfエクスポーター、見つけたので、やってみた。
読み込みは、sketchup6でOK。

写真

image.png

サンプルコード

起動 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


以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?