Polygone concave OpenGL/VB6

Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015 - 6 mars 2013 à 14:09
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015 - 21 mars 2013 à 09:41
Bonjour,

Grace au tutoriel d'Arkham, je suis en train de prendre en main OpenGL avec un soft VB6, ce qui me permet de faire un viewer dans mon soft qui utilisait pour le moment une vue en perspective isométrique filaire.
Miniature :
Lien vers l'image en grand
On voit sur la capture ci-dessus le problème que je rencontre : les faces rouges sont des polygones concaves. OpenGL ne gère que les convexes, il faut donc tesselariser les faces.

Je suppose qu'il me faut utiliser la fonction "gluNewTess", mais là j'atteins mes limites de programmeur autodidacte qui n'y entend rien au C : quasiment toutes les sources que je trouve sur le sujet sont en C et je n'arrive pas à les transposer dans le code du tuto d'Arkham.

Le seul code que j'ai trouvé pendant mes longues heures de recherche et qui serait peut-être exploitable est pour VB5 (visible ICI), mais j'avoue avoir du mal à faire le transfert...

Voudriez-vous me filer un coup de main?

Ci-dessous le code de mon module 3D OpenGL

Merci pour votre aide.

Renaud.

Option Explicit


' Temps à attendre pour le prochaine affichage
Private gWaitTime As Long
' Temps écoulé pour calcul du frame rate
Private gElapsedTime As Long
' Nombre d'affichage pour calcul du frame rate
Private gDisplayCount As Long
' RotationX
Private gRotateX As Double
' RotationY
Private gRotateY As Double
' Zoom
Private gZoom As Double

Sub Fenetre_OpenGL()
   ' Chargement de freeglut
   If LoadLibrary(App.Path & "\freeglut.dll") = 0 Then
       MsgBox "Impossible de charger la librairie freeglut"
       Exit Sub
   End If
   ' Initialisation de la librairie
   glutInit 0&, ""
   ' Initialisation du mode d'affichage
   glutInitDisplayMode GLUT_RGBA Or GLUT_DOUBLE Or GLUT_DEPTH
   ' Création d'une fenêtre
   glutCreateWindow "Tutoriel fenêtre GLUT"
   ' Définition de l'option de sortie de boucle
   glutSetOption GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS
   ' Fonction d'affichage
   glutDisplayFunc AddressOf CallBackDraw
   ' Fonction d'attente
   glutIdleFunc AddressOf CallBackIdle
   ' Fonctions de rappel clavier
   glutSpecialFunc AddressOf CallBackSpecial
   ' Fonction de rappel molette de souris
   glutMouseWheelFunc AddressOf CallBackMouseWheel
   ' Appel de la fonction d'initialisation
   InitScene
   ' Boucle principale
   glutMainLoop
End Sub

Public Sub InitScene()
   ' Initialisation du temps déclencheur de l'affichage
   gWaitTime = glutGet(GLUT_ELAPSED_TIME)
   ' Tests de profondeur
   glEnable GL_DEPTH_TEST
   glDepthFunc GL_LEQUAL
   
   ' Initialisation des variables de visualisation
   gRotateX = 0
   gRotateY = 0
   gZoom = 10
End Sub

' Fonction d'affichage
Public Sub CallBackDraw()
   'appel de la fonction de rendu
   Call Render
   ' Echange les buffers
   glutSwapBuffers
   ' Calcul et affichage du frame rate
   gDisplayCount = gDisplayCount + 1
   If gDisplayCount = 100 Then
       glutSetWindowTitle "Frame rate : " & format(gDisplayCount / (glutGet(GLUT_ELAPSED_TIME) - gElapsedTime) * 1000, "0,0")
       gDisplayCount = 0
       gElapsedTime = glutGet(GLUT_ELAPSED_TIME)
   End If
End Sub

