使用Sketchup Ruby API在圆柱体上打孔

时间:2013-03-29 01:01:56

标签: ruby sketchup

我正在写一个脚本,在SketchUp(免费版,Mac)中制作一个简单的长笛。我想制作一个管子,然后用圆筒戳穿管子,画出管子和圆筒之间的交叉线,然后擦掉圆筒,留下圆圈从管子上切下来。

如果我用鼠标操作,这是有效的,但我发现很难准确地用鼠标进行放置和测量。但到目前为止,我还没有能够使用脚本。目前我坚持在管上绘制不完整的圆圈,所以我无法找到面并擦除它。你应该能够在ruby控制台中运行以下脚本,看看我的意思。我做错了什么?

entities = Sketchup.active_model.entities

# make tube
tube = entities.add_group
tube_inner = tube.entities.add_circle Geom::Point3d.new(0,0,0), Geom::Vector3d.new(0,0,1), 5, 360
tube_outer = tube.entities.add_circle Geom::Point3d.new(0,0,0), Geom::Vector3d.new(0,0,1), 6, 360
cross_section_face = tube.entities.add_face tube_outer
inner_face = tube.entities.add_face tube_inner
tube.entities.erase_entities inner_face
cross_section_face.pushpull -10, false

# make a cylinder that punches through the wall
hole_punch = entities.add_group
hole_outer = hole_punch.entities.add_circle Geom::Point3d.new(0,0, 5), Geom::Vector3d.new(0,1,0), 3, 360
face = hole_punch.entities.add_face hole_outer
face.pushpull 10, false

# draw the intersection lines and erase the hole punch
entities.intersect_with true, hole_punch.transformation, tube, tube.transformation, true, hole_punch
hole_punch.erase!

1 个答案:

答案 0 :(得分:1)

确定交叉后要擦除的正确面孔可能非常棘手。

但是因为你正在使用圆柱形状 - 它们是实体 - 我建议你使用SketchUp 8 Pro中引入的实体布尔运算。例如,您可以使用Group.subtracthttp://www.sketchup.com/intl/en/developer/docs/ourdoc/group#subtract

但是,如果您没有使用SketchUp 8 Pro或更新版本,那么您将无法使用这些方法。


替代解决方案 - 避免Pro版本的Solid Tools方法:

entities = Sketchup.active_model.entities

# (!) You created a circle with so many edges that at the scale
#     you drew it they where pushing the boundary of how small
#     units SketchUp can handle. (1/1000th inch).
#     If you has Edge Outline style enabled you could see that
#     not all edges where fully merged.
#     I reduced the curve segments from 360 to 180.
#     (Do you really need such a high mesh density anyway?)

# make tube
tube = entities.add_group
tube_inner = tube.entities.add_circle Geom::Point3d.new(0,0,0), Geom::Vector3d.new(0,0,1), 5, 180
tube_outer = tube.entities.add_circle Geom::Point3d.new(0,0,0), Geom::Vector3d.new(0,0,1), 6, 180
cross_section_face = tube.entities.add_face tube_outer
inner_face = tube.entities.add_face tube_inner
tube.entities.erase_entities inner_face
cross_section_face.pushpull -10, false

# make a cylinder that punches through the wall
hole_punch = entities.add_group
hole_outer = hole_punch.entities.add_circle Geom::Point3d.new(0,0, 5), Geom::Vector3d.new(0,1,0), 3, 180
face = hole_punch.entities.add_face hole_outer
face.pushpull 10, false

# draw the intersection lines and erase the hole punch
entities.intersect_with true, hole_punch.transformation, tube, tube.transformation, true, hole_punch
hole_punch.erase!

# Find all the edges that belong to the Circle elements drawn
# earlier (including the ones push-pulled).
# (Could also collect these earlier before intersecting by
#  collecting all non-smooth edges.)
circles = tube.entities.grep(Sketchup::Edge).select { |e| e.curve }.uniq
# Then we pick out all the faces that isn't connected to these edges and erase them.
new_faces = tube.entities.grep(Sketchup::Face).select { |f| (f.edges & circles).empty? }
entities.erase_entities( new_faces )

如果您真的想要360细分圈子,则可以缩放群组内容 - 同时缩小群组实例。这样,群体定义的规模要大得多。 (请参阅SketchUp中的实例和定义:http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/

另外,如果你想让脸部填充内外皮之间的洞,你也需要与那个部分相交。


关于Entities.intersect_with描述的注释 - 当前的文档并不能很好地解释所有参数。有两个entities个参数。

第一个应该是Sketchup::Entities对象,其中应该出现相交的对象。 (通过喂它Sketchup::Group对象,我感到有些惊讶。)

第二个应该Sketchup::Entities - 这将失败。它必须是Sketchup:EntitySketchup:Entity个对象的数组。