Android Question 3D Tin Model using OpenGL

Terradrones

Active Member
Licensed User
I have a TIN Model consisting of Triangles as defined by their Vertexes. I would like to display this as a 3D Model using OpenGL, but my code is full of errors. If somebody could please give me a push in the right direction. Here is my code:

B4X:
Sub Render3D
    If GlSV.DeviceAPILevel < 8 Then
        MsgboxAsync("OpenGL Is Not Supported On This Device", "OpenGL Error")
        Panels
        Panel1.Visible=True
    End If
    Panels
    Panel6.Visible = True
    Pnl3DView.Visible = True
    ProgressDialogShow("Generating 3D Model...")
    Sleep(0)
    CalculateScalingFactors
    GetVertices

    GlSV.Initialize2(GlSV.RENDERMODE_WHEN_DIRTY, "glsv", 16, 0)
    Pnl3DView.AddView(GlSV, 0, 0, Pnl3DView.Width, Pnl3DView.Height)
    ProgressDialogHide
End Sub

Sub Butt3_Click
'    Timer1.Enabled = False
    Panels
    Panel1.Visible=True
End Sub

Sub GLSV_Draw(gl As GL2)
    Try
        gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
'        gl.glLoadIdentity()
'        gl.glTranslatef(0, 0, -5)
'        gl.glRotatef(EyeAngle * (180 / 3.14159), 0, 1, 0)
        
        DrawTINModel(gl)
    Catch
        Log(LastException)
    End Try
End Sub

Sub glsv_SurfaceChanged(gl As GL2, width As Int, height As Int)
    Log("Changed")
    Try
        gl.glViewport(0, 0, width, height)
        Dim ratio As Float = width / height
        gl.gluPerspective(45, ratio, 1, 100)
    Catch
        Log(LastException)
    End Try
End Sub
    
Sub glsv_SurfaceCreated(gl As GL2)
    Log("Created")
    Try
        gl.glClearColor(0, 0, 0, 1)
        gl.glEnable(gl.GL_DEPTH_TEST)
        gl.glDepthFunc(gl.GL_LESS)
    Catch
        Log(LastException)
    End Try
End Sub

Sub Timer1_Tick
    EyeAngle = EyeAngle + 0.1
    If EyeAngle > (2 * 3.14159) Then EyeAngle = EyeAngle - (2 * 3.14159)
    GlSV.RequestRender
End Sub

Sub GetVertices
    Dim i As Int
    
    i=0
    vertixes.Initialize
    Do While i<=CGlobals.MaxTins
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev)) ' x, y, height
        
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East1)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North1)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev1)) ' x, y, he
        
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East2)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North2)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev2)) ' x, y, he
        i=i+1
    Loop
    
    MinX=PntMinX
    MinY=PntMinY
    MaxX=PntMaxX
    MaxY=PntMaxY
    MinZ=CGlobals.ZMinCont
    MaxZ=CGlobals.ZMaxCont
    
End Sub

Sub CalculateScalingFactors
    ' Determine the range of your world coordinates
    Dim rangeX As Float = PntMaxX - PntMinX
    Dim rangeY As Float = PntMaxY - PntMinY
    Dim rangeZ As Float = CGlobals.ZMaxCont- CGlobals.ZMinCont

    ' Determine the dimensions of your screen or viewport
    Dim screenWidth As Float = Pnl3DView.Width
    Dim screenHeight As Float = Pnl3DView.Height

    ' Calculate the scaling factors
    Dim scaleFactorX As Float = screenWidth / rangeX
    Dim scaleFactorY As Float = screenHeight / rangeY

    ' Use the minimum of the two scaling factors to maintain aspect ratio
    Dim scaleFactor As Float = Min(scaleFactorX, scaleFactorY)

    ' Apply the same scaling factor to all axes
    ScaleX1 = scaleFactor
    ScaleY1 = scaleFactor
    ScaleZ1 = scaleFactor ' Assuming Z scaling is proportional to X and Y
End Sub

Sub DrawTINModel(gl As GL2)

'    If vertixes.Size < 3 Then
'        Log("Not enough vertices to draw a triangle")
'        Return
'    End If
'
'    Try
'        Dim jo As JavaObject = gl
'        jo.RunMethod("glEnableClientState", Array(gl.GL_VERTEX_ARRAY)) ' Enable vertex array
'
'        ' Define vertex pointer
'        jo.RunMethod("glVertexPointer", Array(3, gl.GL_FLOAT, 0, vertixes)) ' Assuming vertices is a Float array
'
'        ' Draw the vertices as triangles
'        jo.RunMethod("glDrawArrays", Array(gl.GL_TRIANGLES, 0, vertixes.Size / 3))
'
'        jo.RunMethod("glDisableClientState", Array(gl.GL_VERTEX_ARRAY)) ' Disable vertex array
'    Catch
'        Log("Exception during drawing: " & LastException)
'    End Try
End Sub

And my screen is black.

Thanks
Michael
 

MasterGy

Member
Licensed User
I have a TIN Model consisting of Triangles as defined by their Vertexes. I would like to display this as a 3D Model using OpenGL, but my code is full of errors. If somebody could please give me a push in the right direction. Here is my code:

B4X:
Sub Render3D
    If GlSV.DeviceAPILevel < 8 Then
        MsgboxAsync("OpenGL Is Not Supported On This Device", "OpenGL Error")
        Panels
        Panel1.Visible=True
    End If
    Panels
    Panel6.Visible = True
    Pnl3DView.Visible = True
    ProgressDialogShow("Generating 3D Model...")
    Sleep(0)
    CalculateScalingFactors
    GetVertices

    GlSV.Initialize2(GlSV.RENDERMODE_WHEN_DIRTY, "glsv", 16, 0)
    Pnl3DView.AddView(GlSV, 0, 0, Pnl3DView.Width, Pnl3DView.Height)
    ProgressDialogHide
End Sub

Sub Butt3_Click
'    Timer1.Enabled = False
    Panels
    Panel1.Visible=True
End Sub

Sub GLSV_Draw(gl As GL2)
    Try
        gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))