Public Sub CallBackIdle()
   Dim lTimer As Long
   
   ' Temps présent
   lTimer = glutGet(GLUT_ELAPSED_TIME)
   ' Si temps présent >= au temps attendu
   If lTimer >= gWaitTime Then
       ' Rrafraichir l'affichage
       glutPostRedisplay
       ' n affichages par seconde
       gWaitTime = lTimer + (1000 / 50)
   End If
End Sub

Public Sub Render()
   Dim i As Long
   
   ' Passage en matrice de projection
   glMatrixMode GL_PROJECTION
   ' Initialisation de la matrice
   glLoadIdentity
   ' Définition de la perspective
   gluPerspective 45, 1, 0.1, 100
   ' Passage en matrice de modélisation-visualisation
   glMatrixMode GL_MODELVIEW
   ' Initialisation de la matrice
   glLoadIdentity
   
   ' Position de la caméra
   gluLookAt 0, 0, gZoom, 0, 0, 0, 0, 1, 0
   glRotated gRotateX, 1, 0, 0
   glRotated gRotateY, 0, 1, 0
   
   ' Vide les buffers couleur et profondeur
   glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
   
' Sauvegarde la matrice
glPushMatrix
' Rotation du cube
glRotated 30, 1, 1, 1

' Début de la primitive pour l'aile
glBegin GL_TRIANGLE_STRIP  'triangles en bande
   'en vert
    Call glColor3d(0, 1, 0)
    'les points alternativement d'un côté et de l'autre
    With ProfilInitial
         For i = 1 To .NbPointsE
          Call glVertex3d(.PointE(i).x, .PointE(i).y, 0)
          Call glVertex3d(.points(i).x, .points(i).y, .EcartementZ)
         Next i
      'fin de la primitive
      glEnd
      'les faces
      glBegin GL_POLYGON
         Call glColor3d(1, 0, 0)
      
         For i = 1 To .NbPointsE
          Call glVertex3d(.PointE(i).x, .PointE(i).y, 0)
         Next i
      glEnd
      glBegin GL_POLYGON
         Call glColor3d(1, 0, 0)
         For i = 1 To .NbPointsE
          Call glVertex3d(.points(i).x, .points(i).y, .EcartementZ)
         Next i
      glEnd
   End With

' Restaure la matrice
glPopMatrix
End Sub

'gestion des rotations avec les flèches du clavier
Public Sub CallBackSpecial(ByVal key As Long, ByVal x As Long, ByVal y As Long)
Select Case key
    Case GLUT_KEY_LEFT
        gRotateY = gRotateY - 10
    Case GLUT_KEY_RIGHT
        gRotateY = gRotateY + 10
    Case GLUT_KEY_UP
        gRotateX = gRotateX - 10
    Case GLUT_KEY_DOWN
        gRotateX = gRotateX + 10
   Case GLUT_KEY_F2
      gZoom = gZoom + 1
   Case GLUT_KEY_F3
      gZoom = gZoom - 1
End Select
End Sub

'gestion du zoom avec la molette de la souris
Public Sub CallBackMouseWheel(ByVal wheel As Long, ByVal direction As Long, ByVal x As Long, ByVal y As Long)
   gZoom = gZoom + direction
End Sub



Tarz.
A voir également:

13 réponses

CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
11 mars 2013 à 15:29
Bonjour Tarz,
Pour les programmeurs autodidactes que nous sommes ce domaine est extrêmement complexe.
Je te conseil donc vivement de ne pas trop utiliser les fonctions polygones d'OpenGL.

Partant du principe que tout polygones peut se diviser en une série de triangles je te conseil donc de t'orienter sur ce domaine, l'évolution d'OpenGL ce dirige en ce sens et si tu veux un jour pouvoir migrer en vb.net tu aura bcp plus de facilité en gérant ce domaine de cette façon.

Ma solution consisterait donc a transformer un polygone en une série de triangle.
En ce domaine Triangle Strip serait intéressant a utiliser même si pour ma part je préfère tout transformer en triangles normaux.

