Face with hole does not return correct outer loop


#1

image
After accessing the lines on the above face with a call to face.outer_loop the resulting returned lines are as shown below.
image

         lines = [ ]
         face.outer_loop.edgeuses.each{|edgeuse|
          e = edgeuse.edge
          lines <<   [e.start.position.clone, e.end.position.clone]

       }
        lplanes << lines 
        face.loops.each{|loop|
          next if loop.outer?
          lines = [ ]
          loop.edgeuses.each{|edgeuse|
            e = edgeuse.edge
            lines << [e.start.position.clone, e.end.position.clone] 
           }
          lplanes << lines
        }

#2

When you format the code as code (</> button), it becomes easierly readable like code.

The code is probably not complete because lines and lv are undefined.

Also it is not good to abuse integers for control flow (switches, booleans) instead of counting. The meaning of your code becomes much clearer without:

# Process the outer loop first.
face.outer_loop.edgeuses.each{ |edgeuse|
  e = edgeuse.edge
  lv.Build(e.start.position, e.end.position)
}
# Then process all loops except the outer loop.
face.loops.each{ |loop|
  next if loop.outer?
  loop.edgeuses.each{ |edgeuse|
    e = edgeuse.edge
    lv.Build(e.start.position, e.end.position)
  }
}

Have you tried to narrow down the supposed bug? Is it really related to the outer loop?

face.outer_loop.edgeuses.each{ |edgeuse|
  e = edgeuse.edge
  lv.Build(e.start.position, e.end.position)
}

or

vertices = face.outer_loop.vertices
vertices.each_index{ |i|
  v1, v2 = vertices[i-1], vertices[i]
  lv.Build(v1.position, v2.position)
}

#3

There is a lot of context missing from your snippet of code that makes it hard to be certain what it is supposed to do, though one can guess. For example,

  • where is the value of face obtained? What about lv and lines?
  • what is the purpose of loops, index, and lplanes none of which is used for anything here
  • do you realize that the range 0…1 includes only the value 0? It will never pass 1 into the each iterator over the face’s loops
  • perhaps you need to check edgeuse.reversed? because edges can be employed forward or backward by an edgeuse, and that may affect their connectivity in your code
  • lv.Build looks like bad practice: a method name should not start with a capital letter
  • the behavior of classes Linev and Lplane is unknown to us, so we can’t diagnose anything there

Edit: another:

  • what is lines and what does lines.add_line(lv) do?

#4

Thanks for attempting to reformat your code for us. Alas, you appear to have misunderstood. @Aerilius was referring to the </> icon at the top of the post edit window, not to explicitly inserting those symbols. Actually I prefer manually inserting
“```ruby” (without the quotes)
on the line before the code and
three backticks on the line after, as that tells the formatter the code is Ruby and gets syntax highlighting. Note: those are backtick characters, not single quotes.


#5

There is no issue with Linev or Lplane classes and it was a bit misleading for me to include them in the code so I have replaced them with simple arrays for clarity. The source of the face is simply one constructed in Sketchup and I am attempting to poll the outside and inside lines which bound the face for a tool that I am developing. A call to face.loops.count for this particular face returns 1 which strikes me as incorrect. Should it not be 2?


#6

I’ve just seen the problem. The data that was used to create the face was stored as an array of points derived from the selected face which was fine when dealing with a face without holes. I now know what to do. Thanks


#7

I can’t explain this. If I draw a face such as your image shows, face.loops.count returns 2 as expected. Must be something about your specific geometry.