LoginSignup
0
0

More than 1 year has passed since last update.

sketchupでruby その21

Last updated at Posted at 2022-02-13

概要

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

写真

make.jpg

サンプルコード

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


以上。

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