La difficulté réside a transformer un polygone concave en polygone convexe en possédant des coordonnées de points en 3D.

Mon idée:
Il serait je pense possible de transformer les coordonnées de point 3D en 2D pour diminuer le complexité du pb par par projection sur les axes repères.
Projection
Il suffit donc juste de retirer une des dimensions. (la plus adéquat)
Ensuite il faut déterminer comment diviser la forme en triangle.

Il existe il me semble un Algorithm qui s'y emploi de Hertel-Mehlhorn
Hertel-Mehlhorn
Personnellement je suis prêt a t'aider sur ce domaine.

Concernant la tesselation voici un lien trouvé sur le net.
Tessellation

Cordialement CGSI3
0
CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
11 mars 2013 à 16:25
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
13 mars 2013 à 17:22
Bonjour CGSI3,

Désolé de ne pas m'être manifesté plus tôt, mais je n'ai pas reçu de mail pour tes réponses...
C'est un coup de bol que je checke cette page.

J'ai suivi le même raisonnement que toi au début, puis je me suis dit que la triangulation, c'était justement ce que fait gluNewTess, et que faire un algo de triangulation (des polygones concaves) robuste qui tienne compte de tous les cas de figure risquait d'être long et casse-gueule.

Du coup je me suis acharné sur gluNewTess et j'ai pas mal progressé depuis mon premier post (à coup de dizaines d'heures de galère) et maintenant ça roule en utilisant gluNewTess dans une form vb6 en suivant la méthode d'Arkham64 sur developpez.com.

"Seul" souci : l'affichage initial marche à tous les coups, mais la tesselation plante parfois quand je cherche à faire tourner le truc dans tous les sens (avec la souris cliquée sur la fenêtre). Parfois ça marche, ça tourne dans tous les sens, on se déplace, on zoome, et parfois ça plante. Et ça plante plus avec l'exécutable compilé qu'en compilation à la volée dans vb6... arrrrrgh! Je vais essayer de transposer le tout dans une fenêtre freeglut pour voir si ça change quelque chose (vitesse de calcul).

Bon, là je vais avoir beaucoup de travail par ailleurs et je ne pourrai pas répondre avant plusieurs jours, mais je suis preneur de toute idée sur la cause du truc. Ci-dessous le code en question ; le plantage me renvoie à GLU_TESS_MISSING_BEGIN_POLYGON. Désolé, c'est un peu le bordel, mais j'ai pas eu le temps de tout bien mettre en ordre.

' Rendu de la scène
Public Sub Render()
   Dim i As Long
   
   
   ' Passage en matrice de projection
   glMatrixMode GL_PROJECTION
   ' Initialisation de la matrice
   glLoadIdentity
   ' Définition de la perspective
   gluPerspective 55, 1, 0.1, ProfilInitial.EcartementZ * 20
   ' Passage en matrice de modélisation-visualisation
   glMatrixMode GL_MODELVIEW
   ' Initialisation de la matrice
   glLoadIdentity
   
   ' Position de la caméra
   gluLookAt TranslateX, TranslateY, DistCamera, TranslateX, TranslateY, 0, 0, 1, 0
   
   ' Vide les buffers couleur et profondeur
   glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
   
' Sauvegarde la matrice
glPushMatrix

'initialisation de la transparence
'glEnable GL_BLEND
'glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA



   ' Rotation à partir de la souris
glRotated AngleY, 1, 0, 0
glRotated AngleX, 0, 1, 0


' Début de la primitive pour l'aile
glBegin GL_TRIANGLE_STRIP  'triangles en bande
    'les points alternativement d'un côté et de l'autre
      For i = 1 To UBound(Points3D_E)
         glColor3d 1, 0.6, 0.07 ' orange
         glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z
         glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z
      Next i
      'fin de la primitive
   glEnd
      
'glDisable GL_BLEND

      'les faces
         glColor3d 1, 0, 0 ' Rouge