'        gl.glLoadIdentity()
'        gl.glTranslatef(0, 0, -5)
'        gl.glRotatef(EyeAngle * (180 / 3.14159), 0, 1, 0)
       
        DrawTINModel(gl)
    Catch
        Log(LastException)
    End Try
End Sub

Sub glsv_SurfaceChanged(gl As GL2, width As Int, height As Int)
    Log("Changed")
    Try
        gl.glViewport(0, 0, width, height)
        Dim ratio As Float = width / height
        gl.gluPerspective(45, ratio, 1, 100)
    Catch
        Log(LastException)
    End Try
End Sub
   
Sub glsv_SurfaceCreated(gl As GL2)
    Log("Created")
    Try
        gl.glClearColor(0, 0, 0, 1)
        gl.glEnable(gl.GL_DEPTH_TEST)
        gl.glDepthFunc(gl.GL_LESS)
    Catch
        Log(LastException)
    End Try
End Sub

Sub Timer1_Tick
    EyeAngle = EyeAngle + 0.1
    If EyeAngle > (2 * 3.14159) Then EyeAngle = EyeAngle - (2 * 3.14159)
    GlSV.RequestRender
End Sub

Sub GetVertices
    Dim i As Int
   
    i=0
    vertixes.Initialize
    Do While i<=CGlobals.MaxTins
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev)) ' x, y, height
       
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East1)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North1)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev1)) ' x, y, he
       
        Y1=ConvertPhysicToCADX(CGlobals.Tin3D(i).East2)
        X1=ConvertPhysicToCADY(CGlobals.Tin3D(i).North2)
        vertixes.Add(Array As Float(X1, Y1, CGlobals.Tin3D(i).Elev2)) ' x, y, he
        i=i+1
    Loop
   
    MinX=PntMinX
    MinY=PntMinY
    MaxX=PntMaxX
    MaxY=PntMaxY
    MinZ=CGlobals.ZMinCont
    MaxZ=CGlobals.ZMaxCont
   
End Sub

Sub CalculateScalingFactors
    ' Determine the range of your world coordinates
    Dim rangeX As Float = PntMaxX - PntMinX
    Dim rangeY As Float = PntMaxY - PntMinY
    Dim rangeZ As Float = CGlobals.ZMaxCont- CGlobals.ZMinCont

    ' Determine the dimensions of your screen or viewport
    Dim screenWidth As Float = Pnl3DView.Width
    Dim screenHeight As Float = Pnl3DView.Height

    ' Calculate the scaling factors
    Dim scaleFactorX As Float = screenWidth / rangeX
    Dim scaleFactorY As Float = screenHeight / rangeY

    ' Use the minimum of the two scaling factors to maintain aspect ratio
    Dim scaleFactor As Float = Min(scaleFactorX, scaleFactorY)

    ' Apply the same scaling factor to all axes
    ScaleX1 = scaleFactor
    ScaleY1 = scaleFactor
    ScaleZ1 = scaleFactor ' Assuming Z scaling is proportional to X and Y
End Sub

Sub DrawTINModel(gl As GL2)

'    If vertixes.Size < 3 Then
'        Log("Not enough vertices to draw a triangle")
'        Return
'    End If
'
'    Try
'        Dim jo As JavaObject = gl
'        jo.RunMethod("glEnableClientState", Array(gl.GL_VERTEX_ARRAY)) ' Enable vertex array
'
'        ' Define vertex pointer
'        jo.RunMethod("glVertexPointer", Array(3, gl.GL_FLOAT, 0, vertixes)) ' Assuming vertices is a Float array
'
'        ' Draw the vertices as triangles
'        jo.RunMethod("glDrawArrays", Array(gl.GL_TRIANGLES, 0, vertixes.Size / 3))
'
'        jo.RunMethod("glDisableClientState", Array(gl.GL_VERTEX_ARRAY)) ' Disable vertex array
'    Catch
'        Log("Exception during drawing: " & LastException)
'    End Try
End Sub

And my screen is black.

Thanks
Michael
I'm happy to help with opengl, but unfortunately I don't understand your code. If there was only enough in your code that generates the lines or points, so it creates the graphic data, then I can try to build a renderer on top of it.
 
Upvote 0

Terradrones

Active Member
Licensed User
Hi MasterGy

Each Triangle of the TIN Model is formatted as such in the file:

X1,Y1,Z1 & X2,Y2,Z2 & X3,Y3,Z3 & Area

These represent the vertexes of each Triangle. The Area I use to determine in which Triangle the GPS or Prism Pole is held or if it is outside the TIN Model area. If it is inside a Triangle, I then calculate the theorical height what it must be using the coordinates of the vertexes and comparing that to the actual elevation.

I would like to present this TIN Model in a 3D view where the Surveyor can rotate the Model and also zoom in and out.

It does not really have any practical use, but it would be a nice feature in my Surveying program.

The module in the Ceaser program is called "Stock" and it is used to calculate the volume, plane area and slope area of a Stockpile that has been surveyed. I have also added "Height" shading to it.

Thanks
Michael
 
Upvote 0

MasterGy

Member
Licensed User
Hello!

I have prepared a possible solution.

All you have to do is upload your triangles in the activity with: 'ADD_TRIANGLE'

You have to enter 12 parameters.

x0,y0,z0,x1,y1,z1,x2,y2,z2 ,R,G,B

The 3 coordinate points of the triangle and its rgb color.

Make sure the coordinate points fall between -1 and 1, that's how it's set to display correctly.

In process_globals, 'dim triangle(200,12)' . if you have more than 200 triangles, set it as large as possible.

The program currently creates 10 randomly placed triangles, you can rotate and zoom.






triangles:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: landscape
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: true
    #IncludeTitle: false
#End Region

Sub Process_Globals
    Dim OpenGL_timer As Timer
    Dim triangle_c As Int
    Dim triangle(200,12) As Float '012-x0y0z0 345-x1y1z1 678-x2y2z2 ,9,10,11 RGB
End Sub

