IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Presentation Foundation Discussion :

Graphismes 2D en WPF


Sujet :

Windows Presentation Foundation

  1. #1
    Membre expérimenté Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 958
    Points : 1 312
    Points
    1 312
    Par défaut Graphismes 2D en WPF
    Bonjour,

    j'ai conçu un logiciel de dessin CAO/ d'affichage de graphismes sous VB5, puis sous VB.NET.

    Mais GDI et GDI+ c'est lent, donc je souhaite essayer de créer une appli WPF avec Visual Basic 2010.

    Je viens d'y passer deux jours, et entre les DrawingContext, DrawingVisual, BitmapSource, CachedBitmap... je ne m'y retrouve pas Je n'arrive même pas à afficher une ligne dans mon contrôle image.

    Avez-vous un bon tutoriel là dessus ? J'ai trouvé pas mal de trucs en anglais et c'est assez opaque...

    Merci

  2. #2
    Membre expérimenté Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 958
    Points : 1 312
    Points
    1 312
    Par défaut
    Bonsoir,

    Finalement je suis arrivé à mes fins.

    J'ai fait 4 versions différentes du même un petit programme qui fait de l'affichage 3D maison, avec 4 versions de VB différentes, pour comparer les performances.

    Voici un aperçu du programme :



    Voici les résultats (temps moyen pour afficher la scène) :
    - VB.NET 2010 : 142ms
    - VB5 avec API Polygon : 197ms
    - VB5 : 311ms
    - WPF VB 2010 : 361ms - de plus l'application est lente à quitter

    Tous les codes sources et les exécutables sont téléchargeables ici : http://electroremy.free.fr/3D/3D2D_TEST.zip

    Je suis déçu de ce que j'ai obtenu avec WPF mais il est très probable que je n'utilise pas la bonne méthode avec ce langage.

    Comment faire pour avoir des fonctions graphiques rapides avec WPF ? Y compris lorsque mon code doit pouvoir continuer à agir sur les éléments dessinés (par exemple changer la couleur d'une ligne).

    Je me demande aussi si WPF est performant seulement quand c'est lui qui gère le dessin et pas au moment où on créé le dessin à partir du code; dans ce cas de figure, il serait intéressant d'utiliser WPF dans des applis où on charge un modèle et ensuite on le déplace à la souris, mais pas pour dessin type CAO ?

    A bientôt

  3. #3
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Tu utilises mal WPF (et peut-être les autres) et tu as une mauvaise perception de ce qu'est une carte graphique.

    Donc une carte graphique n'est pas un périphérique magique capable d'accélérer de petites opérations de rendu. Au contraire c'est une gros accélérateur situé très loin du CPU, entre lesquels il y a un bus avec une latence de plusieurs microsecondes, et ayant sa propre mémoire. On y stocke les primitives une fois pour toutes en essayant de ne jamais les lire ou les modifier, et on lui envoie aussi peu de commandes de rendu que possible ("batch, batch, batch" - on groupe les primitives ayant les mêmes shaders et textures en un seul gros maillage de milliers ou centaines de milliers de triangles).

    Pour ces raisons WPF est optimisé pour un mode "retained" (gestion d'une scène) : à chaque fois que tu crées une primitive de dessin celui-ci doit générer le maillage et le shader qui seront utilisés par la carte graphique puis tenter de batcher dynamiquement, de l'insérer son graphe de rendu, etc. Par ailleurs WPF expose des objets de haut-niveau capables de supporter des événements, de détecter des clics, etc.


    En résumé : on crée les primitives une seule fois, on ne les change que lorsqu'il le faut, on crée aussi peu de primitives que possibles, et on laisse WPF se débrouiller autant que possible.

    Cela dit ça ne doit pas être le seul problème pour obtenir 361ms de latence. TU n'aurais pas inclus un temps de démarrage ou fait autre chose de très lent ?

  4. #4
    Membre expérimenté Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 958
    Points : 1 312
    Points
    1 312
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Tu utilises mal WPF (et peut-être les autres) et tu as une mauvaise perception de ce qu'est une carte graphique.

    Donc une carte graphique n'est pas un périphérique magique capable d'accélérer de petites opérations de rendu. Au contraire c'est une gros accélérateur situé très loin du CPU, entre lesquels il y a un bus avec une latence de plusieurs microsecondes, et ayant sa propre mémoire. On y stocke les primitives une fois pour toutes en essayant de ne jamais les lire ou les modifier, et on lui envoie aussi peu de commandes de rendu que possible ("batch, batch, batch" - on groupe les primitives ayant les mêmes shaders et textures en un seul gros maillage de milliers ou centaines de milliers de triangles).

    Pour ces raisons WPF est optimisé pour un mode déféré : à chaque fois que tu crées une primitive de dessin celui-ci doit générer le maillage et le shader qui seront utilisés par la carte graphique puis tenter de batcher dynamiquement, de l'insérer son graphe de rendu, etc. Par ailleurs WPF expose des objets de haut-niveau capables de supporter des événements, de détecter des clics, etc.


    En résumé : on crée les primitives une seule fois, on ne les change que lorsqu'il le faut, on crée aussi peu de primitives que possibles, et on laisse WPF se débrouiller autant que possible.

    Cela dit ça ne doit pas être le seul problème pour obtenir 361ms de latence. TU n'aurais pas inclus un temps de démarrage ou fait autre chose de très lent ?
    C'est exactement ça Tu as parfaitement compris ce que je ne comprends pas

    Il faut que je coupe mon code en deux, une partie gérée par le CPU, et une par le GPU

    La difficulté est de minimiser les échanges de données entre les deux parties... il faut surtout éviter, pour chaque affichage, de récréer entièrement les données dans le GPU à partir du code géré par le CPU (c'est ce que je fais actuellement)

    Cela suppose, par exemple, de pouvoir modifier la couleur d'un élément dans le dessin stocké dans le GPU depuis le CPU, sans tout recréer. De même, pour faire des ajouts et suppressions d’éléments sans tout récréer.

    Est-il possible d'avoir cette approche aussi en VB5 ou en VB.NET ? ou est-ce réservé au WPF ?

    Par contre je ne sais pas du tout comment m'y prendre

    Avez-vous un bon tuto ou un bon livre à me conseiller à ce sujet ? Si possible en français ou sinon en anglais ?

    Merci, A+

  5. #5
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Citation Envoyé par electroremy Voir le message
    Il faut que je coupe mon code en deux, une partie gérée par le CPU, et une par le GPU
    Il faut que tu sépares la création des primitives (écriture des données géométriques en coordonnées monde) de leur rendu (projection, coloriage et dessin). Dans le cas de WPF tu n'as en fait pas à t'occuper du rendu, le Viewport3D le fera à ta place en fonction des couples géométrie / matériaux fournis.

    Cela suppose, par exemple, de pouvoir modifier la couleur d'un élément dans le dessin stocké dans le GPU depuis le CPU, sans tout recréer. De même, pour faire des ajouts et suppressions d’éléments sans tout récréer.
    Qu'appelles-tu un élément et quel genre de changement veux-tu faire ?
    S'il s'agit de modifier la couleur d'une seule face WPF devra renvoyer les données mais ce n'est pas grave. En revanche tu devras de ton côté seulement modifier une face en général, pas recréer tout un modèle.

    Est-il possible d'avoir cette approche aussi en VB5 ou en VB.NET ? ou est-ce réservé au WPF ?
    L'API GDI+ sur laquelle repose le dessin en WinForms et compagnie fonctionne uniquement en mode immédiat (on redessine tout à chaque fois).
    Mais tu peux toujours utiliser une API 3D ou mettre en cache certaines parties de l'image.

    Avez-vous un bon tuto ou un bon livre à me conseiller à ce sujet ? Si possible en français ou sinon en anglais ?
    Non mais cherche "WPF Viewport3D" et "ModelUIElement3D".
    Cela dit je ne vais pas pouvoir t'aider bien longtemps, je connais peu le rendu 3D en WPF.

  6. #6
    Membre expérimenté Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 958
    Points : 1 312
    Points
    1 312
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    Qu'appelles-tu un élément et quel genre de changement veux-tu faire ?
    S'il s'agit de modifier la couleur d'une seule face WPF devra renvoyer les données mais ce n'est pas grave. En revanche tu devras de ton côté seulement modifier une face en général, pas recréer tout un modèle.
    Dans ma structure de données, je vais avoir une liste de parcours d'outils, chaque parcours correspond :
    - à une ligne du programme CN à examiner
    - à quelque chose à afficher à l'écran

    Mon programme va permettre à l'utilisateur de choisir, suivant certains critères, les parcours à afficher ou pas, et avec des couleurs différentes selon que le parcours est un déplacement rapide hors de la pièce ou un déplacement dans la pièce qui usine, ou selon d'autres critères (numéro de l'outil utilisé, sens de la broche, ect...). Le but est que l'utilisateur puisse "explorer" visuellement le programme CN en distinguant certains catégories de parcours les unes des autres pour vérifier que le programme CN réalise bien les opérations demandées.

    Depuis l'interface utilisateur, l'utilisateur va pouvoir cliquer sur des cases à cocher qui vont avoir pour effet de cacher ou de montrer les parcours, et/ou de changer leur couleur.

    Je pense stoker dans le Viewport3D l'ensemble des parcours, calculés une bonne fois pour toute à la lecture du fichier CN, et ensuite depuis le code pouvoir changer les propriétés des parcours. Le Viewport3D gérera l'affichage, notamment quand l'utilisateur change l'angle de vue ou le zoom.

    J'espère que c'est suffisamment clair pour toi

    Citation Envoyé par DonQuiche Voir le message
    L'API GDI+ sur laquelle repose le dessin en WinForms et compagnie fonctionne uniquement en mode immédiat (on redessine tout à chaque fois).
    Mais tu peux toujours utiliser une API 3D ou mettre en cache certaines parties de l'image.
    OK - Donc pour VB5 ou .NET, passage par DirectX ou autre.

    Citation Envoyé par DonQuiche Voir le message
    Non mais cherche "WPF Viewport3D" et "ModelUIElement3D".
    OK merci, je vais voir de quoi ça parle

    Citation Envoyé par DonQuiche Voir le message
    Cela dit je ne vais pas pouvoir t'aider bien longtemps, je connais peu le rendu 3D en WPF.
    J'ai aussi des programmes qui ne font que de la 2D que je souhaiterais faire en WPF, pour cela, quoi me conseilles tu ?

    A+ et merci encore pour tes réponses

  7. #7
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 493
    Points
    5 493
    Par défaut
    Citation Envoyé par electroremy Voir le message
    Mon programme va permettre à l'utilisateur de choisir, suivant certains critères, les parcours à afficher ou pas, et avec des couleurs différentes selon que le parcours est un déplacement rapide hors de la pièce ou un déplacement dans la pièce qui usine, ou selon d'autres critères (numéro de l'outil utilisé, sens de la broche, ect...). Le but est que l'utilisateur puisse "explorer" visuellement le programme CN en distinguant certains catégories de parcours les unes des autres pour vérifier que le programme CN réalise bien les opérations demandées.

    Depuis l'interface utilisateur, l'utilisateur va pouvoir cliquer sur des cases à cocher qui vont avoir pour effet de cacher ou de montrer les parcours, et/ou de changer leur couleur.
    D'accord, donc la granularité des changements est le "parcours". Ca ne devrait être simple et ne pas poser de problème de perfs. Et même si WPF était un peu lent à faire certains changements (mes tests initiaux sur la v1 avaient été très décevants), tant que tu ne les fait que rarement...

    J'ai aussi des programmes qui ne font que de la 2D que je souhaiterais faire en WPF, pour cela, quoi me conseilles tu ?
    Même principe : on fonctionne en mode "retained" (gestion d'une scène) plutôt qu'immédiat (dessin à chaque frame façon GDI+).

    Ici ça passe par le Canvas (équivalent de Viewport3D) et par les descendants de Shape et Visual.

  8. #8
    Membre éprouvé Avatar de yonpo
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2010
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 617
    Points : 947
    Points
    947
    Par défaut
    Salut,

    J'avais fait des recherches sur la 3D en WPF il y a quelques années pour un projet qui n'a jamais abouti. J'ai retrouvé quelques liens sur des librairies (payantes et gratuites) et articles. Si ça peut t'aider :
    http://www.ab4d.com/best-3d-graphics...lications.aspx
    http://perspective.codeplex.com/
    https://github.com/helix-toolkit/helix-toolkit
    http://technodesign.solutions/docs/last10

  9. #9
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Points : 4 444
    Points
    4 444
    Par défaut
    Bonjour
    Comme dit par Don Quiche ,il faut separer le Dessin (primitives geometriques :volumes appellees Mesh c.à.d maillages geometriques ) de leur Rendu (shading ou coloriage appele Material en WPF,Transformations qui inclut deplacement,rotation ,mise à l'echelle )...C'est le dessin geometrique qu'il faut eviter de "regenerer" en WPF je veux parler du Mesh.

    En 3D en WPF ,les objets leightweights c.à.d "leger" sont representes par le class ModelVisual3D ,c'est l'equivalent du DrawingVisual en 2D....


    Le modele WPF 3D s'apparente au model 2D avec les equivalences 2D => 3D suivantes :
    1/ DrawingVisual => ModelVisual3D
    2/ Geometry(PathGeometry,EllipseGeometry etc...)=> MehGeomtry3D
    3/ HitTest => HitTest3D dans la couche visuelle par le biais du meme VisualTreeHelper ...
    4/ FrameworkElement Host des drawingvisual => control special dedie:Viewport3D
    4/ DrawingContext => pas d'equivalent...Le Viewport3D se charge du rendu (il genere lui l'aspect visual encapsule dans sa prop Viewport3DVisual ...c'est le imagebrush qu'il restitue )

    5/ Brush => Material ..
    Mais,mais ... Material et MeshGeometry sont regroupes ensembles dans la prop intermediaire GeometryModel du Model3DVisual......et place dans le viewport3d qui fait le rendu(pas de code à ecrire)....
    5/ Transformation 2D = Transformation 3D equivalente plus les rotations par axe(x,y,z) tres simple à utiliser...

    6/ DrawingGroup(accepte des VisualDrawing childs)=>Model3DGroup en l'equivalent ...Plusieurs GeometryModel avec leurs mesh et materials peuvent etre regoupe dans un Model3DGroup y compris leurs Lumieres et affectes à un seul ModelVisual3D dans sa prop Content.....tout en restant accessibles individualiment quant à leurs props de rendu (material,transform ,hittest)...

    7/ Camera et Lumiere n'ont aucun equivalent en 2D ...mais simplifie l'existence en evitant de calculer la proJection des objets 3D en 2D(projection camera)...

    Enfin le must du must et pour eviter de gerer le HitTest dans le code il existe une version bazooka du
    ModelVisual3D qui gere les evenements souris: ModelUIElement3D...qui dispose des fonctionnalites identiques au ModelVisual3D....On clique sur chaque modele separement et il reponds present dans mousedown...
    Seul hic ,ce modele n'est leger ,il ne faut en avoir trop dans l'application à cause des besoins memoires....

    Enfin ,non je n'ai pas fini ,les maillages en WPF n'existent pas et faut ajouter au class FactoryMesh qui suit une fonction qui cree le maillage 3D en simulant une ligne3D....

    code exemple 1
    Class factory cube:
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    Imports System.Windows.Media.Media3D
     
    Public Class FactoryMesh
        Private defaultTickness As Double = 0.01
        Public Sub New()
            Thickness = defaultTickness
        End Sub
        Public ReadOnly Property CubeMesh() As MeshGeometry3D
            Get
                Return CreateCube()
            End Get
        End Property
     
        Public Property Center() As Point3D
        Public ReadOnly Property CubeWire As MeshGeometry3D
            Get
                Return ToWireframe()
            End Get
        End Property
     
        Private thicknessValue As Double
        Public Property Thickness As Double
            Get
                Return thicknessValue
            End Get
            Set(ByVal value As Double)
                thicknessValue = value
                ToWireframe()
            End Set
        End Property
     
        'partie faces
        Private Function CreateCube() As MeshGeometry3D
     
            Dim cube As New MeshGeometry3D()
     
            Dim p0 As Point3D = New Point3D(0, 0, 0)
            Dim p1 As Point3D = New Point3D(1, 0, 0)
            Dim p2 As Point3D = New Point3D(1, 0, 1)
            Dim p3 As Point3D = New Point3D(0, 0, 1)
            Dim p4 As Point3D = New Point3D(0, 1, 0)
            Dim p5 As Point3D = New Point3D(1, 1, 0)
            Dim p6 As Point3D = New Point3D(1, 1, 1)
            Dim p7 As Point3D = New Point3D(0, 1, 1)
     
            'front side triangles
            CreeTriangle(cube, p3, p2, p6)
            CreeTriangle(cube, p3, p6, p7)
            'back side triangles
            CreeTriangle(cube, p1, p0, p4)
            CreeTriangle(cube, p1, p4, p5)
     
            'right side triangles
            CreeTriangle(cube, p2, p1, p5)
            CreeTriangle(cube, p2, p5, p6)
     
            'left side triangles
            CreeTriangle(cube, p0, p3, p7)
            CreeTriangle(cube, p0, p7, p4)
     
            'top side triangles
            CreeTriangle(cube, p7, p6, p5)
            CreeTriangle(cube, p7, p5, p4)
     
            'bottom side triangles
            CreeTriangle(cube, p2, p3, p0)
            CreeTriangle(cube, p2, p0, p1)
     
            For Each p As Point3D In cube.Positions
                Center += p
            Next
     
     
            Return cube
     
        End Function
     
        Private Sub CreeTriangle(ByVal m As MeshGeometry3D, ByVal p0 As Point3D, ByVal p1 As Point3D, ByVal p2 As Point3D)
            Dim index As Integer = m.Positions.Count
            m.Positions.Add(p0)
            m.Positions.Add(p1)
            m.Positions.Add(p2)
     
            m.TriangleIndices.Add(index)
     
            m.TriangleIndices.Add(index + 1)
            m.TriangleIndices.Add(index + 2)
            Dim normal As Vector3D = CalculateNormal(p0, p1, p2)
            m.Normals.Add(normal)
            m.Normals.Add(normal)
            m.Normals.Add(normal)
     
            m.TextureCoordinates.Add(New Point(0, 0))
            m.TextureCoordinates.Add(New Point(0, 1))
            m.TextureCoordinates.Add(New Point(1, 1))
            m.TextureCoordinates.Add(New Point(1, 1))
        End Sub
     
        Private Function CalculateNormal(ByVal p0 As Point3D, ByVal p1 As Point3D, ByVal p2 As Point3D) As Vector3D
            Dim v0 As Vector3D = New Vector3D(
                   p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z)
            Dim v1 As Vector3D = New Vector3D(
                    p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z)
            Return Vector3D.CrossProduct(v0, v1)
     
        End Function
     
        'partie maillage
        Public Function ToWireframe() As MeshGeometry3D
     
            If CubeMesh Is Nothing Then Return Nothing
     
            'Make a mesh to hold the wireframe.
            Dim wireframe As New MeshGeometry3D()
     
            'Loop through the mesh's triangles.
            For triangle As Integer = 0 To CubeMesh.TriangleIndices.Count - 1 Step 3
     
                'Get the triangle's corner indices.
                Dim index1 As Integer = CubeMesh.TriangleIndices(triangle)
                Dim index2 As Integer = CubeMesh.TriangleIndices(triangle + 1)
                Dim index3 As Integer = CubeMesh.TriangleIndices(triangle + 2)
     
                'Make the triangle's three segments.
                AddTriangleSegment(CubeMesh, wireframe, index1, index2, Thickness)
                AddTriangleSegment(CubeMesh, wireframe, index2, index3, Thickness)
                AddTriangleSegment(CubeMesh, wireframe, index3, index1, Thickness)
            Next
     
            Return wireframe
        End Function
     
        'Add the triangle's three segments.
        Private Sub AddTriangleSegment(ByVal OMesh As MeshGeometry3D,
          ByVal OWireframe As MeshGeometry3D,
             ByVal index1 As Integer, ByVal index2 As Double, ByVal thickness As Double)
     
            Dim up As Vector3D = New Vector3D(0, 1, 0)
            Dim segment As Vector3D = OMesh.Positions(index2) - OMesh.Positions(index1)
            segment.Normalize()
            If Math.Abs(Vector3D.DotProduct(up, segment)) > 0.9 Then
                up = New Vector3D(1, 0, 0)
            End If
     
     
            'Create the segment.
            AddSegment(OWireframe, OMesh.Positions(index1), OMesh.Positions(index2), up, thickness)
        End Sub
        Private Sub AddSegment(ByVal OWireframe As MeshGeometry3D,
              ByVal point1 As Point3D, ByVal point2 As Point3D,
              ByVal up As Vector3D, ByVal th As Double)
     
            'Get the segment's vector.
            Dim v As Vector3D = point2 - point1
     
            'Get the scaled up vector.
            Dim n1 As Vector3D = ScaleVector(up, th / 2.0)
     
            'Get another scaled perpendicular vector.
            Dim n2 As Vector3D = Vector3D.CrossProduct(v, n1)
            n2 = ScaleVector(n2, th / 2.0)
     
            'Make a skinny box.
            'p1pm means point1 PLUS n1 MINUS n2.
            Dim p1pp As Point3D = point1 + n1 + n2
            Dim p1mp As Point3D = point1 - n1 + n2
            Dim p1pm As Point3D = point1 + n1 - n2
            Dim p1mm As Point3D = point1 - n1 - n2
            Dim p2pp As Point3D = point2 + n1 + n2
            Dim p2mp As Point3D = point2 - n1 + n2
            Dim p2pm As Point3D = point2 + n1 - n2
            Dim p2mm As Point3D = point2 - n1 - n2
     
            'Sides.
            AddTriangle(OWireframe, p1pp, p1mp, p2mp)
            AddTriangle(OWireframe, p1pp, p2mp, p2pp)
     
            AddTriangle(OWireframe, p1pp, p2pp, p2pm)
            AddTriangle(OWireframe, p1pp, p2pm, p1pm)
     
            AddTriangle(OWireframe, p1pm, p2pm, p2mm)
            AddTriangle(OWireframe, p1pm, p2mm, p1mm)
     
            AddTriangle(OWireframe, p1mm, p2mm, p2mp)
            AddTriangle(OWireframe, p1mm, p2mp, p1mp)
     
            'Ends.
            AddTriangle(OWireframe, p1pp, p1pm, p1mm)
            AddTriangle(OWireframe, p1pp, p1mm, p1mp)
     
            AddTriangle(OWireframe, p2pp, p2mp, p2mm)
            AddTriangle(OWireframe, p2pp, p2mm, p2pm)
        End Sub
        Private Sub AddTriangle(ByVal OWireframe As MeshGeometry3D, ByVal point1 As Point3D, ByVal point2 As Point3D, ByVal point3 As Point3D)
            'Create the points.
            Dim index1 As Integer = OWireframe.Positions.Count
            OWireframe.Positions.Add(point1)
            OWireframe.Positions.Add(point2)
            OWireframe.Positions.Add(point3)
     
            'Create the triangle.
            OWireframe.TriangleIndices.Add(index1)
            index1 += 1
            OWireframe.TriangleIndices.Add(index1)
            index1 += 1
            OWireframe.TriangleIndices.Add(index1)
        End Sub
        'Set the vector's length.
        Private Function ScaleVector(ByVal vector As Vector3D, ByVal length As Double) As Vector3D
     
            Dim scale As Double = length / vector.Length
            Return New Vector3D(
                vector.X * scale,
                vector.Y * scale,
                vector.Z * scale)
        End Function
    End Class
    code du form utilisateur qui illustre le binding des transformations (et meme des materials via le brush):
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    <Window x:Class="WinVisual3DMode"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfObjetLeger3D" 
        Title="WinVisual3DMode" Height="350" Width="525">
        <Window.Resources>
            <local:FactoryMesh x:Key="f"></local:FactoryMesh>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="100"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal" >
                <ScrollBar 
                    Margin="10"
                    x:Name="scrollRotCube1"
                    Orientation="Vertical" 
                    Value="{Binding ElementName=rotCube1,Path=Angle}"
                    Maximum="360"
                    Minimum="0">
                </ScrollBar>
                <ScrollBar 
                    Margin="10"
                    x:Name="scrollScaleCube2"
                    Orientation="Vertical" 
                    Value="{Binding ElementName=scaleCube2,Path=ScaleY}"
                    Maximum="2.0"
                    Minimum="0.5">
     
                </ScrollBar>
            </StackPanel>
            <Viewport3D
                Grid.Row="1">
                <Viewport3D.Camera>
                    <PerspectiveCamera 
                        Position="5,5,5"
                        LookDirection="-5,-5,-5"
                        NearPlaneDistance="0"
                        FarPlaneDistance="20"
                        UpDirection="0,1,0"
                        FieldOfView="35">
     
                    </PerspectiveCamera>
                </Viewport3D.Camera>
                <Viewport3D.Children>
                    <!--'lumiere-->
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <DirectionalLight  Color="White"   Direction="-15,-12,-15">
                            </DirectionalLight>
                        </ModelVisual3D.Content>
     
                    </ModelVisual3D>
     
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <!--regroupoument de plusieurs maillages-->
                            <Model3DGroup>
                                <GeometryModel3D 
                                    Geometry="{Binding Source={StaticResource f},Path=CubeMesh}">
                                    <GeometryModel3D.Material>
                                        <DiffuseMaterial >
                                            <DiffuseMaterial.Brush>
                                                <SolidColorBrush Color="Blue"  Opacity="1.0"/>
                                            </DiffuseMaterial.Brush>
                                        </DiffuseMaterial>
                                    </GeometryModel3D.Material>
                                    <GeometryModel3D.Transform>
                                        <Transform3DGroup>
                                            <RotateTransform3D
                                                CenterX="0.5"
                                                CenterY="0.5"
                                                CenterZ="0.5">
                                                <RotateTransform3D.Rotation>
                                                    <AxisAngleRotation3D 
                                                        x:Name="rotCube1"
                                                        Axis="0,1,1" Angle="0"/>
                                                </RotateTransform3D.Rotation>
                                            </RotateTransform3D>
                                            <ScaleTransform3D 
                                                x:Name="transCube1"
                                                CenterX="0.5"
                                                CenterY="0.5"
                                                CenterZ="0.5"
                                                ScaleX="1" ScaleY="1" ScaleZ="1">
                                            </ScaleTransform3D>
                                        </Transform3DGroup>
     
                                    </GeometryModel3D.Transform>
                                </GeometryModel3D>
                                <GeometryModel3D 
                                    Geometry="{Binding Source={StaticResource f},Path=CubeMesh}">
                                    <GeometryModel3D.Material>
                                        <DiffuseMaterial >
                                            <DiffuseMaterial.Brush>
                                                <SolidColorBrush Color="Yellow"   Opacity="1.0"/>
                                            </DiffuseMaterial.Brush>
                                        </DiffuseMaterial>
                                    </GeometryModel3D.Material>
                                    <GeometryModel3D.Transform>
                                        <Transform3DGroup>
                                            <!--petite translation pour le voir--> 
                                            <TranslateTransform3D OffsetX="1" OffsetZ="-1.5"/>
                                            <ScaleTransform3D 
                                                x:Name="scaleCube2"
                                                CenterX="0.5"
                                                CenterY="0.5"
                                                CenterZ="0.5"
                                                ScaleX="1" ScaleY="1" ScaleZ="1"> 
                                            </ScaleTransform3D>
                                        </Transform3DGroup> 
                                    </GeometryModel3D.Transform>
                                </GeometryModel3D>
                            </Model3DGroup>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                </Viewport3D.Children>
            </Viewport3D>
        </Grid>
    </Window>

    Code du form pour le maillage d'un cube:
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    <Window x:Class="Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfObjetLeger3D"
        Title="Window1" Height="350" Width="525">
        <Window.Resources>
            <local:FactoryMesh x:Key="f"></local:FactoryMesh>
        </Window.Resources>
     
        <Grid>
            <Viewport3D>
                <Viewport3D.Camera>
                    <PerspectiveCamera 
                        Position="5,5,5"
                        LookDirection="-5,-5,-5"
                        NearPlaneDistance="0"
                        FarPlaneDistance="20"
                        UpDirection="0,1,0"
                        FieldOfView="35">
     
                    </PerspectiveCamera>
                </Viewport3D.Camera>
                <Viewport3D.Children>
                    <!--'lumiere-->
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <DirectionalLight  Color="White"   Direction="-15,-12,-15"/>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <GeometryModel3D
                                Geometry="{Binding Source={StaticResource f},Path=CubeMesh}">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Blue"></DiffuseMaterial>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <GeometryModel3D
                                Geometry="{Binding Source={StaticResource f},Path=CubeWire}">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Red"></DiffuseMaterial>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                </Viewport3D.Children>
            </Viewport3D>
        </Grid>
    </Window>
    code du class FactoryMesh qui genere une sphere (code du maillage identique à cube):
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    Imports System.Windows.Media.Media3D
     
    Public Class FactoryMesh2
        Private defaultTickness As Double = 0.01
        Private radius As Double = 2.0
        Private ttDiv As Integer = 8
        Private ppDiv As Integer = 10
     
        Public Sub New()
            Thickness = defaultTickness
            m_sphereMesh = CreateSphere(ttDiv, ppDiv, radius)
        End Sub
        Private m_sphereMesh As MeshGeometry3D
        Public ReadOnly Property SphereMesh() As MeshGeometry3D
            Get
                Return m_sphereMesh
            End Get
     
        End Property
        Public ReadOnly Property SphereWire As MeshGeometry3D
            Get
                Return ToWireframe()
            End Get
     
        End Property
        Private thicknessValue As Double
        Public Property Thickness As Double
            Get
                Return thicknessValue
            End Get
            Set(ByVal value As Double)
                thicknessValue = value
                ToWireframe()
            End Set
        End Property
     
        'partie faces
        Private Function CreateSphere(ByVal tDiv As Integer, ByVal pDiv As Integer, ByVal radius As Double) As MeshGeometry3D
            Dim dt As Double = DegToRad(360.0) / tDiv
            Dim dp As Double = DegToRad(180.0) / pDiv
            Dim mesh As New MeshGeometry3D()
            For pi As Integer = 0 To pDiv
                Dim phi As Double = pi * dp
                For ti As Integer = 0 To tDiv
     
                    Dim theta As Double = ti * dt
                    mesh.Positions.Add(GetPosition(theta, phi, radius))
                    mesh.Normals.Add(GetNormal(theta, phi))
                    mesh.TextureCoordinates.Add(GetTextureCoordinate(theta, phi))
     
                Next
     
            Next
     
            For pi As Integer = 0 To pDiv - 1
                For ti As Integer = 0 To tDiv - 1
                    Dim x0 As Integer = ti
                    Dim x1 As Integer = (ti + 1)
                    Dim y0 As Integer = pi * (tDiv + 1)
                    Dim y1 As Integer = (pi + 1) * (tDiv + 1)
     
                    mesh.TriangleIndices.Add(x0 + y0)
                    mesh.TriangleIndices.Add(x0 + y1)
                    mesh.TriangleIndices.Add(x1 + y0)
     
                    mesh.TriangleIndices.Add(x1 + y0)
                    mesh.TriangleIndices.Add(x0 + y1)
                    mesh.TriangleIndices.Add(x1 + y1)
                Next
            Next
     
            Return mesh
     
        End Function
        'Private helper methods
        Private Function GetPosition(ByVal theta As Double, ByVal phi As Double, ByVal radius As Double) As Point3D
     
            Dim x As Double = radius * Math.Sin(theta) * Math.Sin(phi)
            Dim y As Double = radius * Math.Cos(phi)
            Dim z As Double = radius * Math.Cos(theta) * Math.Sin(phi)
     
            Return New Point3D(x, y, z)
        End Function
     
        Private Function GetNormal(ByVal theta As Double, ByVal phi As Double) As Vector3D
            Return CType(GetPosition(theta, phi, 1.0), Vector3D)
        End Function
     
        Private Function DegToRad(ByVal degrees As Double) As Double
     
            Return (degrees / 180.0) * Math.PI
        End Function
     
        Private Function GetTextureCoordinate(ByVal theta As Double, ByVal phi As Double) As Point
     
            Dim p As Point = New Point(theta / (2 * Math.PI),
                                           phi / (Math.PI))
     
            Return p
        End Function
        'partie maillage
        Public Function ToWireframe() As MeshGeometry3D
     
            If SphereMesh Is Nothing Then Return Nothing
     
            'Make a mesh to hold the wireframe.
            Dim wireframe As New MeshGeometry3D()
     
            'Loop through the mesh's triangles.
            For triangle As Integer = 0 To SphereMesh.TriangleIndices.Count - 1 Step 3
     
                'Get the triangle's corner indices.
                Dim index1 As Integer = SphereMesh.TriangleIndices(triangle)
                Dim index2 As Integer = SphereMesh.TriangleIndices(triangle + 1)
                Dim index3 As Integer = SphereMesh.TriangleIndices(triangle + 2)
     
                'Make the triangle's three segments.
                AddTriangleSegment(SphereMesh, wireframe, index1, index2, Thickness)
                AddTriangleSegment(SphereMesh, wireframe, index2, index3, Thickness)
                AddTriangleSegment(SphereMesh, wireframe, index3, index1, Thickness)
            Next
     
            Return wireframe
        End Function
        'Add the triangle's three segments.
        Private Sub AddTriangleSegment(ByVal OMesh As MeshGeometry3D,
          ByVal OWireframe As MeshGeometry3D,
             ByVal index1 As Integer, ByVal index2 As Double, ByVal thickness As Double)
     
            Dim up As Vector3D = New Vector3D(0, 1, 0)
            Dim segment As Vector3D = OMesh.Positions(index2) - OMesh.Positions(index1)
            segment.Normalize()
            If Math.Abs(Vector3D.DotProduct(up, segment)) > 0.9 Then
                up = New Vector3D(1, 0, 0)
            End If
     
     
            'Create the segment.
            AddSegment(OWireframe, OMesh.Positions(index1), OMesh.Positions(index2), up, thickness)
        End Sub
        Private Sub AddSegment(ByVal OWireframe As MeshGeometry3D,
              ByVal point1 As Point3D, ByVal point2 As Point3D,
              ByVal up As Vector3D, ByVal th As Double)
     
            'Get the segment's vector.
            Dim v As Vector3D = point2 - point1
     
            'Get the scaled up vector.
            Dim n1 As Vector3D = ScaleVector(up, th / 2.0)
     
            'Get another scaled perpendicular vector.
            Dim n2 As Vector3D = Vector3D.CrossProduct(v, n1)
            n2 = ScaleVector(n2, th / 2.0)
     
            'Make a skinny box.
            'p1pm means point1 PLUS n1 MINUS n2.
            Dim p1pp As Point3D = point1 + n1 + n2
            Dim p1mp As Point3D = point1 - n1 + n2
            Dim p1pm As Point3D = point1 + n1 - n2
            Dim p1mm As Point3D = point1 - n1 - n2
            Dim p2pp As Point3D = point2 + n1 + n2
            Dim p2mp As Point3D = point2 - n1 + n2
            Dim p2pm As Point3D = point2 + n1 - n2
            Dim p2mm As Point3D = point2 - n1 - n2
     
            'Sides.
            AddTriangle(OWireframe, p1pp, p1mp, p2mp)
            AddTriangle(OWireframe, p1pp, p2mp, p2pp)
     
            AddTriangle(OWireframe, p1pp, p2pp, p2pm)
            AddTriangle(OWireframe, p1pp, p2pm, p1pm)
     
            AddTriangle(OWireframe, p1pm, p2pm, p2mm)
            AddTriangle(OWireframe, p1pm, p2mm, p1mm)
     
            AddTriangle(OWireframe, p1mm, p2mm, p2mp)
            AddTriangle(OWireframe, p1mm, p2mp, p1mp)
     
            'Ends.
            AddTriangle(OWireframe, p1pp, p1pm, p1mm)
            AddTriangle(OWireframe, p1pp, p1mm, p1mp)
     
            AddTriangle(OWireframe, p2pp, p2mp, p2mm)
            AddTriangle(OWireframe, p2pp, p2mm, p2pm)
        End Sub
        Private Sub AddTriangle(ByVal OWireframe As MeshGeometry3D, ByVal point1 As Point3D, ByVal point2 As Point3D, ByVal point3 As Point3D)
            'Create the points.
            Dim index1 As Integer = OWireframe.Positions.Count
            OWireframe.Positions.Add(point1)
            OWireframe.Positions.Add(point2)
            OWireframe.Positions.Add(point3)
     
            'Create the triangle.
            OWireframe.TriangleIndices.Add(index1)
            index1 += 1
            OWireframe.TriangleIndices.Add(index1)
            index1 += 1
            OWireframe.TriangleIndices.Add(index1)
        End Sub
        'Set the vector's length.
        Private Function ScaleVector(ByVal vector As Vector3D, ByVal length As Double) As Vector3D
     
            Dim scale As Double = length / vector.Length
            Return New Vector3D(
                vector.X * scale,
                vector.Y * scale,
                vector.Z * scale)
        End Function
    End Class
    et le code du form qui affiche la sphere avec maillage:
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    <Window x:Class="Window2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WpfObjetLeger3D" 
        Title="Window2" Height="350" Width="525">
        <Window.Resources>
            <local:FactoryMesh2  x:Key="f"/>
        </Window.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <CheckBox x:Name="chkWire" Content="ShowHideWire" Click="chkWire_Click"/>
            <Viewport3D 
                x:Name="vp"
                Grid.Row="1" >
                <Viewport3D.Camera>
                    <PerspectiveCamera 
                        Position="6,6,6" 
                        LookDirection="-4,-4,-4"
                        NearPlaneDistance="0"
                        FarPlaneDistance="20"
                        FieldOfView="45" />
                </Viewport3D.Camera>
                <Viewport3D.Children>
                    <ModelVisual3D >
                        <ModelVisual3D.Content>
                            <DirectionalLight Color="White" Direction="-12,-12,-15" />
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <GeometryModel3D
                                Geometry="{Binding Source={StaticResource f},Path=SphereMesh}">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Blue"></DiffuseMaterial>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                    <ModelVisual3D x:Name="wire">
                        <ModelVisual3D.Content>
                            <GeometryModel3D
                                Geometry="{Binding Source={StaticResource f},Path=SphereWire}">
                                <GeometryModel3D.Material>
                                    <DiffuseMaterial Brush="Red"></DiffuseMaterial>
                                </GeometryModel3D.Material>
                            </GeometryModel3D>
                        </ModelVisual3D.Content>
                    </ModelVisual3D>
                </Viewport3D.Children>
            </Viewport3D>
        </Grid>
    </Window>

    Un dernier conseil si tu veux modifier un point d'un meshgeometry 3D ne touche pas à un element de sa collection directement par acces direct à sa collection comme ceci:
    Code vb.net : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    'a proscrire
            For i = 0 To mesh.Positions.Count - 1
                mesh.Positions(i) = New Point3D(1.5, 2.3, 4.5)
            Next
            'recommende
            Dim mesNouvellesPositions As Point3DCollection = mesh.Positions
            For i = 0 To mesNouvellesPositions.Count - 1
                mesNouvellesPositions(i) = New Point3D(1.5, 2.3, 4.5)
            Next
            mesh.Positions = mesNouvellesPositions

    bon code...

  10. #10
    Membre expérimenté Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    958
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 958
    Points : 1 312
    Points
    1 312
    Par défaut
    Citation Envoyé par MABROUKI Voir le message
    Bonjour
    Comme dit par Don Quiche ,il faut separer le Dessin (primitives geometriques :volumes appellees Mesh c.à.d maillages geometriques ) de leur Rendu (shading ou coloriage appele Material en WPF,Transformations qui inclut deplacement,rotation ,mise à l'echelle )...C'est le dessin geometrique qu'il faut eviter de "regenerer" en WPF je veux parler du Mesh.

    En 3D en WPF ,les objets leightweights c.à.d "leger" sont representes par le class ModelVisual3D ,c'est l'equivalent du DrawingVisual en 2D....

    bon code...
    Alors je me suis plongé dans la doc WPF et ça m'a permit de mieux comprendre comment bien programmer la 3D

    Du coup ça m'a donné les bonnes clefs (et le bon vocabulaire) mathématique et je me suis replongé dans mon programme maison

    Je suis en train de concevoir une application qui affiche une collection d'objets faits de lignes (c'est cela qui correspond à mon besoin) et qui affiche simultanément, en écran partagé, la vue de face, la vue de droite, la vue de dessus et la vue en 3D perspective parallèle

    Je n'utilise pas WPF mais le .NET classique, mais maintenant je commence à maîtriser ce que je fais, au niveau algo et mathématiques :-)

    A+ et merci pour vos conseils

  11. #11
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Points : 4 444
    Points
    4 444
    Par défaut
    Re-bonjour

    1/Si tu veux tracer des lignes et avoir en plus la performance ,il faut utiliser DirectX managed(c'est du DirectX sous .Net :taper DirectX Managed August 2007 pour le lien MSDN ou SharDX ) accessible sous VbNet ...
    DirectX tout court est programmable en c++...
    En dx tu as les primivites lines,polygones ,triangles etc..Plus la camera,les lumieres ,un shading "foudrayant" et de plus la rapidite d'execution..

    2/Si tu veux comprendre le monde 3D ,ce tutorial de David Rousset est une bonne introduction pour comment bien concevoir ton appli(c'est en c# mais transposable en vb.net facilement)...
    Une connaissance minimale du calcul matriciel est un pre-requis (vecteur2d et vecteur3d,et plus generalement matrices 2D-3D ,les vecteurs etant par ailleurs eux memes des matrices )..Une connaissance des bases de la geometrie projective ou art de la perpective est necessaire...

    le lien en question :http://www.google.fr/url?url=http://...jg3ImK0yAcHYlA

    bon code....

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2020
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2020
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Bonjour MABROUKI ,

    J'ai copié l'intégralité de vos deux premiers codes un en vb.net l'autre en XAML.

    La classe FactoryMesh est dans un fichier Vb.net indépendant qui se nomme FactoryMesh.vb.

    Le code XAML est dans le XAML de la fenêtre WPF qui se nomme WinVisual3DMode.xaml, ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <Window x:Class="WinVisual3DMode"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Thouars_2"
            mc:Ignorable="d"
            Title="WinVisual3DMode" Height="450" Width="800">
        <Window.Resources>
            <local:FactoryMesh x:Key="f"></local:FactoryMesh>
        </Window.Resources>
    ...

    et j'obtiens une erreur qui me dit :
    Erreur XDG0008 Le nom "FactoryMesh" n'existe pas dans l'espace de noms "clr-namespace:Thouars_2".

    Thouars_2 étant mon projet et j'utilise Visual studio 2022.

    Sans compter les deux autres erreurs liées à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <GeometryModel3D  Geometry="{Binding Source={StaticResource f},Path=CubeMesh}">
    vu que f n'est pas défini.

    Auriez vous un début d'explication car je ne comprends pas ?

    Alain.

Discussions similaires

  1. [VB6] [Graphisme] Tracer un cercle avec pset
    Par bleuerouge dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 09/12/2002, 18h12
  2. [VB6] [Graphisme] Floodfill et motif
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 03/12/2002, 10h35
  3. [VB6] [Graphisme] Arc de cercle dans un picturebox
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 04/11/2002, 18h55
  4. [VB6] [Graphisme] Transfert d'image pixel par pixel
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 15/10/2002, 10h53
  5. [VB6][Graphisme] Zoom
    Par Troopers dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 10/10/2002, 18h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo