概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。
練習問題
Three.jsでobjビュアーを作って、objファイルを埋め込んだHTMLを出力するRUBYスクリプトを書け。
写真
サンプルコード
require "sketchup.rb"
module Oe
def self.export_entities(of, entities, o = nil)
faces = entities.find_all { |e|
e.typename == "Face"
}
verts = faces.map { |f|
f.vertices
}
verts.flatten!
verts.uniq!
if verts.length < 1
UI.messagebox("Nothing to export")
return
end
verts.each do |v|
pt = v.position
pt.transform!(o) if o
of.print "v #{pt.x.to_f} #{pt.z.to_f} #{pt.y.to_f}\n"
end
gc = 0
puts "face count: #{faces.length}"
faces.each do |f|
gc += 1
of.print "f "
f.outer_loop.vertices.each do |v|
i = verts.index(v) + @verts.length
of.print "#{i + 1} "
end
of.puts
end
of.puts
@verts << verts
@verts.flatten!
end
def self.export_group(of, g)
o = g.transformation
of.print "g "
id = g.entityID
name = g.name.empty? ? "Group#{id}" : g.name
of.puts "#{name}"
export_entities(of, g.entities, o)
end
def self.html
of = File.new("C:/Users/User/Desktop/oe.html", "w")
of.puts <<-EOF
<!doctype html>
<html>
<head>
<meta name="Keywords" content="JavaScript,HTML5,CSS" />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<style type="text/css">
* {
margin: 0;
padding: 0;
border: 0;
}
body {
background: #ddf;
font: 30px sans-serif;
}
</style>
</head>
<body>
<script src="https://unpkg.com/three@0.140.0/build/three.js"></script>
<script src="https://unpkg.com/three@0.140.0/examples/js/controls/DragControls"></script>
<script src="https://unpkg.com/three@0.140.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://unpkg.com/three@0.140.0/examples/js/loaders/OBJLoader.js"></script>
<textarea id="obj" cols="65" rows="5">
EOF
grps = Sketchup.active_model.entities.find_all { |e|
e.typename == "Group"
}
@verts = []
@vcnt = 0
entities = Sketchup.active_model.entities
export_entities(of, entities)
grps.each { |g|
export_group(of, g)
}
of.puts <<-EOF
</textarea>
<div id="out"></div>
<script type="text/javascript">
var container;
var scene;
var camera;
var controls;
var renderer;
var mesh;
var omesh;
var geometry;
function init() {
container = document.getElementById('out');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(600, 600);
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
camera = new THREE.PerspectiveCamera(45, aspect, 1, 1000);
camera.position.z = 70;
controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(new THREE.AmbientLight(0x999999));
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(1, 1, 1);
scene.add(light);
var axis = new THREE.AxisHelper(50);
scene.add(axis);
}
function loop() {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(loop);
}
var obj = document.getElementById("obj");
var data = obj.value;
var blob = new Blob([data], {
"type": "text"
});
var url = window.URL.createObjectURL(blob);
var loader = new THREE.OBJLoader();
loader.load(url, function(res) {
init();
loop();
var obj = res;
scene.add(obj);
});
</script>
</body>
</html>
EOF
of.flush
of.close
UI.messagebox("ok")
end
end
以上。