Created Objects are formed "inside out"

Hi fellow sketchupers,

I am currently working on a modelling skript for forest plots to depict them on posters. Everything works fine apart from one thing: Sometimes trees are created “inside out”, which you can see in the following picture:

I discovered that this occures randomly when I load the codefile into sketchup, so I think there is not a problem with the code. Either way I just want to detect wether the outside of the object faces inside (or the other way arround) to then turn that arround.
Does on of you know a way of doing this?

I am looking forward to your answers.
Best Regards

The face reversal in FollowMe comes from the interaction of the direction of the path [circle] - cw/ccw - and the orientation of the profile face, when compared to the direction.
Either ensure consistency, or check in your code for both of these factors - reverse the face before the FollowMe, as might be needed…

Thanks a lot for your reply.
As the trees are all created with a while loop, the code is consistend and the faces and paths all share the same orientation. Apart from that, this mistakes occures at random, so I do not really know where to look, as the code does not change.
Either way, I think i can work arround it with changing the insides colour. Do you know, whether that is possible?

Follow Me might introduce some randomness. When creating individual faces with Entities#add_face the orientation is governed by a set of (somewhat odd) rules and always predictable when you know these rules.

A set of vertices/points/edges that form an outer-loop for a face, when set up ccw makes a face with a normal perpendicular to the loop. However, if the loop is flat at z==0 then the created face’s normal is always Z_AXIS.reverse and the cw/ccw nature of the loop is ignored.
You see this in manual face creation in SketchUp itself.
Making cw/ccw face loops produces faces with different normals, except when flat at z==0, when the face is always down - allowing a PushPull up while keeping the bottom face logically oriented.
A face’s normal relative to a FollowMe path’s starting edge direction will affect how the extruded form’s surface is oriented. Your code needs to check the face.normal against this, and use face.reverse! if needed, also making allowance for the times when the face is made flat at z==0, with an unexpected flipped normal…

1 Like

I would just add some of my own thoughts, I maybe makes some sense…

Looking at the face and the vertices order are clockwise you will see the back face, but:

http://ruby.sketchup.com/Sketchup/Entities.html#add_face-instance_method
Note that a special case exists for any face created on the ground plane, in which case the vertex order is ignored and the face is always facing down.

Yup, the rules are a bit weird but once you know them you can work around that. When creating new faces this way you can check the normal and reverse the faces if needed.

Again, I am really gratefull to your reply.
I worked on checking the normal vectors of the created faces and let sketchup put them in the ruby window / console. What it showed me was the following:

"Baumnummer: 1; Normalenvector Bst Face: (0, -1, 0); Normalenvector Path Face: (-0, -0, 1)

  1. Normalenvector Kuk Face: (0, 0, -1)
  2. Normalenvector Kuk Face: (0, 0, -1)

Baumnummer: 2; Normalenvector Bst Face: (0, -1, 0); Normalenvector Path Face: (-0, -0, 1)

  1. Normalenvector Kuk Face: (-0, -0, 1)
  2. Normalenvector Kuk Face: (0, 0, -1)

[…]
***Baumnummer: 7; Normalenvector Bst Face: (0, -1, 0); Normalenvector Path Face: (-0, -0, 1)

  1. Normalenvector Kuk Face: (-0, -0, 1)
  2. Normalenvector Kuk Face: (0, 0, -1)

[…]
***Baumnummer: 10; Normalenvector Bst Face: (0, -1, 0); Normalenvector Path Face: (-0, -0, 1)

  1. Normalenvector Kuk Face: (-0, -0, 1)
  2. Normalenvector Kuk Face: (0, 0, -1)

[…]
true"

The only relevant thing to notice is, that “Normalenvector Bst Face” and “Normalenvector Path Face” do not Change. With the corresponding model it is different though:

Baummodell%20forum%20bild

As you can see, there are two trees that have red surfaces. Those are tree 7 and 10, (marked with *** in the text above), which means, that I can not use the .normal method to help me out here, as it does not show what the model ends up like.

My idea is now to check whether I can use another way, which I need your help with.
At the Bottom of every tree, that is generated with the followme method, there is a face that either Points up (red is shown) or downwards (brow is shown). Using the find method I could search for a face that has the normal Vector [0,0,1]. The Problem is, that in every tree, there are at least to faces that have the same orientation. To cope with that I could search for faces that do not have the same Variablename as These two. Is this possible?