tessEmplanture = gluNewTess
    gluTessCallback tessEmplanture, GLU_TESS_BEGIN, AddressOf glBeginCB
    gluTessCallback tessEmplanture, GLU_TESS_END, AddressOf glEndCB
    gluTessCallback tessEmplanture, GLU_TESS_ERROR, AddressOf glErrorCB
    gluTessCallback tessEmplanture, GLU_TESS_VERTEX, AddressOf glVertex3dvCB
    
    gluTessBeginPolygon tessEmplanture, 0  '(0 est un Long, on trouve parfois NULL)
        gluTessBeginContour tessEmplanture
      For i = 1 To UBound(Points3D_E)
               gluTessVertex tessEmplanture, Points3D_E(i).x, Points3D_E(i).x
            Next i
        gluTessEndContour tessEmplanture
    gluTessEndPolygon tessEmplanture
gluDeleteTess tessEmplanture

         glColor3d 0, 0, 1 ' Bleu
tessSaumon = gluNewTess
    gluTessCallback tessSaumon, GLU_TESS_BEGIN, AddressOf glBeginCB
    gluTessCallback tessSaumon, GLU_TESS_END, AddressOf glEndCB
    gluTessCallback tessSaumon, GLU_TESS_ERROR, AddressOf glErrorCB
    gluTessCallback tessSaumon, GLU_TESS_VERTEX, AddressOf glVertex3dvCB
    
    gluTessBeginPolygon tessSaumon, 0  '(0 est un Long, on trouve parfois NULL)
        gluTessBeginContour tessSaumon
      For i = 1 To UBound(Points3D_S)
               gluTessVertex tessEmplanture, Points3D_S(i).x, Points3D_S(i).x
            Next i
        gluTessEndContour tessSaumon
    gluTessEndPolygon tessSaumon
gluDeleteTess tessSaumon

' Restaure la matrice
glPopMatrix
End Sub

'**** les callback de gluNewTess

Private Sub glBeginCB(ByVal which As Long)
    glBegin which
End Sub

Private Sub glEndCB()
    glEnd
End Sub

Private Sub glErrorCB(ByVal errorCode As Long) '???
    Dim estring As String
    
    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

Private Sub glVertex3dvCB(ByRef arg As Double)
    glVertex3dv arg
    
End Sub


Tant que j'y suis, je te mets aussi le code de la form dans laquelle j'affiche tout ça. Il y a un timer et un combobox verrouillé en liste dessus, c'est une astuce pour récupérer la molette de la souris.
Option Explicit

' Classe pour affichage dans un form
Private oGl As clOpengGLFormVB6


Private Sub comboMouseWheel_KeyDown(KeyCode As Integer, Shift As Integer)
   Select Case KeyCode
   Case vbKeySpace   'la barre d'espace permet de passer d'un mode de représentation à l'autre
      TypeVisu = TypeVisu + 1
      If TypeVisu 3 Then TypeVisu 0
      Select Case TypeVisu
      Case 0
         glPolygonMode GL_FRONT_AND_BACK, GL_FILL
      Case 1
         glPolygonMode GL_FRONT_AND_BACK, GL_LINE
      Case 2
         glPolygonMode GL_FRONT_AND_BACK, GL_POINT
      End Select
   Case vbKeyReturn
      SaveToBMP App.Path & "\capture.bmp"
      MsgBox "Création du fichier " & App.Path & "\capture.bmp", vbInformation, "Capture"
   End Select
   Call Draw
   
End Sub

' Chargement du formulaire
Private Sub Form_Load()

'pour pouvoir utiliser la molette de la souris, on utilise le défilement d'un combobox et l'événement click
comboMouseWheel.left = 30000
comboMouseWheel.AddItem "Z+"
comboMouseWheel.AddItem "0"    'index 1
comboMouseWheel.AddItem "Z-"   'index 2

Set oGl = New clOpengGLFormVB6
oGl.InitOpenGL Me
' Appel de la fonction d'initialisation
Call InitScene