Sub Globals
    Dim OpenGL As GLSurfaceView
    Dim seekbar As SeekBar
    Dim touchpanel As Panel
    Dim touchpanel_data(10) As Float
    Dim lbl As Label
    Dim zoom_distance As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)


    
    'touchpanel
    touchpanel.Initialize("TouchPanel")
    Activity.AddView(touchpanel,  0,0,100%x,100%y)
    
    'opengl, opengltimer
    OpenGL.Initialize(OpenGL.RENDERMODE_WHEN_DIRTY, "opengl")
    Activity.AddView(OpenGL, 0,0,100%x,100%y)
    OpenGL_timer.Initialize("opengl_render",60)
    OpenGL_timer.Enabled = True

    'label   
    lbl.Initialize("lbl") ' Az "lbl" az események azonosítására szolgál
    lbl.TextSize = 20
    lbl.TextColor = Colors.argb(200,255,255,255)
    lbl.Color = Colors.argb(100,255,0,0)
    Activity.AddView(lbl, 0, 0, Activity.width, 50dip)

    'seekbar
    seekbar.Initialize("seekbar")
    seekbar.Max = 100
    seekbar.Value = 50
    Activity.AddView(seekbar, 0, Activity.Height - 50dip, Activity.Width, 50dip) ' SeekBar elhelyezése az alján




    For t = 0 To 10
    add_triangle(randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,Rnd(0,150),Rnd(0,150),Rnd(0,150))
    Next

End Sub

Sub randpos As Float
    Return  Rnd(0,1000)/1000-.5
    
End Sub

Sub add_triangle(x0 As Float,y0 As Float,z0 As Float,x1 As Float,y1 As Float,z1 As Float,x2 As Float,y2 As Float,z2 As Float,colr As Float,colg As Float,colb As Float)
    triangle(triangle_c,0) = x0
    triangle(triangle_c,1) = y0
    triangle(triangle_c,2) = z0
    triangle(triangle_c,3) = x1
    triangle(triangle_c,4) = y1
    triangle(triangle_c,5) = z1
    triangle(triangle_c,6) = x2
    triangle(triangle_c,7) = y2
    triangle(triangle_c,8) = z2
    triangle(triangle_c,9) = colr/255
    triangle(triangle_c,10) = colg/255
    triangle(triangle_c,11) = colb/255
    triangle_c = triangle_c+1
    
End Sub

Sub TouchPanel_Touch (Action As Int, X As Float, Y As Float)
    
    If Action = Activity.ACTION_MOVE  Then
        touchpanel_data(2) = touchpanel_data(2)+(touchpanel_data(0)-x)*.15
        touchpanel_data(3) = touchpanel_data(3)+(touchpanel_data(1)-y)*.15
    End If

    touchpanel_data(0) = X
    touchpanel_data(1) = y
End Sub

Sub opengl_render_tick
    OpenGL.RequestRender
    lbl.Text = "ANG1:"& NumberFormat(touchpanel_data(2), 1, 1) &"  ANG2:"  &   NumberFormat(touchpanel_data(3), 1, 1) & "  DISTANCE:"& NumberFormat(Abs(zoom_distance), 1, 1)
    lbl.Invalidate
End Sub




Sub opengl_draw(gl As GL1)
    
    
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)


    
    
    gl.glClearColor(.8, .8, .8, 1)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    gl.glEnable(gl.GL_NORMALIZE)

    gl.glLoadIdentity
    
    gl.glTranslatef(0,0,zoom_distance)
    gl.glrotatef(-touchpanel_data(3),1,0,0)
    gl.glrotatef(-touchpanel_data(2),0,1,0)
    
    
    
    
    gl.glFrontFace(gl.GL_CCW)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)

    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glDepthMask(True)
    gl.glDisable(gl.GL_BLEND)
    
    gl.glPushMatrix
    
    

    Dim vertices(9) As Float
    For at = 0 To triangle_c-1
            
        For t = 0 To 8:vertices(t) = triangle(at,t):Next
            gl.glVertexPointerf(3,  vertices)
            gl.glColor4f(triangle(at,9),triangle(at,10),triangle(at,11), 1) ' RGBA = Red    ' Set the color to red for the triangle
             gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
        Next
        
    gl.glPopMatrix
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)

End Sub

Sub opengl_SurfaceChanged(gl As GL1, width As Int, height As Int)
    
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.gluPerspective(60,width/height,0.01,6)
    gl.glMatrixMode(gl.GL_MODELVIEW)

    
End Sub


Sub SeekBar_ValueChanged (Value As Int, UserChanged As Boolean)
    zoom_distance = -(100-Value)*.05
End Sub
 
Upvote 0

Johan Schoeman

Expert
Licensed User
Longtime User
It might be worthwhile working through this thread starting at post #1. Perhaps you have already seen it but in case you have not. A great library by @agraham

 
Upvote 0

Terradrones

Active Member
Licensed User
Hello!

I have prepared a possible solution.

All you have to do is upload your triangles in the activity with: 'ADD_TRIANGLE'

You have to enter 12 parameters.

x0,y0,z0,x1,y1,z1,x2,y2,z2 ,R,G,B

The 3 coordinate points of the triangle and its rgb color.

Make sure the coordinate points fall between -1 and 1, that's how it's set to display correctly.

In process_globals, 'dim triangle(200,12)' . if you have more than 200 triangles, set it as large as possible.

The program currently creates 10 randomly placed triangles, you can rotate and zoom.






triangles:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: landscape
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: true
    #IncludeTitle: false
#End Region

Sub Process_Globals
    Dim OpenGL_timer As Timer
    Dim triangle_c As Int
    Dim triangle(200,12) As Float '012-x0y0z0 345-x1y1z1 678-x2y2z2 ,9,10,11 RGB
End Sub

