ocliff

02-07-2005, 06: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, 07: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, 09: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, 06: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, 08: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, 03: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?