' Pour lancer l'affichage, on a besoin d'un événement qui vient de la form : on lance le timer
' (Juste faire Call Draw ne fonctionne pas!)
Me.GLTimer.Interval = 10

'on donne le focus à la combobox pour initialiser le zoom
comboMouseWheel.ListIndex = 1

End Sub

' Fonction d'affichage
Public Sub Draw()
' Appel de la fonction de rendu
Call Render
' Echange les buffers
oGl.Display
End Sub

' Initialisation de la scène
Public Sub InitScene()
' Mode d'affichage = remplissage
glPolygonMode GL_FRONT_AND_BACK, GL_FILL
' Tests de profondeur
glEnable GL_DEPTH_TEST
glDepthFunc GL_LEQUAL
' Initialisation des variables de visualisation
TranslateX = 0
TranslateY = 0
DistCamera = ProfilInitial.EcartementZ / 2 + ProfilInitial.CordeE
AngleX = 0
AngleY = 0
TypeVisu = 0
End Sub

Private Sub Form_MouseDown(button As Integer, Shift As Integer, x As Single, y As Single)
   If button = vbLeftButton Then
      Xold = x
      Yold = y
   End If
End Sub

Private Sub Form_MouseMove(button As Integer, Shift As Integer, x As Single, y As Single)
   Select Case button
   Case vbLeftButton
      AngleX = AngleX + (x - Xold) / 100
      AngleY = AngleY + (y - Yold) / 100
   Call Draw
   Case vbRightButton
      TranslateX = TranslateX - (x - Xold) / (10000 / ProfilInitial.EcartementZ)
      TranslateY = TranslateY + (y - Yold) / (10000 / ProfilInitial.EcartementZ)
   Call Draw
   End Select
   Xold = x
   Yold = y

End Sub

Private Sub Form_MouseUp(button As Integer, Shift As Integer, x As Single, y As Single)
   'on redonne le focus au zoom
   comboMouseWheel.ListIndex = 1
End Sub

' Le timer sert uniquement au chargement de la feuille pour lancer le premier affichage
Private Sub GLTimer_Timer()
   Call Draw
   GLTimer.Enabled = False
End Sub

Private Sub comboMouseWheel_Click()
   Select Case comboMouseWheel.ListIndex
   
   Case 0   'on est sur "Z+"
             DistCamera = DistCamera + ProfilInitial.EcartementZ / 5
   Case 1    'on est sur "0"
      Call Draw
   Case 2    'on est sur "Z-"
         DistCamera = DistCamera - ProfilInitial.EcartementZ / 5
   End Select
   comboMouseWheel.ListIndex = 1
   
End Sub


Tarz.
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
13 mars 2013 à 17:34
je n'ai pas reçu de mail pour tes réponses...

Forcément, mon email n'était pas à jour... je corrige.

Tarz.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
14 mars 2013 à 22:23
Bonjour Tarz,
Ton petit Post m'a mis un peu d'entrain et
Je suis en train de remettre a plat mes fonctions 2D.
Je vais en profiter pour construire une petite appli qui partitionne en triangle un polygone quelconque, puis améliorer une fonction d'enveloppement de formes (Identifier les bords d'un objets)
Je te recontacte ce week end
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
15 mars 2013 à 07:13
Bonjour CGSI3,

Très sympa à toi de te pencher sur mon problème.
Le plus important en premier : je t'ai fait un projet simplifié pour avoir facilement accès aux polygones de mes tests (ceux qui font planter). Ils sont dans des fichiers .txt de type .ini. Tu as la fonction de lecture.
C'est basé sur mon soft, donc il y a des trucs en trop, mais tu aura ainsi facilement des coordonnées un peu compliquées (attention, le premier point n'est pas dupliqué à la fin). Toutes les déclarations et les types sont regroupés dans un module. Tu devras probablement y jeter un oeil pour comprendre les structures.

