Check if component exists before making it
-
I have a script that rasterizes a line into cubes. My problem is, I want to make sure it doesn't generate duplicate cubes. How do I do that?
require 'sketchup.rb' require 'extensions.rb' cCube = Sketchup.active_model.definitions.add("Cube") ; newface = cCube.entities.add_face( [ [0.5, -0.5, 0.5], [0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5] ] ) ; newface.reverse! if newface.normal.z < 0 ; newface.pushpull(1) ; # extrude it up to make a cube Sketchup.active_model.selection.each { |entity| x = entity.start.position.x y = entity.start.position.y z = entity.start.position.z l = entity.length dx = (x-entity.end.position.x)/l dy = (y-entity.end.position.y)/l dz = (z-entity.end.position.z)/l for i in 0..l.to_int cx = (x - (dx*i)).round cy = (y - (dy*i)).round cz = (z - (dz*i)).round # a bit of code to make sure a cCube doesnt exist here already Sketchup.active_model.active_entities.add_instance(cCube, Geom;;Transformation.new([cx,cy,cz])) end }
-
name="Cube" name=Sketchup.active_model.definitions.unique_name(name)
if 'Cube' is already taken it becomes 'Cube#1'
if 'Cube#1' is already taken it becomes 'Cube#2' etc...
Sketchup.active_model.definitions.add(name)
-
@tig said:
name="Cube" name=Sketchup.active_model.definitions.unique_name(name)
if 'Cube' is already taken it becomes 'Cube#1'
if 'Cube#1' is already taken it becomes 'Cube#2' etc...
Sketchup.active_model.definitions.add(name)
That solves a different question I had (lol) but not the one I'm asking here.
Let's take point [1, 2, 3]. I want to add an instance of cCube at that point
Sketchup.active_model.active_entities.add_instance(cCube, Geom::Transformation.new( [1, 2, 3] ))
What I want to know, is how do I check that that instance of cCube does not already exist?
How do I prevent creating duplicate instances of a component?
If there is not a cCube at [1, 2, 3] then{ Sketchup.active_model.active_entities.add_instance(cCube, Geom::Transformation.new( [1, 2, 3] )) }
-
point=Geom;;Point3d.new(1,2,3 )### or whatever 'point' you are testing for exists=false compo=Sketchup.active_model.definitions['Cube'] compo.instances.each{|ins| if ins.transformation.origin==point exists=true break end } if exists puts 'That Cube exists already!' else ### do your stuff to add a new instance of compo at point Sketchup.active_model.active_entities.add_instance(cCube, Geom;;Transformation.new( [1, 2, 3] ) end
-
@tig said:
point=Geom;;Point3d.new(1,2,3 > )### or whatever 'point' you are testing for > exists=false > compo=Sketchup.active_model.definitions['Cube'] > compo.instances.each{|ins| > if ins.transformation.origin==point > exists=true > break > end > } > if exists > puts 'That Cube exists already!' > else > ### do your stuff to add a new instance of compo at point > Sketchup.active_model.active_entities.add_instance(cCube, Geom;;Transformation.new( [1, 2, 3] ) > end
How will this effect performance if I had hundreds of them? I figured something like this must be possible, but as the number of cubes grows, this would become less efficient. I'm talking on the scale of ~2000 cubes. Is this method efficient enough for the speed to be negligible?
-
At best it will find a match immediately 1/2000, at worst at go 2000/2000, on average at go 1000/2000.
You can but test it and see...
If you are adding all cube-instances in the same SketchUp session then why not make a @points array to push [<<
] all of the points you will use during the placements - these need to be as arrays so they are 'comparable' [usepoint.to_a
] - points are comparable as == but include? is faster [most probably] with array comparisons ?
Then... instead of finding all instances and comparing each 'instance.origin' to 'point' use:
@points.include?(point.to_a)
If the tested point is in the current list then it's taken and you skip the operation...
Of course this doesn't work when instances have been erased or across SketchUp sessions
Advertisement