REQ: Checking if components (solids) intersect
-
Thanks for the really awesome explanation.
I know a way that works (and just finished writing it) however it requires the pro version.
I wrote it "ruby code editor" plugin and there for used the selection in the model to set the two components. (link http://www.alexschreyer.net/projects/sketchup-ruby-code-editor/)
it works good so far only got a little error when I try to turn the material red of the intersecting component part.
mod = Sketchup.active_model # Open model ent = mod.entities # All entities in model sel = mod.selection # Current selection instance1 = sel[0] instance2 = sel[1] ci_def = instance1.definition tr1 = instance1.transformation test1 = Sketchup.active_model.entities.add_instance ci_def, tr1 ci_def2 = instance2.definition tr2 = instance2.transformation test2 = Sketchup.active_model.entities.add_instance ci_def2, tr2 result = test1.intersect(test2) # I can delete this later using something like an observer but would have to figure out how that works, also need to figure out how to make this work for more than 2 components and I need to figure out how to do it (multi)nested components. cnt = result.entities.count if cnt > 0 int=true result.material='red' # result.definition.entities.each {|ent| ###When I run this in the plugin in console I get the following error "Done. Ruby says; uninitialized constant AS_RubyEditor;;RubyEditor;;Face" # if ent.is_a? Sketchup;;Face # Face.material = 'red' #Sketchup;;Color.new(255, 0, 0) # end} else int=false end #return int
If I run the code normally I get the following output "Done. Ruby says: red"
However the faces aren't red they just stay the original color. -
@bobvandevoort said:
..
If I run the code normally I get the following output "Done. Ruby says: red"
However the faces aren't red they just stay the original color.they are red, actually... but inside. Faces a reversed
-
It's not
Face.material = 'red'
it'd beent.material = 'red'
-
@TIG
In method def self.intersectALL()(ens.length-1).times{|i| (ens.length-1).times{|j| next if j<=i # in place of ; next if j==i if self.intersect?(ens[i], ens[j]) ss.add(ens[i]) ss.add(ens[j]) end }
next if j<=i ( in place of next if j==i )
prevents double checking (slower) and double results.
If intersect?(ens[1], ens[2]) has been tested, then we don't have to test intersect?(ens[2], ens[1]) -
@pgarmyn said:
@TIG
In method def self.intersectALL()(ens.length-1).times{|i| > (ens.length-1).times{|j| > next if j<=i # in place of ; next if j==i > if self.intersect?(ens[i], ens[j]) > ss.add(ens[i]) > ss.add(ens[j]) > end > }
next if j<=i ( in place of next if j==i )
prevents double checking (slower) and double results.
If intersect?(ens[1], ens[2]) has been tested, then we don't have to test intersect?(ens[2], ens[1])I don't know why, but neither TIG's version, nor yours, works on my computer
this is how i changed the code:
model=Sketchup.active_model ss=model.selection ents=model.active_entities ss.clear gps=ents.grep(Sketchup;;Group) ins=ents.grep(Sketchup;;ComponentInstance) ens=gps+ins ens.uniq! ens.compact! for i in (0..ens.length-1) for j in ((i+1)..ens.length-1) if TIG.intersect?(ens[i], ens[j]) ss.add(ens[i]) ss.add(ens[j]) end end end puts "Any intersecting groups/component-instances are highlighted..."
length-1 because it because i begins at 0...
and the i+1 to avoid comparing i to itselfis this version much slower than yours?
-
model=Sketchup.active_model ss=model.selection ents=model.active_entities ss.clear gps=ents.grep(Sketchup;;Group) ins=ents.grep(Sketchup;;ComponentInstance) ens=gps+ins ens.uniq! ens.compact! for i in (0..ens.length-2) ############changed from length-1 to length-2 for j in ((i+1)..ens.length-1) if TIG.intersect?(ens[i], ens[j]) ss.add(ens[i]) ss.add(ens[j]) end end end puts "Any intersecting groups/component-instances are highlighted..."
I think, in this case, the last TIG.intersect?(ens[i], ens[j]) is with i=length-2 and j=length-1
Otherwise j = i+1 will become ens.length : for 5 elements (0 to 4) in ens, j will be 5. -
-
@tig said:
It's not
Face.material = 'red'
it'd beent.material = 'red'
Thanks this solved it
Btw there's a way to do it with the intersect_with function and rule out most of the touching elements.
Any 3d volume needs at least 4 faces, so do a face count for ges and see if it equals 4 or more.
I know there probably some odd situations where it would still only be touching but then you could check if the faces form a solid if it doesn't form a solid it's a touch (I think this should be a correct way to implement this).Let me know your thought about this method
(in any real 3d modeling you only need to find volumetric intersections and if you also want to find out of they are thouching we already have the method you previously described.
Everybody else thanks for the response and sorry for the delay on my side with responding, I have been away for 2 days.
-
@bobvandevoort
To rule out most of the elements :
You can exclude elements based on boundingbox values :
Elements a and b won't intersect
If a.bounds.max.x < b.bounds.min.x
If a.bounds.min.x > b.bounds.max.x
If ..... 4 other tests with .y and .zI'm not shure if this will speed up your code. I can imagen that those tests are also done by the (faster) intersect method of the API
-
@pgarmyn said:
model=Sketchup.active_model > ss=model.selection > ents=model.active_entities > ss.clear > gps=ents.grep(Sketchup;;Group) > ins=ents.grep(Sketchup;;ComponentInstance) > ens=gps+ins > ens.uniq! > ens.compact! > for i in (0..ens.length-2) ############changed from length-1 to length-2 > for j in ((i+1)..ens.length-1) > if TIG.intersect?(ens[i], ens[j]) > ss.add(ens[i]) > ss.add(ens[j]) > end > end > end > puts "Any intersecting groups/component-instances are highlighted..."
I think, in this case, the last TIG.intersect?(ens[i], ens[j]) is with i=length-2 and j=length-1
Otherwise j = i+1 will become ens.length : for 5 elements (0 to 4) in ens, j will be 5.i tried to run this code in sketchup 15 64 bits, thinking it could run faster than is sketchup 8
All the contrary
it is much slower in sketchup 15 64 bits... (about 10 times...)
i am very disapointed
am i the only one to experience that?
-
This is my version of the srcipt for now that seems to work for all non nested component instances
module Bob # Huge parts of this code were written by TIG this is a sligthly modified version def self.intersectBob?(e1=nil, e2=nil) mod = Sketchup.active_model # Open model ent = mod.entities # All entities in model instance1 = e1 #sel[0] instance2 = e2 #sel[1] ci_def = instance1.definition tr1 = instance1.transformation test1 = Sketchup.active_model.entities.add_instance ci_def, tr1 ci_def2 = instance2.definition tr2 = instance2.transformation test2 = Sketchup.active_model.entities.add_instance ci_def2, tr2 result = test1.intersect(test2) cnt = result.entities.count if cnt > 0 int=true result.definition.entities.each {|ent| if ent.is_a? Sketchup;;Face ent.material = 'red' #Sketchup;;Color.new(255, 0, 0) end} else int=false end return int end #def self.del() #does not work like this typing Bob.del into the ruby console, meaning result has to be changed from local to global variable but I don't know how yet #result.erase! #end def self.intersectALL() model=Sketchup.active_model ss=model.selection ents=model.active_entities ss.clear gps=ents.grep(Sketchup;;Group) ins=ents.grep(Sketchup;;ComponentInstance) ens=gps+ins ens.uniq! ens.compact! (ens.length).times{|i| (ens.length).times{|j| next if j<=i if self.intersectBob?(ens[i], ens[j]) ss.add(ens[i]) ss.add(ens[j]) end } } puts "Any intersecting component-instances are highlighted..." end end
In this script I still need to fix the deleting function which later will have to be added to an observer class so as soon as another is clicked (or a button is pressed) the resulting intersection is deleted.
The more important function that still has to be added is that it does the check for all the nested components (and possibly groups).
@giro
I only have the 32 bits version so can't say
Advertisement