J'y ai intégré la visu 3D. Donc il sera assez simple de faire des rendus, en remplaçant la partie gluNewTess par tes triangles.

Il y a deux boutons, ils ouvrent les mêmes polygones, mais un des fichiers n'est pas nettoyé par mon appli alors que l'autre l'est (le nettoyage vire les points alignés ou trop proches).

C'est dispo ici, sur cjoint

Quand tu cliques sur un des boutons, tu dois avoir la visu 3D qui s'ouvre. Chez moi (sous XP), elle plante très vite (et parfois elle ne plante pas, c'est pas sérieux cette histoire!)


Ca donne ça (visu en grand de la miniature ci-dessus).

Le moins important : pour info je suis sous XP, j'ai passé pas mal de temps à tout remettre dans une fenêtre Glut à la place d'une fenêtre VB6, mais j'ai le même problème. Note que ça m'a permis de mieux comprendre le fonctionnement de Glut et de la notion de callback, mais ça m'a aussi filé mal aux yeux (ben oui, boulot le jour, code la nuit, ça fatigue... )
Glut et OpenGL arrivent bien à trianguler mes faces, affichent le tout à l'écran, je commence à faire bouger/zoomer, ça tourne, puis ça plante.

Le gestionnaire d'erreur m'indique un truc du genre qu'il manque le début du polygone ; sauf qu'il l'a bien trouvé au premier affichage...!

Bref, la triangulation préalable serait probablement la solution, comme ça on ne gère que des primitives ultra-simples. J'ai essayé de voir si je peux récupérer la triangulation de gluNewTess, mais ça n'a pas l'air très simple (pour moi), d'autant que j'ai lu qu'il faut en plus identifier le type de primitive renvoyé par la fonction, type qui est variable (on en a besoin pour savoir comment sont organisés les points récupérés), genre des triangles simples ou des triangles en bande.

Bon, faut aller déjeuner et bosser... j'attends de tes nouvelles!

Tarz.
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
15 mars 2013 à 07:16
Petite précision : j'écris "les polygones" parce que ce ne sont pas les mêmes des deux côtés, mais ils ont le même nombre de points (qui sont reliés par des triangles en bande).

Tarz.
0
CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
16 mars 2013 à 08:26
Bonjour Tarz,
Au préalable j'ai bien réussi a charger ton petit fichier, je regarde cela ce matin.
Petite difficultée : je n ai plus vb6 installé donc je transfert donc tout sur vb.net 2008

Glut et OpenGL arrivent bien à trianguler mes faces, affichent le tout à l'écran, je commence à faire bouger/zoomer, ça tourne, puis ça plante.


Voila tout le pb d'OpenGL, définir d'ou viens le pb.

Pour info : j avais réalisé il y a longtemps une petite appli 3D, certe elle était très brouillon et peu expliqué mais elle pourrait peut être t'aider. (c'était mes débuts)

OPENGL-AVEC-VB6

Pense tu un jour migrer ton appli de base sur vb.Net ou est ce pour toi non envisageable?
car le vb.net permet surtout une gestion par class (et donc objet plus poussé ce qui est indispensable en 3D)
Et as tu vb.net d'installé?

J'analyse ton fichier et j'essai déjà de comprendre comment tu as réalisé ton appli.
A bientot cgsi3
0
CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
16 mars 2013 à 09:20
Voici un lien permettant aussi de se faire une idée d'un découpage de forme par des triangles.

Lien

L'idée est la, mais l'algo est cependant a modifier car tout ces triangles allongés ne sont absolument pas très graphiques, ils devrait se rapprocher bcp plus de triangles équilatéral ce qui permet une meilleur modification du maillage.

Je vais m'orienter sur ce sujet.
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
16 mars 2013 à 13:23
Bonjour,
Pense tu un jour migrer ton appli de base sur vb.Net ou est ce pour toi non envisageable?

