0

I have an application using Qt3D to show 3D objects. I'm looking for a way to detect 3D surfaces on my 3D objects which are more vertical versus surfaces which are more horizontal, like this:

tea pot with sample hor. and ver. surfaces

I don't know where to begin. I don't know the available tools. I don't even know the terminology for such a detection. Can anybody help?

Megidd
  • 7,089
  • 6
  • 65
  • 142
  • 1
    I'm not familiar with Qt3D, but in theory what you need is to find the tangent for each point on your object and evaluate it based on what you think is vertical/horizontal. So, for example if it's steeper than 45 degrees it should be vertical and vice versa. – aframestor Sep 04 '18 at 07:47
  • 1
    This is difficult to answer, as it is not necessarily clear what a _horizontal_ (or vertical) surface is. This actually depends on a higher coordinate system and what you define as the ground. Is that the plane with coordinate `z` set to 0? What kind of 3D models do you have? I think Qt's shader codes make use of the surface normals. If you have those lying around somewhere in your mesh you could calculate the angle between the normal and the "ground" plane. – Florian Blume Sep 04 '18 at 07:50
  • @FlorianBlume @aframestor I think your suggested method of calculating the angle between normal and ground would work. My ground is `z=0` plane. The critical angle of horizontal/vertical could possibly be `45 deg`. My 3D models are meshes with vertex `positions` and vertex `normals`. One problem comes to mind: Qt3D is giving me 3 normals for each triangle i.e. one normal for each vertex of the triangle. However, I only need one normal for every triangle. I don't know how to convert 3 vertex normals to 1 triangle normal. – Megidd Sep 04 '18 at 08:24
  • @FlorianBlume [this answer](https://stackoverflow.com/a/6661242/3405291) and [this page](https://docs.unity3d.com/Manual/AnatomyofaMesh.html) helped to understand it better. – Megidd Sep 04 '18 at 09:27

1 Answers1

0

To detect the horizontal surfaces on a 3D object, OpenGL Shading Language or GLSL can be used. Qt3D material class along with Qt3D effect class can be employed to implement any custom GLSL code. A Q & A shows how to use those classes.

To detect the horizontal surfaces on a 3D object and show them with red color, the fragment shader for OpenGL 2.0 can be developed like this on a Qt3D custom material/effect:

#define FP highp
varying FP vec3 worldNormal;

void main()
{
    vec3 n = normalize(worldNormal);
    vec3 z = vec3(0.0, 0.0, -1.0); // Normalized already

    float zDotN = dot(z, n);

    if ( zDotN > 0.7 ) { // 0.7 is my threshold/criterion

        vec3 oc = vec3(1.0, 0.0, 0.0); // Use red color!
        gl_FragColor = vec4(oc, 1.0);

    } else {

        vec3 oc = vec3(0.0, 0.0, 1.0); // Use blue color!
        gl_FragColor = vec4(oc, 1.0 );
    }
}

On the above code, the dot-product of surface normal vector with the (0.0, 0.0, -1.0) is employed to decide if the surface is horizontal or not.

For OpenGL 3.0, the GLSL code would be modified like this:

#version 150 core

in vec3 worldNormal;
out vec4 fragColor;

void main()
{
    vec3 n = normalize(worldNormal);
    vec3 z = vec3(0.0, 0.0, -1.0); // Normalized already
    float zDotN = dot(z, n);

    if ( zDotN > 0.7 ) { // 0.7 is my threshold/criterion

        vec3 oc = vec3(1.0, 0.0, 0.0); // Use red color!
        fragColor = vec4( oc, 1.0);

    } else {

        vec3 oc = vec3(0.0, 0.0, 1.0); // Use blue color!
        fragColor = vec4( oc, 1.0 );

    }
}
Megidd
  • 7,089
  • 6
  • 65
  • 142