Sub Globals
    Dim OpenGL As GLSurfaceView
    Dim seekbar As SeekBar
    Dim touchpanel As Panel
    Dim touchpanel_data(10) As Float
    Dim lbl As Label
    Dim zoom_distance As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)


   
    'touchpanel
    touchpanel.Initialize("TouchPanel")
    Activity.AddView(touchpanel,  0,0,100%x,100%y)
   
    'opengl, opengltimer
    OpenGL.Initialize(OpenGL.RENDERMODE_WHEN_DIRTY, "opengl")
    Activity.AddView(OpenGL, 0,0,100%x,100%y)
    OpenGL_timer.Initialize("opengl_render",60)
    OpenGL_timer.Enabled = True

    'label  
    lbl.Initialize("lbl") ' Az "lbl" az események azonosítására szolgál
    lbl.TextSize = 20
    lbl.TextColor = Colors.argb(200,255,255,255)
    lbl.Color = Colors.argb(100,255,0,0)
    Activity.AddView(lbl, 0, 0, Activity.width, 50dip)

    'seekbar
    seekbar.Initialize("seekbar")
    seekbar.Max = 100
    seekbar.Value = 50
    Activity.AddView(seekbar, 0, Activity.Height - 50dip, Activity.Width, 50dip) ' SeekBar elhelyezése az alján




    For t = 0 To 10
    add_triangle(randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,Rnd(0,150),Rnd(0,150),Rnd(0,150))
    Next

End Sub

Sub randpos As Float
    Return  Rnd(0,1000)/1000-.5
   
End Sub

Sub add_triangle(x0 As Float,y0 As Float,z0 As Float,x1 As Float,y1 As Float,z1 As Float,x2 As Float,y2 As Float,z2 As Float,colr As Float,colg As Float,colb As Float)
    triangle(triangle_c,0) = x0
    triangle(triangle_c,1) = y0
    triangle(triangle_c,2) = z0
    triangle(triangle_c,3) = x1
    triangle(triangle_c,4) = y1
    triangle(triangle_c,5) = z1
    triangle(triangle_c,6) = x2
    triangle(triangle_c,7) = y2
    triangle(triangle_c,8) = z2
    triangle(triangle_c,9) = colr/255
    triangle(triangle_c,10) = colg/255
    triangle(triangle_c,11) = colb/255
    triangle_c = triangle_c+1
   
End Sub

Sub TouchPanel_Touch (Action As Int, X As Float, Y As Float)
   
    If Action = Activity.ACTION_MOVE  Then
        touchpanel_data(2) = touchpanel_data(2)+(touchpanel_data(0)-x)*.15
        touchpanel_data(3) = touchpanel_data(3)+(touchpanel_data(1)-y)*.15
    End If

    touchpanel_data(0) = X
    touchpanel_data(1) = y
End Sub

Sub opengl_render_tick
    OpenGL.RequestRender
    lbl.Text = "ANG1:"& NumberFormat(touchpanel_data(2), 1, 1) &"  ANG2:"  &   NumberFormat(touchpanel_data(3), 1, 1) & "  DISTANCE:"& NumberFormat(Abs(zoom_distance), 1, 1)
    lbl.Invalidate
End Sub




Sub opengl_draw(gl As GL1)
   
   
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)


   
   
    gl.glClearColor(.8, .8, .8, 1)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    gl.glEnable(gl.GL_NORMALIZE)

    gl.glLoadIdentity
   
    gl.glTranslatef(0,0,zoom_distance)
    gl.glrotatef(-touchpanel_data(3),1,0,0)
    gl.glrotatef(-touchpanel_data(2),0,1,0)
   
   
   
   
    gl.glFrontFace(gl.GL_CCW)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)

    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glDepthMask(True)
    gl.glDisable(gl.GL_BLEND)
   
    gl.glPushMatrix
   
   

    Dim vertices(9) As Float
    For at = 0 To triangle_c-1
           
        For t = 0 To 8:vertices(t) = triangle(at,t):Next
            gl.glVertexPointerf(3,  vertices)
            gl.glColor4f(triangle(at,9),triangle(at,10),triangle(at,11), 1) ' RGBA = Red    ' Set the color to red for the triangle
             gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
        Next
       
    gl.glPopMatrix
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)

End Sub

Sub opengl_SurfaceChanged(gl As GL1, width As Int, height As Int)
   
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.gluPerspective(60,width/height,0.01,6)
    gl.glMatrixMode(gl.GL_MODELVIEW)

   
End Sub


Sub SeekBar_ValueChanged (Value As Int, UserChanged As Boolean)
    zoom_distance = -(100-Value)*.05
End Sub
Hi MasterGy, thank you very much for that. I am in Jefferies Bay at the moment, but I am driving back to Paarl tomorrow. I will give it a try on Tuesday.
 
Upvote 0

Terradrones

Active Member
Licensed User
Hi MasterGy, I have used your code and then added a routine to read in my Triangles from the Tin Model. As you said that the coordinates must be between -1 and 1 , I calculated a "Scale Factor" which is applied to each Coordinate to stay between -1 and 1.

My problem is that the screen stays black in Debug mode and a olive green in Release mode.

When looking at the code, please bear in mind that in South Africa we call the Horizontal Axis the "Y" coordinate and the Vertical Axis the "X" coordinate. Its a mirror naming of the rest of the World.

I have adjusted the RGB colors according to the heights of the Vertexes.

Code:

Code:
[
#Region ****************************************************** Start **********************************************

#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim Panel1,Panel2 As Panel
    Dim Butt1 As ImageView
    Dim Label As Label
    
    Dim OpenGL_timer As Timer
    Dim triangle_c As Int
    Dim triangle(20000,12) As Float '012-x0y0z0 345-x1y1z1 678-x2y2z2 ,9,10,11 RGB
    
    Dim OpenGL As GLSurfaceView
    Dim Seekbar As SeekBar
    Dim Touchpanel As Panel
    Dim Touchpanel_data(10) As Float
    Dim zoom_distance As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Plot3D")
    Activity.Title="Plot 3D"
    Panel1.Visible=True
    Seekbar.Value=50
    
    
    'opengl, opengltimer
    OpenGL.Initialize(OpenGL.RENDERMODE_WHEN_DIRTY, "opengl")
    If OpenGL.IsInitialized Then
        Panel2.AddView(OpenGL, 0, 0, 100%x, 100%y)
    Else
        Log("OpenGL initialization failed")
    End If

    OpenGL_timer.Initialize("opengl_render",60)

    ScaleTin
'    For t = 0 To 10
'        add_triangle(randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,Rnd(0,150),Rnd(0,150),Rnd(0,150))
'    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

#End Region

#Region ******************************************************** Buttons Pressed ****************************************************

Sub Butt1_Click
    Activity.Finish
End Sub

#End Region

#Region ******************************************************* Calcs ************************************************************

Sub ScaleTin
    Dim Count,i As Int
    Dim YRange,XRange,ZRange As Double
    Dim AveElev As Double
    
    Engine.GetTriangles(2)
    Count=CGlobals.MaxTins        'Number of Triangles
    
    'Next work out a scale factor so that the real world coords are between -1 and 1
    YRange=1.9/(CGlobals.YMaxCoord-CGlobals.YMinCoord)
    XRange=1.9/(CGlobals.XMaxCoord-CGlobals.XMinCoord)
    ZRange=1.9/(CGlobals.ZMaxCont-CGlobals.ZMinCont)
    
    For i=0 To Count-1
        'Calc the average Height of the Triangle
        AveElev=(CGlobals.Tin3D(i).Elev + CGlobals.Tin3D(i).Elev1 + CGlobals.Tin3D(i).Elev2)/3
        
        'Calc the Color shading according to the average Height
        'Red is heighest and Blue is lowest with other colors inbetween
        Dim ratio As Float = (i - CGlobals.ZMinCont) / (CGlobals.ZMaxCont - CGlobals.ZMinCont)
        Dim red As Int = 255 * ratio
        Dim blue As Int = 255 * (1 - ratio)
        
        'Add the Triangle
        add_triangle(CGlobals.Tin3D(i).East*YRange,CGlobals.Tin3D(i).North*XRange,CGlobals.Tin3D(i).Elev*ZRange,CGlobals.Tin3D(i).East1*YRange,CGlobals.Tin3D(i).North1*XRange,CGlobals.Tin3D(i).Elev1*ZRange,CGlobals.Tin3D(i).East2*YRange,CGlobals.Tin3D(i).North2*XRange,CGlobals.Tin3D(i).Elev2*ZRange,red,0,blue)
    Next
End Sub

Sub randpos As Float
    Return  Rnd(0,1000)/1000-.5
    
End Sub

Sub add_triangle(x0 As Float,y0 As Float,z0 As Float,x1 As Float,y1 As Float,z1 As Float,x2 As Float,y2 As Float,z2 As Float,colr As Float,colg As Float,colb As Float)
    triangle(triangle_c,0) = x0
    triangle(triangle_c,1) = y0
    triangle(triangle_c,2) = z0
    triangle(triangle_c,3) = x1
    triangle(triangle_c,4) = y1
    triangle(triangle_c,5) = z1
    triangle(triangle_c,6) = x2
    triangle(triangle_c,7) = y2
    triangle(triangle_c,8) = z2
    triangle(triangle_c,9) = colr/255
    triangle(triangle_c,10) = colg/255
    triangle(triangle_c,11) = colb/255
    triangle_c = triangle_c+1
    
End Sub

Sub Panel2_Touch (Action As Int, X As Float, Y As Float)
    
    If Action = Panel2.ACTION_MOVE  Then
        Touchpanel_data(2) = Touchpanel_data(2)+(Touchpanel_data(0)-x)*.15
        Touchpanel_data(3) = Touchpanel_data(3)+(Touchpanel_data(1)-y)*.15
    End If

    Touchpanel_data(0) = X
    Touchpanel_data(1) = y
End Sub

Sub opengl_render_tick
    OpenGL.RequestRender
    Label.Text = "ANG1:"& NumberFormat(Touchpanel_data(2), 1, 1) &"  ANG2:"  &   NumberFormat(Touchpanel_data(3), 1, 1) & "  DISTANCE:"& NumberFormat(Abs(zoom_distance), 1, 1)
    Label.Invalidate
End Sub

Sub opengl_draw(gl As GL1)
   
   
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)


   
   
    gl.glClearColor(.8, .8, .8, 1)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    gl.glEnable(gl.GL_NORMALIZE)

    gl.glLoadIdentity
   
    gl.glTranslatef(0,0,zoom_distance)
    gl.glrotatef(-Touchpanel_data(3),1,0,0)
    gl.glrotatef(-Touchpanel_data(2),0,1,0)
   
   
   
   
    gl.glFrontFace(gl.GL_CCW)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)

    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glDepthMask(True)
    gl.glDisable(gl.GL_BLEND)
   
    gl.glPushMatrix
   
   

    Dim vertices(9) As Float
    For at = 0 To triangle_c-1
           
        For t = 0 To 8:vertices(t) = triangle(at,t):Next
            gl.glVertexPointerf(3,  vertices)
            gl.glColor4f(triangle(at,9),triangle(at,10),triangle(at,11), 1) ' RGBA = Red    ' Set the color to red for the triangle
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
        Next
        
        gl.glPopMatrix
        gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
        
    End Sub

Sub opengl_SurfaceChanged(gl As GL1, width As Int, height As Int)
   
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.gluPerspective(60,width/height,0.01,6)
    gl.glMatrixMode(gl.GL_MODELVIEW)

   
End Sub


Sub SeekBar_ValueChanged (Value As Int, UserChanged As Boolean)
    zoom_distance = -(100-Value)*.05
End Sub

#End Region
/CODE]
 
Upvote 0

MasterGy

Member
Licensed User
Hi MasterGy, I have used your code and then added a routine to read in my Triangles from the Tin Model. As you said that the coordinates must be between -1 and 1 , I calculated a "Scale Factor" which is applied to each Coordinate to stay between -1 and 1.

My problem is that the screen stays black in Debug mode and a olive green in Release mode.

When looking at the code, please bear in mind that in South Africa we call the Horizontal Axis the "Y" coordinate and the Vertical Axis the "X" coordinate. Its a mirror naming of the rest of the World.

I have adjusted the RGB colors according to the heights of the Vertexes.

Code:

Code:
[
#Region ****************************************************** Start **********************************************

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim Panel1,Panel2 As Panel
    Dim Butt1 As ImageView
    Dim Label As Label
   
    Dim OpenGL_timer As Timer
    Dim triangle_c As Int
    Dim triangle(20000,12) As Float '012-x0y0z0 345-x1y1z1 678-x2y2z2 ,9,10,11 RGB
   
    Dim OpenGL As GLSurfaceView
    Dim Seekbar As SeekBar
    Dim Touchpanel As Panel
    Dim Touchpanel_data(10) As Float
    Dim zoom_distance As Float
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Plot3D")
    Activity.Title="Plot 3D"
    Panel1.Visible=True
    Seekbar.Value=50
   
   
    'opengl, opengltimer
    OpenGL.Initialize(OpenGL.RENDERMODE_WHEN_DIRTY, "opengl")
    If OpenGL.IsInitialized Then
        Panel2.AddView(OpenGL, 0, 0, 100%x, 100%y)
    Else
        Log("OpenGL initialization failed")
    End If

    OpenGL_timer.Initialize("opengl_render",60)

    ScaleTin
'    For t = 0 To 10
'        add_triangle(randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,randpos,Rnd(0,150),Rnd(0,150),Rnd(0,150))
'    Next
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

#End Region

#Region ******************************************************** Buttons Pressed ****************************************************

Sub Butt1_Click
    Activity.Finish
End Sub

#End Region

#Region ******************************************************* Calcs ************************************************************

Sub ScaleTin
    Dim Count,i As Int
    Dim YRange,XRange,ZRange As Double
    Dim AveElev As Double
   
    Engine.GetTriangles(2)
    Count=CGlobals.MaxTins        'Number of Triangles
   
    'Next work out a scale factor so that the real world coords are between -1 and 1
    YRange=1.9/(CGlobals.YMaxCoord-CGlobals.YMinCoord)
    XRange=1.9/(CGlobals.XMaxCoord-CGlobals.XMinCoord)
    ZRange=1.9/(CGlobals.ZMaxCont-CGlobals.ZMinCont)
   
    For i=0 To Count-1
        'Calc the average Height of the Triangle
        AveElev=(CGlobals.Tin3D(i).Elev + CGlobals.Tin3D(i).Elev1 + CGlobals.Tin3D(i).Elev2)/3
       
        'Calc the Color shading according to the average Height
        'Red is heighest and Blue is lowest with other colors inbetween
        Dim ratio As Float = (i - CGlobals.ZMinCont) / (CGlobals.ZMaxCont - CGlobals.ZMinCont)
        Dim red As Int = 255 * ratio
        Dim blue As Int = 255 * (1 - ratio)
       
        'Add the Triangle
        add_triangle(CGlobals.Tin3D(i).East*YRange,CGlobals.Tin3D(i).North*XRange,CGlobals.Tin3D(i).Elev*ZRange,CGlobals.Tin3D(i).East1*YRange,CGlobals.Tin3D(i).North1*XRange,CGlobals.Tin3D(i).Elev1*ZRange,CGlobals.Tin3D(i).East2*YRange,CGlobals.Tin3D(i).North2*XRange,CGlobals.Tin3D(i).Elev2*ZRange,red,0,blue)
    Next
End Sub

Sub randpos As Float
    Return  Rnd(0,1000)/1000-.5
   
End Sub

Sub add_triangle(x0 As Float,y0 As Float,z0 As Float,x1 As Float,y1 As Float,z1 As Float,x2 As Float,y2 As Float,z2 As Float,colr As Float,colg As Float,colb As Float)
    triangle(triangle_c,0) = x0
    triangle(triangle_c,1) = y0
    triangle(triangle_c,2) = z0
    triangle(triangle_c,3) = x1
    triangle(triangle_c,4) = y1
    triangle(triangle_c,5) = z1
    triangle(triangle_c,6) = x2
    triangle(triangle_c,7) = y2
    triangle(triangle_c,8) = z2
    triangle(triangle_c,9) = colr/255
    triangle(triangle_c,10) = colg/255
    triangle(triangle_c,11) = colb/255
    triangle_c = triangle_c+1
   
End Sub

Sub Panel2_Touch (Action As Int, X As Float, Y As Float)
   
    If Action = Panel2.ACTION_MOVE  Then
        Touchpanel_data(2) = Touchpanel_data(2)+(Touchpanel_data(0)-x)*.15
        Touchpanel_data(3) = Touchpanel_data(3)+(Touchpanel_data(1)-y)*.15
    End If

    Touchpanel_data(0) = X
    Touchpanel_data(1) = y
End Sub

Sub opengl_render_tick
    OpenGL.RequestRender
    Label.Text = "ANG1:"& NumberFormat(Touchpanel_data(2), 1, 1) &"  ANG2:"  &   NumberFormat(Touchpanel_data(3), 1, 1) & "  DISTANCE:"& NumberFormat(Abs(zoom_distance), 1, 1)
    Label.Invalidate
End Sub

Sub opengl_draw(gl As GL1)
  
  
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glDisableClientState(gl.GL_NORMAL_ARRAY)


  
  
    gl.glClearColor(.8, .8, .8, 1)
    gl.glClear(Bit.Or(gl.GL_COLOR_BUFFER_BIT, gl.GL_DEPTH_BUFFER_BIT))

    gl.glEnable(gl.GL_NORMALIZE)

    gl.glLoadIdentity
  
    gl.glTranslatef(0,0,zoom_distance)
    gl.glrotatef(-Touchpanel_data(3),1,0,0)
    gl.glrotatef(-Touchpanel_data(2),0,1,0)
  
  
  
  
    gl.glFrontFace(gl.GL_CCW)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)

    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glDepthFunc(gl.GL_LEQUAL)
    gl.glDepthMask(True)
    gl.glDisable(gl.GL_BLEND)
  
    gl.glPushMatrix
  
  

    Dim vertices(9) As Float
    For at = 0 To triangle_c-1
          
        For t = 0 To 8:vertices(t) = triangle(at,t):Next
            gl.glVertexPointerf(3,  vertices)
            gl.glColor4f(triangle(at,9),triangle(at,10),triangle(at,11), 1) ' RGBA = Red    ' Set the color to red for the triangle
            gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
        Next
       
        gl.glPopMatrix
        gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
       
    End Sub