C'est inenvisageable. Raisons multiples :
- Créer un .exe qui te demande de mettre à jour le Framemachin me branche moyen (ce qui est d'ailleurs devenu impossible sur mon PC depuis un plantage de ladite mise à jour pour cause de bas débit à l'époque).
- Quitte à prendre du temps à me former sur un autre langage, autant apprendre le C. Paradoxalement, à force de fouiller sur le net pour faire marcher OpenGL avec VB6 je commence à mieux appréhender la syntaxe en C (qui était du sombre chinois jusqu'à il y a quelques jours).

Bref, ce sera vb6 pour cette appli, ou rien.

Voila tout le pb d'OpenGL, définir d'ou viens le pb.

Pour le moment j'ai implémenté la visu 3D sans les faces de mon aile (juste l'enveloppe à base de triangle_strip et les contours à base de line_strip), avec un zeste de transparence c'est joli et ça ne plante pas. C'est bien la tesselation qui est en cause. Si tu veux tester, voici les primitives sans la tesselation
      ' Primitive pour l'enveloppe de l'aile
      'on va activer la transparence
      glEnable GL_BLEND
         glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
         
         glBegin GL_TRIANGLE_STRIP  'triangles en bande
            'les points alternativement d'un côté et de l'autre
            For i = 1 To UBound(Points3D_E)
               glColor4d 1, 0, 0, 0.5
               glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z
               glColor4d 0, 0, 1, 0.5
               glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z
            Next i
         glEnd
         'Primitive pour les contours des profils
         'Emplanture
         glBegin GL_LINE_STRIP  'lignes connectées
            'les points alternativement d'un côté et de l'autre
            For i = 1 To UBound(Points3D_E)
               glColor4d 1, 0, 0, 1
               glVertex3d Points3D_E(i).x, Points3D_E(i).y, Points3D_E(i).z
            Next i
         glEnd
         'Saumon
         glBegin GL_LINE_STRIP  'lignes connectées
            'les points alternativement d'un côté et de l'autre
            For i = 1 To UBound(Points3D_S)
               glColor4d 0, 0, 1, 1
               glVertex3d Points3D_S(i).x, Points3D_S(i).y, Points3D_S(i).z
            Next i
         glEnd
      glDisable GL_BLEND ' Désactive la transparence


La triangulation de ton lien donne effectivement des trucs un peu bizarres. Voici ce que donne gluNewTess avant de planter :

Ça ma paraît plus conforme à une représentation qui ne plantera pas quand l'utilisateur la fera tourner dans tous les sens...

Je vais regarder ton source. Je suis notamment intéressé par le texturage des triangles, tous les tutos parlent de carrés! J'aurais bien mis une image de billes de polystyrène en texture.

Tarz.
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
16 mars 2013 à 13:40
Juste une précision, le soft en question est "Complexes", soft de travail des profils pour la découpe cnc par fil chaud, dispo gratuitement sur le site 5xproject.

Les deux polygones sont parallèles dans deux plans (z=0 et z=écartement). On peut donc traiter en 2D.

Tarz.
0
CGSI3 Messages postés 416 Date d'inscription vendredi 22 février 2008 Statut Membre Dernière intervention 7 janvier 2018 1
21 mars 2013 à 08:32
Bonjour Tarz.
J'ai déjà une petite appli qui fonctionne (vb.net) , j'ai cependant des cas particuliers a résoudre.