An example:
With this Code, I can search for such a face, but it can only give out one. How can i include the Name (in my case “kuk_face” or “path_face”)?

ents = Sketchup.active_model.entities
xface = ents.find {|ent| ent.typename == “Face” &&
ent.normal == [0, 0, 1]} <-- The third condition would Need to be the Name
xface.material = [0, 0, 255]
puts "The face is: " + xface.to_s

Thanks a lot for your help!

Best regards
Hendrik

P.S.: Sorry for the wrong capitalization, my autorcorrect wants to make everything in german.

ents = Sketchup.active_model.active_entities # .active_entities NOT .entities
faces = ents.grep(Sketchup::Face).find_all{|e| e.normal == Z_AXIS }
# .find_all for ALL such faces, .find returns just the first one that matches
faces.each{|e|
  e.material='blue'
  puts e
}

This collects all faces with a normal matching the Z_AXIS ([0,0,1]) into the array ‘faces’
It then iterates them, to assign them a ‘blue’ material, and also prints their reference id[s]…

1 Like

I had this problem with a method although I ensured that the profile was always drawn counter clockwise on the ground plane and viewed from above (at a point on the z blue axis above the face looking down towards the origin) and the path always drawn counter clockwise viewed from a point at a greater positive distance along the y green axis looking back towards the origin. Despite all this care the followme method extruded the faces randomly inside out. I checked the direction of the profile and path vertices by add_text numbers at each vertex and I checked the front/back face result of the add_face. They were always the same but followme happened about 50% inside out.

In the end I used raytest to check and got it working. Just as a point of interest, raytest doesn’t detect the virtual entities which form a definition. I had to add_instance a temporary instance at the model origin of the group I was testing and erase! it when tested. raytest found nothing until I realised I had to do that, which was a bit confusing.

Happy coding and Happy New Year!

Model#raytest is very slow as it checks all faces in the model. If possible try avoiding it.

Merry coding!

Thanks for the tip. I just test one group at a time and there is a logical break in the test loop so as soon as it finds a face it stops testing so in my case it works fast enough. If I need it for more extensive searches I’ll be aware of the speed issue.

I thought I’d mention the issue with raytest and virtual entities because it tripped me up and I’m sure it trips up others. I was reading the post to find out about such things so I thought it might be helpful to add what I’ve found out. The raytest frequently gets a mention in posts as a fix for inside out geometry.

I’m quite sure It doesn’t stop when it finds a face but continues to test if any other face is ahead of that face. If it stopped at the first face it finds intersected the ray, it could hit a face at the back of the model through other faces, if that face happens to be earlier in the entities collection.

The raytest method is used to cast a ray (line) through the model and return the first thing that the ray hits.

I quote from the documentation. It returns an edge if that is the first thing it hits. I accept what you say

I’m quite sure It doesn’t stop when it finds a face but continues to test if any other face is ahead of that face.

But surely it is wasting effort and time if it continues? Just wondering. I have little inkling of what goes on under the bonnet of individual API methods.

The documentation states what is returned, not what is done internally. It returns the first thing hit in space seen from the ray start. It doesn’t return the first thing in time that it finds to intersect the ray. It has to continue and find all intersections before it can determine which one is “first” spatially.

In my human way of thinking I imagined the ray going forth and striking an entity and immediately shouting ‘Ouch!’. Silly me!

Computers aren’t (yet) capable of the intuitive human way of thinking where we can just “see” the solution to a problem. Instead computers have to run through all of the number crunching. I would expect raytest to work something like this:

For every face
  Skip if ray line doesn't intersect face
  Skip if intersection lies behind the start of the ray
  Skip if intersection lies outside the bounds of the face
  Memorize this intersection point
  # NOTE: Face's are iterated in an arbitrary order, likely time of creation,
  # so the first intersection found isn't necessarily the one we want.

Sort intersections by distance to the ray start
return the first intersection

The classic problem is deciding if an entity is inside or outside of a closed set of faces or 3d region. There is a mathematical algorithm for solving this but it is a bit of a night mare to program. We can just see it! It is hard work being a computer ;-D

At least computers aren’t capable of getting bored or drifting away thinking about more interesting things when they crunch the numbers :stuck_out_tongue: .

True :smile: