SketchUp Update Broke the Foundation Plugin
-
I'm not entirely sure what has changed but I just noticed that the "face" tool of the slab-on-grade foundation is throwing an error after I updated SketchUp (SketchUp 2017), everything is working fine in previous versions of SketchUp:
Error: #<NoMethodError: undefined method
volume' for #<Geom::BoundingBox:0x0000000f7b2488>> c:/users/administrator/appdata/roaming/sketchup/sketchup 2017/sketchup/plugins/medeek_foundation_ext/medeek_sog_trim_rebar.rbs:104:in
trim_rebar'I've indicated the exact line where the error is happening below.
The code is:
######################################################### # # Slab on Grade (TRIM REBAR) Methods # ######################################################### def sog_trim_rebar (slabgroup, rebargroup, profileface, edgedistance) # Initialization @mod = Sketchup.active_model @ent = @mod.active_entities # Profile Face @face = profileface @slab_ents = slabgroup.is_a?(Sketchup;;Group) ? slabgroup.entities ; slabgroup.definition.entities @slab_trns = slabgroup.transformation @rebar_ents = rebargroup.is_a?(Sketchup;;Group) ? rebargroup.entities ; rebargroup.definition.entities @rebar_trns = rebargroup.transformation MedeekMethods.face_inset(@face,edgedistance) v3 = @face.normal v3.length = 24 @bf = @ent.add_group @bfe = @bf.entities @bft = @bf.transformation last = @o_pts.length - 1 0.upto(last) do |i| @bfe.add_face(MedeekMethods.make_a_face(@o_pts[i],@o_pts[i-last],v3)) end face = @ent.add_face(@o_pts) MedeekMethods.trim_rebar(rebargroup,face) @bf.erase!; @ent.erase_entities(face.edges); end def trim_rebar(ci,f) plane = f.plane; bb=Geom;;BoundingBox.new; 0.upto(7){|i|bb.add ci.bounds.corner(i)} [b]unless bb.intersect(@bf.bounds).volume == 0.0[/b] ci.make_unique; cit = ci.transformation; cde = ci.is_a?(Sketchup;;Group) ? ci.entities ; ci.definition.entities; new = cde.intersect_with(false,cit,cde,cit,false,@bf) if new # puts "Finding clipped edges" rmv = cde.grep(Sketchup;;Edge).select{|e| !new.include?(e) && f.classify_point(e.midpnt.transform(cit).project_to_plane(plane))==16 }; # puts "Erasing clipped edges" cde.erase_entities(rmv) unless ci.manifold? # puts "Making manifold" new.grep(Sketchup;;Edge).each{|e|e.find_faces if e.valid?} end end end end def make_a_face(p1,p2,v) pts=[]; pts<<p1.offset(v) pts<<p2.offset(v) pts<<p2.offset(v.reverse) pts<<p1.offset(v.reverse) return pts end def face_inset(face,dist) @c_pts=face.outer_loop.vertices.collect{|v|v.position}; last = @c_pts.length-1;@o_pts = [] 0.upto(last) do |a| vec1 = (@c_pts[a]-@c_pts[a-last]).normalize vec2 = (@c_pts[a]-@c_pts[a-1]).normalize unless vec1.parallel? vec2 vec3=(vec1+vec2).normalize ang = vec1.angle_between(vec2)/2; if vec3.valid? vec3.length = -dist/Math;;sin(ang); vec3.reverse! if face.classify_point(@c_pts[a].offset(vec3))==16 t = Geom;;Transformation.new(vec3) @o_pts << @c_pts[a].transform(@slab_trns*t) end end end end
-
As Dan says,
bounds
does not have a method.volume
!Also, don't leave a space between a method and its arguments:
def sog_trim_rebar (slabgroup, rebargroup, profileface, edgedistance)
should be
def sog_trim_rebar(slabgroup, rebargroup, profileface, edgedistance)
etc... -
@medeek said:
I've indicated the exact line where the error is happening below.
You cannot use bbCode bold tags inside a bbCode code block.
Try marking errors inside code using comments like:
erroneous code # <<<<<<<<<<--------------<<<<<<<< ERROR !
Or, bracketing:
` ####
THIS DOES NOT WORK
result = some_code()
a = b + result####`
Regarding your
NoMethodError
error. TheBoundingBox
class does not have (nor ever did,) an instance method namedvolume()
. So I doubt that it could work as intended on older versions.EDIT: However, it is possible you were relying upon a modification to the
BoundingBox
class made by some extension that you've not loaded in the latest version ? (Generally, you should not rely upon API modifications made by other extensions.)You also seem to have ignored the advice in the API docs concerning the
BoundingBox#intersect
method.You'd have to either define a singleton
volume()
method and attach to that single object:module BB_Volume def volume() height * width * depth end end bb_obj.extend(BB_Volume) unless bb_obj.volume == 0.0 # do code here end
OR .. just use the
Geom::BoundingBox#empty?
method:unless bb_obj.empty? # do code here end
-
I would also suggest avoiding naming objects "new" as this is the standard name for the class constructor method. This could confuse the Ruby interpreter under some situations, as it must decide whether you are trying to make a method call or creating a local reference of the same name.
The idea is to train yourself to avoid hard to find errors.
-
Dan you are a SketchUp Wizard.
Sure enough after I did a bit of digging about I found two class modifications that I was relying on that somehow got deleted from my plugins folder:
class Sketchup::Edge
def midpnt
Geom::Point3d.linear_combination(0.5, self.start.position, 0.5, self.end.position)
end
endclass Geom::BoundingBox def volume vol = self.width*self.height*self.depth vol = vol<1.0e+30 ? vol : 0.0 end end
Which basically tells me that the rebar for the slab-on-grade foundation was never working for anyone except me (polygon and face tool)
-
I never said I was good at programming in Ruby or dealing with the API, actually I'm very weak in that regard. I know just enough to get me into trouble. I'm surprised that I have gotten as far as I have with these plugins.
-
You should not modify or add to shipped modules/classes - like Sketchup and Geom.
It won't get past the EWH audit.It's easy enough to define similar methods inside your own module[s]...
def midpt(edge) Geom;;Point3d.linear_combination(0.5, edge.start.position, 0.5, edge.end.position) end
Used thus, passing it an edge:
mpt = midpt(edge)
returns a point...and
def bbvol(bb) vol = bb.width*bb.height*bb.depth vol = vol < 1.0e+30 ? vol ; 0.0 end
Used thus, passing it a bounding-box:
vol = bbvol(bb)
returns a float volume... -
Or single object extension via mixin module (as shown above.)
unless bb.extend(BB_Volume).volume == 0.0 # do code here end
Or if only supporting Ruby 2.x+ SketchUp versions, you can use class refinements that are only active within your files.
See: http://ruby-doc.org/core-2.0.0/doc/syntax/refinements_rdoc.html
Advertisement