Is an entity in a surface
-
There is a model.Selection function is_surface(), which is true if the current selection is a surface.
I am looking for a similar function to determine if a single entity - say a face - is part of a surface.
(and/or to get an array of all entities which are in the same surface)Any ideas?
-
@al hart said:
I am looking for a similar function to determine if a single entity - say a face - is part of a surface.
<span class="syntaxdefault">def is_part_of_surface</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault"> entity </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> if entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Edge </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">soft</span><span class="syntaxkeyword">?<br /></span><span class="syntaxdefault"> elsif entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">is_a</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> entity</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">edges</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">any</span><span class="syntaxkeyword">?</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">soft</span><span class="syntaxkeyword">?</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault"> else<br /> false<br /> end<br />end<br /></span>
@al hart said:
(and/or to get an array of all entities which are in the same surface)
I'm actually about to write such a method for my own plugin. Don't have it yet, but it's just traversing all connected faces of soft edges.
(Note that it's only the
soft
property that SU use in regard to what is a Surface,smooth
is just used for shading.) -
<span class="syntaxdefault">def get_surface</span><span class="syntaxkeyword">( </span><span class="syntaxdefault">face </span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">surface </span><span class="syntaxkeyword">= {} </span><span class="syntaxcomment"># Use hash for speedy lookup<br /> </span><span class="syntaxdefault">stack </span><span class="syntaxkeyword">= [ </span><span class="syntaxdefault">face </span><span class="syntaxkeyword">]<br /> </span><span class="syntaxdefault">until stack</span><span class="syntaxkeyword">.empty?<br /> </span><span class="syntaxdefault">face </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">stack</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">shift<br /> edges </span><span class="syntaxkeyword">= </span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">edges</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select </span><span class="syntaxkeyword">{ |</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">| </span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">soft</span><span class="syntaxkeyword">? }<br /> for </span><span class="syntaxdefault">edge in edges<br /> </span><span class="syntaxkeyword">for </span><span class="syntaxdefault">face in edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">faces<br /> next </span><span class="syntaxkeyword">if </span><span class="syntaxdefault">surface</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">key</span><span class="syntaxkeyword">?( </span><span class="syntaxdefault">face </span><span class="syntaxkeyword">)<br /> </span><span class="syntaxdefault">stack </span><span class="syntaxkeyword"><< </span><span class="syntaxdefault">face<br /> surface</span><span class="syntaxkeyword">[ </span><span class="syntaxdefault">face </span><span class="syntaxkeyword">] = </span><span class="syntaxdefault">face<br /> end<br /> end<br /> end<br /> surface</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">keys<br />end<br /></span>
-
Thanks ThomThom,
I'll give these a try.
-
hi,
this seems to be an interesting approach, but
what is returned by the method?is it an array of elements, i can iterate?
i am not yet familiar with "keys" etc..... -:)if this gives back all entities of the "surface", how could i iterate thru it?
when i try, i get errors,
thanx
stan@thomthom said:
<span class="syntaxdefault">def get_surface</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> face </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> surface </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{}</span><span class="syntaxdefault"> </span><span class="syntaxcomment"># Use hash for speedy lookup<br /></span><span class="syntaxdefault"> stack </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">[</span><span class="syntaxdefault"> face </span><span class="syntaxkeyword">]<br /></span><span class="syntaxdefault"> until stack</span><span class="syntaxkeyword">.empty?<br /></span><span class="syntaxdefault"> face </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> stack</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">shift<br /> edges </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">edges</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|</span><span class="syntaxdefault"> e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">soft</span><span class="syntaxkeyword">?</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault"> for edge in edges<br /> for face in edge</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">faces<br /> next if surface</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">key</span><span class="syntaxkeyword">?(</span><span class="syntaxdefault"> face </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> stack </span><span class="syntaxkeyword"><<</span><span class="syntaxdefault"> face<br /> surface</span><span class="syntaxkeyword">[</span><span class="syntaxdefault"> face </span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> face<br /> end<br /> end<br /> end<br /> surface</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">keys<br />end<br /></span>
-
The return is an Array of all the Faces from any surface containing the Face passed as the argument. If the Face is not in a surface, the return will be an empty array.
-
@slbaumgartner said:
The return is an Array of all the Faces from any surface containing the Face passed as the argument. If the Face is not in a surface, the return will be an empty array.
hello,
thanx a lot. yes,in the mean time i renamed the array to @surface.keys and got the array back. works perfectly.
i have to find out, if there is a way to return this array without renaming (return xxxx ???)
stan
-
Where did you get @surface from?
-
@artmusicstudio said:
i am not yet familiar with "
keys
" etc..... -:)Go to the Ruby Resources "Sticky Thread" here:
RUBY PROGRAMMING REFERENCESGet the CHM files for whatever version Ruby your SketchUp is using.
SketchUp v8, 2013 and earlier uses Ruby 1.8.6
(some earlier version used Ruby 1.8.5 and 1.8.0, FYI)THEN ... lookup the
Hash#keys()
method -
@thomthom said:
Where did you get @surface from?
hi thomthom,
the method is
having a smooth mesh with any loops projected on it and intesect
selection of one or more surfaces by user and calling the method
iterating thru selected surfaces
iteration thru all elements within one of them
further operation with edges within the surface, especially the smooth ones
this peace of code for surface works super for me.
stan
-
@dan rathbun said:
@artmusicstudio said:
i am not yet familiar with "
keys
" etc..... -:)Go to the Ruby Resources "Sticky Thread" here:
RUBY PROGRAMMING REFERENCESGet the CHM files for whatever version Ruby your SketchUp is using.
SketchUp v8, 2013 and earlier uses Ruby 1.8.6
(some earlier version used Ruby 1.8.5 and 1.8.0, FYI)THEN ... lookup the
Hash#keys()
methodhi dan, thanx,
next one to be studied (of still so many....). -:)just to be sure of universality (ruby-versions), i run the code always in 2014 and v8 in win7, vista and xp....
stan -
TT's snippet earlier in this post contains a couple of bugs: it will raise an exception if the
argument isn't a Face (or something that supports #edges), and it will find false surfaces
built where more than two Faces meet at a soft Edge. The below fixes these issues.def get_surface( face ) return [] unless face.is_a?(Sketchup;;Face) surface = {} # Use hash for speedy lookup stack = [ face ] until stack.empty? face = stack.shift edges = face.edges.select { |e| e.soft? && e.faces.length == 2} for edge in edges for face in edge.faces next if surface.key?( face ) stack << face surface[ face ] = face end end end surface.keys end
-
That's for that revised version!
Advertisement