sketchupでruby その21

# 概要

sketchupでrubyやってみた。
make_fur使ってみた。


# 写真

![make.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c6292bbb-a024-ad2e-4abc-4c8f0b52ff39.jpeg)


# サンプルコード


```
def glowup(preview = false)
	@finstance = "yes"
	@funits = "funits"
	@camera = Sketchup.active_model.active_view.camera
	@fdensity = 10.0
	@flength = 10.0
	@frootw = 10.0
	@fvradius = 10.0
	@maxnum = 10
	@fforce = Geom::Vector3d.new(0.0, 0.0, 0.05)
	@fdirection = Geom::Vector3d.new(0.0, 0.0, 0.05)
	@ftype = "ftype"
	@fj = 1.0 / 100
	@flj = @fj / 100  * @flength
	@fljitter = Geom::Vector3d.new(@fj * @flength, @fj * @flength, @fj * @flength)
	@fwjitter = 1.0 * @frootw / 100
	@fstrong = 1.0
	@fsjitter = 1.0 * @fstrong / 100
	@fdivs = 0
	@fur_deflist = []
		model = Sketchup.active_model
		ss = model.selection
		ents = model.entities
		if ss.empty? 
		  	UI.messagebox("No selection.")
		  	return nil
		end
		return if ss.find{ |selface| 
			selface.kind_of? Sketchup::Face 
		} == nil
		starttime = Time.now.to_f
		@camera = Sketchup.active_model.active_view.camera
		@fdivs = @fdivs + 1 if @fvradius != 0
		cnt = 0
		sfaces = ss.find_all{ |selface| 
			selface.is_a?(Sketchup::Face) 
		}
		spgs = sfaces.map{ |pg| 
			[pg.mesh(5), pg.material, pg.normal] 
		}
		ocnt = 0
		pmesh = Geom::PolygonMesh.new
		pmeshes = []
		pcmax = 600
		pcnext = pcmax
		pmat = Sketchup.active_model.materials.current
		fur_inss_list = []
		fur_inss = []
		fur_def = Sketchup.active_model.definitions["fur_instance"]
		if @finstance == "yes" or (fur_def == nil and @finstance == "fur_instance")
			fur_def = model.definitions.add(model.definitions.unique_name(("fur_instance")))
			make_fur(pmesh, pointXYZ(0, 0, 0), pointXYZ(0, 0, 0), pointXYZ(0, 0, 1), nil, pointXYZ(1, 0, 0), @fdivs, true)
			if @ftype == "Box"
				fur_def.entities.fill_from_mesh(pmesh, false, 0)
			else
				fur_def.entities.fill_from_mesh(pmesh, false, 12)
			end
			fur_def.insertion_point = pointXYZ(0, 0, 0)
			fi_pcount = pmesh.count_polygons.to_i + 1.to_i
		elsif @finstance == ("fur_crowd")
			fi_pcount = 1
		elsif @finstance != "no"
			fur_def = Sketchup.active_model.definitions[@finstance]
			@finstance = ("no") if fur_def == nil
			fi_pcount = 1
		end
		pmesh = Geom::PolygonMesh.new if preview == false
		prmax = 10000
		@prepts = []
		spgs.each{ |mesh, mat, nvec|
			if mesh != nil
				mesh.polygons.each{ |poly|
					pt1 = mesh.point_at poly[0]
					pt2 = mesh.point_at poly[1]
					pt3 = mesh.point_at poly[2]
					uv1 = mesh.uv_at(poly[0], 1)
					uv2 = mesh.uv_at(poly[1], 1)
					uv3 = mesh.uv_at(poly[2], 1)
					nor1 = mesh.normal_at poly[0]
					nor2 = mesh.normal_at poly[1]
					nor3 = mesh.normal_at poly[2]
					len12 = pt1.distance pt2
					len13 = pt1.distance pt3
					vec12 = pt1.vector_to pt2
					vec13 = pt1.vector_to pt3
					ang23 = vec12.angle_between vec13
					area123 = len12.to_m * len13.to_m * Math.sin(ang23) * 0.5
					cnt = area123.to_f * @fdensity.to_f
					if cnt.to_f < 1.to_f
						if cnt.to_f > rand.to_f
							cnt = 1
						else
							cnt = 0
						end
					end
					cnt = cnt.to_i
					cnt = @maxnum if cnt > @maxnum
					(1..cnt).each{ |i|
						ra = rand
						rb = 1.to_f - Math.sqrt(rand)
						pt4 = Geom::Point3d.new
						pt4 = point_add(vector_scale(pt2, ra.to_f), vector_scale(pt3, (1.to_f - ra.to_f)))
						pt5 = Geom::Point3d.new
						pt5 = point_add(vector_scale(pt1, rb.to_f), vector_scale(pt4, (1.to_f - rb.to_f)))
						uv4 = Geom::Point3d.new
						uv4.x = uv2.x * ra + uv3.x * (1 - ra)
						uv4.y = uv2.y * ra + uv3.y * (1 - ra)
						uv5 = Geom::Point3d.new
						uv5.x = uv1.x * rb + uv4.x * (1 - rb)
						uv5.y = uv1.y * rb + uv4.y * (1 - rb)
						nor4 = Geom::Point3d.new
						nor4 = point_add(vector_scale(nor2, ra.to_f), vector_scale(nor3, (1.to_f - ra.to_f)))
						nor5 = Geom::Point3d.new
						nor5 = point_add(vector_scale(nor1, rb.to_f), vector_scale(nor4, (1.to_f - rb.to_f)))
						divs = @fdivs
						if @finstance != ("no") and @finstance != "no"
							if preview == false
								fur_inss.push [pt5, nor5, mat]
								ocnt += fi_pcount
								pmat = mat
								if (ocnt) >= pcnext
									ocnt += fi_pcount
									fur_inss_list.push fur_inss
									fur_inss = []
									while pcnext < (ocnt + pcmax / 2)
										pcnext += pcmax
									end
									Sketchup.set_status_text "Calc #{ocnt} Polygons"
								end
							else
								make_preview(@prepts, pt5, nor5, divs)
								break if @prepts.size > prmax
							end
						else
							if @fvradius == 0
								if preview == false
									make_fur pmesh, pt5, uv5, nor5, mat, pt1, divs
								else
									make_preview(@prepts, pt5, nor5, divs)
									break if @prepts.size > prmax
								end
							else
								cv1 = @camera.eye.vector_to @camera.target
								cv2 = @camera.eye.vector_to pt5
								if cv2.angle_between(cv1).to_f <= @camera.fov.degrees.to_f
									pdist = @fvradius.to_f - pt5.distance(@camera.eye)
									pdist = 0 if pdist < 0
									divs = (@fdivs * Math.sqrt(pdist / @fvradius)).to_i
									if divs != 0
										if preview == false
											make_fur(pmesh, pt5, uv5, nor5, mat, pt1, divs)
										else
											make_preview(@prepts, pt5, nor5, divs)
											break if @prepts.size > prmax
										end
									end
								end
							end
							pmat = mat
							if preview == false
								if (ocnt + pmesh.count_polygons) >= pcnext
									ocnt += pmesh.count_polygons
									pmeshes.push [pmesh, mat]
									pmesh = Geom::PolygonMesh.new
									while pcnext < (ocnt + pcmax / 2)
										pcnext += pcmax
									end
									Sketchup.set_status_text "Calc #{ocnt} Polygons"
								end
							end
						end
					break if @prepts.size > prmax
					}
				break if @prepts.size > prmax
				}
			end
			break if @prepts.size > prmax
		}
		return if preview == true
		if Sketchup.version.to_f >= 7
			model.start_operation "fur glow", true
		else
			model.start_operation "fur glow"
		end
		oocnt = 0
		fgp = model.active_entities.add_group
		fgents = fgp.entities
		if @finstance != ("no") and @finstance != "no"
			if fur_inss.size > 0
				ocnt += fi_pcount
				fur_inss_list.push fur_inss
				Sketchup.set_status_text "Calc #{ocnt} Polygons"
			end
			fur_inss_list.each{ |fur_inss|
				fur_inss.each{ |pt5, npt5, mat|
					nor5 = pointXYZ(0, 0, 0).vector_to(npt5)
					nor5.length = @flength.to_f
					nor6 = vector_add(nor5, vector_scale(@fdirection, 0.5))
					flv = vectorXYZ(@fljitter.x * (0.5 - rand), @fljitter.y * (0.5 - rand), @fljitter.z * (0.5 - rand))
					nor7 = vector_add(nor6, flv)
					nor7.length = nor5.length
					nor6.length = nor5.length
					if @fdirection.length == 0
						scale_deg = 180.degrees
					else
						scale_deg = (90.degrees - nor5.angle_between(nor6)).abs
					end
					scale_deg = 180.degrees if scale_deg > 180.degrees
					scale_deg = 180.degrees if scale_deg < 0
					ra = ((1.0 - rand * 2.0) * scale_deg)
					tr = Geom::Transformation.rotation(pointXYZ(0, 0, 0), vectorXYZ(0, 0, 1), ra)
					if nor7.samedirection?(vectorXYZ(0, 0, 1))
					elsif nor7.samedirection?(vectorXYZ(0, 0, -1))
						tr = Geom::Transformation.rotation(pointXYZ(0, 0, 0), vectorXYZ(1, 0, 0), 180.degrees) * tr
					else
						zax = nor7
						yax = nor7.cross(vectorXYZ(0, 0, 1))
						xax = yax.cross(nor7)
						tr = Geom::Transformation.axes(pointXYZ(0, 0, 0), xax, yax, zax) * tr
					end
					tsfactor = 1.to_f - @fj * (1.to_f - rand * 2.to_f)
					tsfactor = 0.01 if  tsfactor == 0
					ts = Geom::Transformation.scaling(tsfactor, tsfactor, tsfactor)
					tr = ts * tr
					tr = Geom::Transformation.translation(pointXYZ(0, 0, 0).vector_to(pt5)) * tr
					if @fur_deflist.length > 0
						fins = fgents.add_instance @fur_deflist[(@fur_deflist.length * rand).to_i], tr
					else
						fins = fgents.add_instance fur_def, tr
					end
					fins.material = mat if mat != nil
					Sketchup.set_status_text "Making #{oocnt} polygons / #{ocnt}"
					oocnt += fi_pcount
				}
			}
		else
			if pmesh.count_polygons > 0
				ocnt += pmesh.count_polygons
				pmeshes.push [pmesh, pmat]
				Sketchup.set_status_text "Calc #{ocnt} Polygons"
			end
			pmeshes.each{ |pmesh, mat|
				if pmesh != nil
					tgp = fgents.add_group
					tgents = tgp.entities
					if @ftype == "Box"
						tgents.fill_from_mesh(pmesh, false, 0)
					else
						tgents.fill_from_mesh(pmesh, false, 12)
					end
					tgp.material = mat
					oocnt += pmesh.count_polygons
					Sketchup.set_status_text "Making #{oocnt} polygons / #{ocnt}"
				end
			}
		end
		model.commit_operation
		wastetime = Time.now.to_f - starttime
		Sketchup.set_status_text "#{('waste time is')} #{wastetime} #{('sec')}"
end


```

以上。