Voici déjà quelques fonctions utiles pour ce genre d'appli 2D: (elles sont en vb.Net)
Je suis en train de les tester. La structure de Vector2 Correspond a celui d'un point avec X et Y en Attribut
mais bcp+ rapide d’exécution dans la bibliothèque écrite en c que j'utilise.

    ''' <summary>
    ''' Donne une différence d'angle entre 2 vecteurs 2D  0.093µs
    ''' </summary>
    ''' Valeur du Vector[01]


    ''' Valeur du Vector[02]

;d
    Function AngleBetween(ByVal a As Vector2, ByVal b As Vector2) As Single
        Dim dotProd As Double, lenProd As Double, divOperation As Double
        dotProd = (a.X * b.X) + (a.Y * b.Y)
        lenProd = Math.Sqrt(a.X * a.X + a.Y * a.Y) * Math.Sqrt(b.X * b.X + b.Y * b.Y)
        divOperation = dotProd / lenProd
        Dim Res As Single = Convert.ToSingle(Math.Acos(divOperation))
        If (b.Y - a.Y) < 0 Then Res = Pi2 - Res
        Return Res
    End Function

    ''' <summary>
    ''' Donne la distance entre 2 points 2D  0.170µs
    ''' </summary>
    ''' Position du point[01]


    ''' Position du point[02]


    ''' <remarks> Plus rapide : => Vector2.length 0.033µs =>Vector2.lengthFast 0.054µs) Soustraction de vector2 0.005µs
    ''' </remarks>
    Public Function DistanceBetweenTwoPoints(ByVal p1 As Vector2, ByVal p2 As Vector2) As Single
        Return Math.Sqrt((Math.Abs(p2.X - p1.X) ^ 2) + (Math.Abs(p2.Y - p1.Y) ^ 2))
    End Function


    ''' <summary>
    ''' Indique si un point se situe dans un triangle 0.046µs
    ''' </summary>
    ''' Point[00] du triangle


    ''' Point[01] du triangle


    ''' Point[02] du triangle


    ''' Position du point[02]


    Public Function IsPointInsideTriangle(ByRef P0 As Vector2, ByRef P1 As Vector2, ByRef P2 As Vector2, ByRef Pt_To_Test As Vector2) As Boolean
        Dim z1 As Boolean = ComputeZCoordinate(P0, P1, Pt_To_Test)
        Dim z2 As Boolean = ComputeZCoordinate(P1, P2, Pt_To_Test)
        Dim z3 As Boolean = ComputeZCoordinate(P2, P0, Pt_To_Test)
        Return (z1 And z2 And z3) Or (z1 False And z2 False And z3 = False)
    End Function
    Private Function ComputeZCoordinate(ByRef P1 As Vector2, ByRef P2 As Vector2, ByRef P3 As Vector2) As Boolean
        'Nécessaire a la fonction IsPointInsideTriangle
        Dim A As Single
        A = P1.X * (P2.Y - P3.Y) + P2.X * (P3.Y - P1.Y) + P3.X * (P1.Y - P2.Y)
        Return A > 0
    End Function

    ''' <summary>
    ''' Indique si un point se situe dans un polygone 
    ''' </summary>
    ''' Liste de points (enveloppe)


    ''' Point a tester


    Public Function InsidePolygon(ByRef Polygon As List(Of Vector2), ByRef P As Vector2) As Boolean
        'http://erich.realtimerendering.com/ptinpoly/
        'http://paulbourke.net/geometry/insidepoly/     
        Dim i As Integer, xinters As Double, counter As Integer = 0
        Dim p1 As Vector2, p2 As Vector2, n As Integer = Polygon.Count
        p1 = Polygon(0)
        For i = 1 To n
            p2 = Polygon(i Mod n)
            If P.Y > Min(p1.Y, p2.Y) Then
                If P.Y <= Max(p1.Y, p2.Y) Then
                    If P.X <= Max(p1.X, p2.X) Then
                        If p1.Y <> p2.Y Then
                            xinters = (P.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X
                            If p1.X = p2.X OrElse P.X <= xinters Then
                                counter += 1
                            End If
                        End If
                    End If
                End If
            End If
            p1 = p2
        Next
        Return (counter Mod 2 <> 0)
    End Function
0
Tarz974 Messages postés 10 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 7 août 2015
21 mars 2013 à 09:41
Super! J'avais un peu regardé de mon côté, mais je n'arrivais à rien.
Merci de ton aide!

Tarz.
0
Rejoignez-nous