Sub opengl_SurfaceChanged(gl As GL1, width As Int, height As Int)
  
    gl.glViewport(0, 0, width, height)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.gluPerspective(60,width/height,0.01,6)
    gl.glMatrixMode(gl.GL_MODELVIEW)

  
End Sub


Sub SeekBar_ValueChanged (Value As Int, UserChanged As Boolean)
    zoom_distance = -(100-Value)*.05
End Sub

#End Region
/CODE]
Hi !

Unfortunately I couldn't test the code because 'engine', 'cglobals' are missing.

Unfortunately, there are cases when the 'debug' mode cannot be used. Examples include 'opengl', 'thread', and there are certainly times when it doesn't work.

I don't know why in oil-green 'release' mode. You can set the screen background here:
gl.glClearColor(.8, .8, .8, 1)

Order : RGBA. Not 0-255, but in the range 0-1!

I would like to see a screenshot of the final result, I'm curious how many triangles you display.

If you want to further develop the program and need the 'debug' mode, it can be solved by not using opengl, but simple drawing on CANVAS. Unfortunately, this way the triangles would have no color and the center would be empty. so you would only draw it from lines. OpenGL is much more spectacular (you can add light effects, fog effects, etc.), but if your goal is to be able to develop the triangle generation part in debug mode, then I can help you prepare a wireframe drawing version.
 
Upvote 0

Terradrones

Active Member
Licensed User
Hi, I would like to solve the OpenGL issue, as you have rightly mentioned that OpenGL is much more spectacular.

In "Engine" I read my Triangles from a File and in "CGlobals" I keep the variables:

This is what is in "Engine":

B4X:
Public Sub GetTriangles(A As Int)
    Dim i,i1 As Int
    
    CGlobals.ZMinCont = 99999999
    CGlobals.ZMaxCont = -99999999
    CGlobals.YMinCoord = 99999999
    CGlobals.YMaxCoord = -99999999
    CGlobals.XMinCoord = 99999999
    CGlobals.XMaxCoord = -99999999
    
    CGlobals.CreateOtherTables
    i=-1
    Try
        If A=1 Then
            Dim rs As ResultSet = CGlobals.sql1.ExecQuery("SELECT East1, North1, Elevation1, East2, North2, Elevation2, East3, North3, Elevation3, Area FROM Tin")
        Else
            Dim rs As ResultSet = CGlobals.sql1.ExecQuery("SELECT East1, North1, Elevation1, East2, North2, Elevation2, East3, North3, Elevation3, Area FROM Stock")
        End If
        Do While rs.NextRow
            i=i+1
            If i>95000 Then i=95000
            CGlobals.Tin3D(i).East = NumberFormat2(rs.GetDouble("East1"),1,3,3,False)
            CGlobals.Tin3D(i).North = NumberFormat2(rs.GetDouble("North1"),1,3,3,False)
            CGlobals.Tin3D(i).Elev = NumberFormat2(rs.GetDouble("Elevation1"),1,3,3,False)
            CGlobals.Tin3D(i).East1 = NumberFormat2(rs.GetDouble("East2"),1,3,3,False)
            CGlobals.Tin3D(i).North1 = NumberFormat2(rs.GetDouble("North2"),1,3,3,False)
            CGlobals.Tin3D(i).Elev1 = NumberFormat2(rs.GetDouble("Elevation2"),1,3,3,False)
            CGlobals.Tin3D(i).East2 = NumberFormat2(rs.GetDouble("East3"),1,3,3,False)
            CGlobals.Tin3D(i).North2 = NumberFormat2(rs.GetDouble("North3"),1,3,3,False)
            CGlobals.Tin3D(i).Elev2 = NumberFormat2(rs.GetDouble("Elevation3"),1,3,3,False)
            CGlobals.Tin3D(i).Area = NumberFormat2(rs.GetDouble("Area"),1,3,3,False)
            CGlobals.ZMinCont = Min(CGlobals.ZMinCont, CGlobals.Tin3D(i).Elev)
            CGlobals.ZMaxCont = Max(CGlobals.ZMaxCont, CGlobals.Tin3D(i).Elev)
            CGlobals.ZMinCont = Min(CGlobals.ZMinCont, CGlobals.Tin3D(i).Elev1)
            CGlobals.ZMaxCont = Max(CGlobals.ZMaxCont, CGlobals.Tin3D(i).Elev1)
            CGlobals.ZMinCont = Min(CGlobals.ZMinCont, CGlobals.Tin3D(i).Elev2)
            CGlobals.ZMaxCont = Max(CGlobals.ZMaxCont, CGlobals.Tin3D(i).Elev2)
            
            CGlobals.YMinCoord = Min(CGlobals.YMinCoord, CGlobals.Tin3D(i).East)
            CGlobals.XMinCoord = Min(CGlobals.XMinCoord, CGlobals.Tin3D(i).North)
            CGlobals.YMinCoord = Min(CGlobals.YMinCoord, CGlobals.Tin3D(i).East1)
            CGlobals.XMinCoord = Min(CGlobals.XMinCoord, CGlobals.Tin3D(i).North1)
            CGlobals.YMinCoord = Min(CGlobals.YMinCoord, CGlobals.Tin3D(i).East2)
            CGlobals.XMinCoord = Min(CGlobals.XMinCoord, CGlobals.Tin3D(i).North2)
            
            CGlobals.YMaxCoord = Min(CGlobals.YMaxCoord, CGlobals.Tin3D(i).East)
            CGlobals.XMaxCoord = Min(CGlobals.XMaxCoord, CGlobals.Tin3D(i).North)
            CGlobals.YMaxCoord = Min(CGlobals.YMaxCoord, CGlobals.Tin3D(i).East1)
            CGlobals.XMaxCoord = Min(CGlobals.XMaxCoord, CGlobals.Tin3D(i).North1)
            CGlobals.YMaxCoord = Min(CGlobals.YMaxCoord, CGlobals.Tin3D(i).East2)
            CGlobals.XMaxCoord = Min(CGlobals.XMaxCoord, CGlobals.Tin3D(i).North2)
        Loop
        rs.Close
        CGlobals.MaxTins=i
    Catch
        Log(LastException)
    End Try
