ocliff
02-07-2005, 05:49 AM
I'm trying to triangulate some polygons. It's not easy to use the GL Utility library (glu32.dll) from VB, but I guess you could write a dll in C/C++ that acts as a wrapper. I have very little experience in that area, would anyone like to help me? I know how it should work in theory and there is a good example of c-code at:
http://graphicsbb.itgo.com/solutions/extrude.html
I would like to put that code (the triangulation-part) into a c/c++ dll so that it is accessible from VB.
Any help and directsion is appreciated!
00100b
02-07-2005, 06:24 AM
Recruitment to have somebody develop you a DLL is not permitted on this site.
Here in the Interface & Graphics forum however, you may find somebody with experience in developing a solution that can assist you in providing direction.
ocliff
02-07-2005, 08:33 AM
Recruitment to have somebody develop you a DLL is not permitted on this site.
Here in the Interface & Graphics forum however, you may find somebody with experience in developing a solution that can assist you in providing direction.
Sorry, I did not mean to recruite someone to create a DLL for me, I meant to ask for help in as in 'how do you create a dll' in c/c++ for use in vb. Thats why I asked for help and directions. Sorry about not being crystal clear. If I only wanted a dll, I would just post at rentacoder... :) But I want to learn how to do it myself.
ocliff
02-14-2005, 05:54 AM
Hi again, I'm back with some working code. The function 'triangulate' takes a polygon in the form of an array of points (as doubles), triangulates the polygon and returns a new array where the triangles are stored as three points following each other.
It is the CombineCB function (which is used for self-intersecting polygons) that I don't know how to write, I have looked at many examples but the ones I have tried have made errors in the resulting list of triangles.
Option Explicit
Private Type VERTEX
x As Double
y As Double
z As Double
End Type
Public Type POINTAPI_DOUBLE
x As Double
y As Double
End Type
Private Mode&
Private tesspoints(0 To 2) As Long
Private triangles() As Long
Private index As Long
Private TIndex As Long
Private Poly() As VERTEX
Declare Sub CopyToDoubleFromPtr Lib "kernel32" Alias "RtlMoveMemory" (Dest#, ByVal PtrSrc&, ByVal length&)
Public Function triangulate(polypoint() As POINTAPI_DOUBLE) As POINTAPI_DOUBLE()
Dim tobj&
Dim i As Long
TIndex = 0
tobj = gluNewTess
gluTessCallback tobj, GLU_TESS_BEGIN, AddressOf glBeginCB
gluTessCallback tobj, GLU_TESS_END, AddressOf glEndCB
gluTessCallback tobj, GLU_TESS_ERROR, AddressOf glErrorCB
gluTessCallback tobj, GLU_TESS_VERTEX, AddressOf glVertex3dvCB
'gluTessCallback tobj, GLU_TESS_COMBINE, AddressOf CombineCB
ReDim Poly(0 To UBound(polypoint) - 1) As VERTEX
For i = 0 To UBound(Poly)
Poly(i).x = polypoint(i).x
Poly(i).y = polypoint(i).y
Poly(i).z = 0
Next
Dim id() As Double
ReDim id(0 To UBound(Poly)) As Double
ReDim triangles(0 To UBound(Poly) * 3) As Long
gluTessBeginPolygon tobj, 0&
gluTessBeginContour tobj
For i = 0 To UBound(Poly)
id(i) = i
gluTessVertex tobj, Poly(i).x, id(i)
Next
gluTessEndContour tobj
gluTessEndPolygon tobj
Dim retur() As POINTAPI_DOUBLE
ReDim retur(0 To TIndex - 1) As POINTAPI_DOUBLE
For i = 0 To TIndex - 1
retur(i).x = Poly(triangles(i)).x
retur(i).y = Poly(triangles(i)).y
Next
triangulate = retur
End Function
Sub glBeginCB(ByVal which&)
Dim S$
glBegin which
Mode = which
index = 0
End Sub
Sub glEndCB()
glEnd
End Sub
Sub glErrorCB(ByVal errorCode&) '???
Dim estring$, S$
estring = gluErrorString(errorCode)
Debug.Print "Tessellation Error: " & estring
Select Case errorCode
Case GLU_TESS_MISSING_BEGIN_POLYGON
Debug.Assert 0
Case GLU_TESS_MISSING_END_POLYGON
Debug.Assert 0
Case GLU_TESS_MISSING_BEGIN_CONTOUR
Debug.Assert 0
Case GLU_TESS_MISSING_END_CONTOUR
Debug.Assert 0
Case GLU_TESS_COORD_TOO_LARGE
Debug.Assert 0
Case GLU_TESS_NEED_COMBINE_CALLBACK
Debug.Assert 0
Case errorCode >= GLU_TESS_ERROR1 And errorCode <= GLU_TESS_ERROR8
'10151-10158
Debug.Assert 0
Case Else
Debug.Assert 0
End Select
Stop
End Sub
Sub glVertex3dvCB(ByRef arg#)
glVertex3dv arg
tesspoints(index) = arg
index = index + 1
Select Case Mode
Case 4
If index = 3 Then
triangles(TIndex) = tesspoints(0)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(1)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(2)
TIndex = TIndex + 1
index = 0
End If
Case 5
If index = 3 Then
If (Not (index And &H1)) Then
triangles(TIndex) = tesspoints(0)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(1)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(2)
TIndex = TIndex + 1
Else
triangles(TIndex) = tesspoints(1)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(2)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(0)
TIndex = TIndex + 1
End If
tesspoints(0) = tesspoints(1)
tesspoints(1) = tesspoints(2)
index = 2
End If
Case 6
If index = 3 Then
triangles(TIndex) = tesspoints(0)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(1)
TIndex = TIndex + 1
triangles(TIndex) = tesspoints(2)
TIndex = TIndex + 1
tesspoints(1) = tesspoints(2)
index = 2
End If
End Select
End Sub
This is one example of the CombineCB that I have used:
Sub CombineCB(Coords As VERTEX, ByVal vdata&, ByVal weight&, ByRef OutData&)
Dim cv As Long
cv = UBound(Poly) + 1
ReDim Preserve Poly(0 To cv) As VERTEX
Poly(cv).x = Coords.x
Poly(cv).y = Coords.y
Poly(cv).z = 0
OutData = VarPtr(cv)
ReDim Preserve triangles(0 To UBound(triangles) + 3) As Long
End Sub
Please help me, I'm stuck!
You need a reference to vbogl.tbl from http://home.pacific.net.hk/~edx/tlb.htm
Here is some code for a polygon that works:
Private Sub cmdTest_Click()
Dim polypoint(0 To 8) As POINTAPI_DOUBLE
polypoint(0).x = 10
polypoint(0).y = 0
polypoint(1).x = 40
polypoint(1).y = 0
polypoint(2).x = 40
polypoint(2).y = 10
polypoint(3).x = 15
polypoint(3).y = 10
polypoint(4).x = 15
polypoint(4).y = 30
polypoint(5).x = 40
polypoint(5).y = 30
polypoint(6).x = 40
polypoint(6).y = 40
polypoint(7).x = 10
polypoint(7).y = 40
polypoint(8).x = 10
polypoint(8).y = 0
Dim triangles() As POINTAPI_DOUBLE
triangles = triangulate(polypoint)
Dim i As Integer
For i = 0 To UBound(triangles) Step 3
MsgBox triangles(i).x & "," & triangles(i).y & " / " & triangles(i + 1).x & "," & triangles(i + 1).y & " / " & triangles(i + 2).x & "," & triangles(i + 2).y
Next
End Sub
ocliff
02-14-2005, 07:09 AM
Heureka! It works! I found the bug! I now have a complete working version of this triangulator/tesselator which is extremely fast compared to native vb such as the Delauney algorithm.
fobru
09-28-2005, 02:17 AM
I'm looking for the same thing as you do, can you send me the correct code, also of combineCB? Is it also possible to make a hole in a polygon with this code?