End Sub

This is what is in "CGlobals":

Type TINModel(Name As String, East As Double,North As Double,Elev As Double, East1 As Double,North1 As Double,Elev1 As Double, East2 As Double,North2 As Double,Elev2 As Double,Area As Double)
Public Tin3D(42000) As TINModel
 
Upvote 0

Terradrones

Active Member
Licensed User
With the next code I use a normal canvas and shade the Triangles of the Tin Model according to the heights of the vertexes:

B4X:
#Region ****************************************************** Shade TIN Model **********************************************************

Sub EditText1_FocusChanged(HasFocus As Boolean)
    If HasFocus =False Then
        If IsNumber(EditText1.Text) = False Then EditText1.Text=2
        EditText1.Text=NumberFormat2(EditText1.Text,1,0,0,False)
    Else
        EditText1.SelectAll
    End If
End Sub

Sub Butt2_Click
    If IsNumber(EditText1.Text)=False Or EditText1.Text<1 Then
        EditText1.Text=2
    End If
    EndCont.RequestFocus
    Panels
    Panel1.Visible=True
    ProgressDialogShow2("Generating Height Shading...",False)
    Sleep(0)
    FillTIN
    Shade=True
End Sub

Sub Butt1_Click
    'Exit
    Panels
    Panel1.Visible=True
End Sub

Sub FillTIN
    Dim i As Int
    Dim triangles As List
    Dim vertices As List
    
    HeightRanges.Initialize
    ColorsList.Initialize
    
    For i=Floor(CGlobals.ZMinCont) To Floor(CGlobals.ZMaxCont) Step EditText1.Text
        HeightRanges.Add(i)
        Dim ratio As Float = (i - CGlobals.ZMinCont) / (CGlobals.ZMaxCont - CGlobals.ZMinCont)
        Dim red As Int = 255 * ratio
        Dim blue As Int = 255 * (1 - ratio)
        ColorsList.Add(Colors.RGB(red, 0, blue))
    Next
    
    i=0
    Do While i<=CGlobals.MaxTins
        
        vertices.Initialize
        vertices.Add(Array As Float(CGlobals.Tin3D(i).East, CGlobals.Tin3D(i).North, CGlobals.Tin3D(i).Elev)) ' x, y, height
        vertices.Add(Array As Float(CGlobals.Tin3D(i).East1, CGlobals.Tin3D(i).North1, CGlobals.Tin3D(i).Elev1))
        vertices.Add(Array As Float(CGlobals.Tin3D(i).East2, CGlobals.Tin3D(i).North2, CGlobals.Tin3D(i).Elev2))
        
        triangles.Initialize
        triangles.Add(Array As Int(0, 1, 2)) ' Indices of vertices forming a triangle
    
        ColorTINModel(vertices, triangles)
        i=i+1
    Loop
    DrawLegend
    ProgressDialogHide
End Sub

Sub ColorTINModel(vertices As List, triangles As List)
    For Each triangle() As Int In triangles
        Dim v1() As Float = vertices.Get(triangle(0))
        Dim v2() As Float = vertices.Get(triangle(1))
        Dim v3() As Float = vertices.Get(triangle(2))
        
        ' Calculate average height
        Dim avgHeight As Float = (v1(2) + v2(2) + v3(2)) / 3
        
        ' Determine color based on height
        Dim color As Int = GetColorFromHeight(avgHeight)
        
        ' Draw the filled triangle
        DrawFilledTriangle(v1(0), v1(1), v2(0), v2(1), v3(0), v3(1), color)
    Next
End Sub

Sub DrawFilledTriangle(Y21 As Float, X21 As Float, Y22 As Float, X22 As Float, Y23 As Float, X23 As Float, color As Int)
    Dim path As B4XPath
    
    X21 = ConvertToDrawingX(X21)
    Y21 = ConvertToDrawingY(Y21)
    X22 = ConvertToDrawingX(X22)
    Y22 = ConvertToDrawingY(Y22)
    X23 = ConvertToDrawingX(X23)
    Y23 = ConvertToDrawingY(Y23)
    path.Initialize(Y21, X21)
    path.LineTo(Y22, X22)
    path.LineTo(Y23, X23)
    path.LineTo(Y21, X21)
    
    cvsDrawing.DrawPath(path, color, True, 1)
    cvsDrawing.Invalidate
End Sub

Sub GetColorFromHeight(Height As Float) As Int
    ' Map height to a color gradient from blue (low) to red (high)
    Dim ratio As Float = (Height - CGlobals.ZMinCont) / (CGlobals.ZMaxCont - CGlobals.ZMinCont)
    Dim red As Int = 255 * ratio
    Dim blue As Int = 255 * (1 - ratio)
    Dim color As Int = Colors.RGB(red, 0, blue)
    Return color
End Sub

Sub ConvertToDrawingY(A As Double) As Double
    Return (A - SheetX0) * ScaleX + ScreenX0
End Sub

Sub ConvertToDrawingX(B As Double) As Double
    Return (B - SheetY0) * ScaleY + ScreenY0
End Sub

Sub DrawLegend
    Dim i As Int
    Dim fnt As B4XFont
    Dim Color As Int
    Dim Top As Int
    
    fnt = xui.CreateDefaultFont(12)
    For i = 1 To HeightRanges.Size - 1
        Color = ColorsList.Get(i)
        Top = (i * 30) + 25
        cvsDrawing.DrawLine(10,Top,40,Top,Color,25)
        cvsDrawing.DrawText(HeightRanges.Get(i-1) & " - " & HeightRanges.Get(i),47,Top+8,fnt, Colors.Black, "LEFT")
    Next
    cvsDrawing.Invalidate
End Sub

#End Region
 
Upvote 0

Terradrones

Active Member
Licensed User
Hi, the proposed 3D view is part of the "Stockpile" activity, where one can import points from a csv file, create a TIN Model, generate contours, calculate volumes, etc.


I am attaching a file which you can import and also the "StockCalcs.bas" file which contains the complete code of the Activity.
 

Attachments

  • StockCalcs.bas
    49.7 KB · Views: 12
Upvote 0
Top