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

Delphi Discussion :

conversion stl en obj


Sujet :

Delphi

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut conversion stl en obj
    bonjour
    comme FMX accepte que des modeles OBJ
    et moi j'ai des modeles en STL en format ASCII
    je voudrais faire la conversion en delphi
    viens de trouver un programme qui le fait mais en C
    quelqu'un pourrait me traduire a grande ligne le processus
    merci d'avance vous joint les liens
    STL to OBJ Geometry Converter
    https://github.com/baserinia/stl2obj

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 161
    Par défaut
    N'as-tu pas déjà posé la question fmx viewver 3d stl ?

    Que veux tu faire ?
    Juste compiler ce code C++11 pour produire l'exe utilisable en ligne de commande.
    Ou plutôt tout traduire en Delphi ?

    La seconde tache ne sera pas facile, car il y a l'import et export d'un format à l'autre mais finalement ce n'est pas le plus complexe, cela inclu des objets Arbre et Liste fait maison, tu vas passer un temps à les reproduire, surtout que tu n'as aucune référence sur le comportement.

    Peut-être déjà voir ce qui existe depuis longtemps GLScene comme TGLSTLVectorFile et TGLOBJVectorFile ou une version plus récente GLS.FileSTL et GLS.FileOBJ

    Bon inclure GLScene dans un projet FMX (ex-VGScene) c'est peut-être un peu redondant, donc mieux vaut faire une DLL ou Exe à part pour assurer la conversion.

    Enfin, c'est un besoin systématique, par l'utilisateur final ou c'est uniquement durant la phase de conception/réalisation
    Si c'est juste pour convertir quelques fichiers, une fois, Google donne des "STL to OBJ Converter Online" par dizaine.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonjour Shailetroll

    oui une conversion du C en delphi
    car je voudrais avec Tmodel3d faire un "loadfromfile"
    mais in n'accepte que 3 formats dont le OBJ

    autrement je vais m'orienter sur le Tmesh et récupérer
    seulement les lignes "vectex"
    mais je ne pense pas que sa suffiras
    merci encore pour tes liens peut être je trouverais
    une solution

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonsoir
    viens de faire une ébauche pour convertir
    fichier STL ascii en fichier OBJ
    programme pas optimalisé
    c'est seulement pour voir si c'était possible
    fichier zip joint
    par contre très gros fichier Jai des erreurs


    convertstl2.zip

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 161
    Par défaut
    Je ne connais pas ces formats STL et OBJ
    A la lecture du code, j'ai un peu l'impression que tu passes d'un truc genre vertex 1,2 3,4 5,6 en v 1.2 3.4 5.6, le DelimitedText c'est simple mais on doit effectivement aller plus vite.


    Sinon le Application.ProcessMessages, cela ne sert pas à grand chose, ça ralenti surtout, si tu ne fais pas défiler un progressbar ou un label, retire-le pour le moment.


    EDIT : Ma lecture du code semble bonne, Wikipedia confirme :

    Code stl : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    facet normal ni nj nk
       outer loop
         vertex v1x v1y v1z
         vertex v2x v2y v2z
         vertex v3x v3y v3z
       endloop
    endfacet

    Clairement tu peux fusionner loadnormal et loadvertex puisqu'il y a une structure imbriquée qu'il faut exploiter.

    Idem, le fichier OBJ ressemble clairement à ce que j'en déduis du code

    Code obj : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    v  -1.0  1.0  -1.0
     
    vt 0.25 0.0
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonjour
    merci Shailetroll
    tu as raison mais j'ai pas optimisé car je voulais savoir si on avait un résultat comme sa
    par contre je vous avez dit avoir un problème avec les gros fichier
    mais non seulement delphi a une erreur car le gros fichier généré marche avec autre
    logiciel comme Utimalker logiciel pour imprimante 3d
    par contre avec le tmodel3d je n'arrive pas a mettre une texture
    avec des mesh j'y arrive
    pourtant j'ai bien mis le composant materialtexture nommé "mattexture"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    form1.Model3D1.MeshCollection[0].MaterialSource:=form1.mattexture;

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 161
    Par défaut
    C'est pas la conversion qui pose problème
    C'est l'utilisation du fichier généré qui n'est pas correctement supporté par FMX ?
    Faudrait étudier le code FMX, voir si est plus "fragile" sur le formatage du fichier.
    Ne faisant jamais de FMX, cela dépasse mes compétences, autant la conversion de format de fichier texte->texte, c'est de la connaissance de base, cela reste juste de la manipulation de chaine, pour la 3D, là il te faut un connaisseur FMX.

    Après, comme le fichier STL est chargé, pourquoi ne pas faire un objet pour créer le Model3D manuellement ?

    Ai-je bien compris ?
    Comme vous écrivez en phonétique, c'est un peu difficile à comprendre.


    Je te laisse voir comment ça se manipule, tu as un objet structuré depuis l'OBJ, tout ce qu'il faut pour construire autre chose
    Soit reconstruire l'OBJ soit directement remplir le TModel3D
    Je repasserais peut-être sur le forum pour le code d'écriture de l'OBJ mais le TModel3D, ça c'est pour toi.

    Désactive le code du TTreeView pour un gros fichier, ça sera affreusement lent voire ça plantera si tu approches du millions de noeud

    Code : 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
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    unit STL2OBJConverter;
     
    interface
     
    uses
      System.Classes, System.SysUtils,
      System.Generics.Collections;
     
    type
      ESTL2OBJConverterError = class(Exception);
     
      TSTL2OBJConverter = class(TObject)
      public
        type
          TCoordType = (ctX, ctY, ctZ);
          TCoords = array[TCoordType] of Double;
     
          TVertex = class(TObject)
          private
            FRawData: string;
            FCoords: TCoords;
          public
            constructor Create(const ARawData: string);
     
            function ParseCoord(): Integer;
     
            property RawData: string read FRawData;
            property Coords: TCoords read FCoords;
          end;
          TVertices = class(System.Generics.Collections.TObjectList<TVertex>);
     
          TLoopType = (ltOuterLoop); // Inner Loop ???
          TLoop = class(TObject)
          private
            FLoopType: TLoopType;
            FVertices: TVertices;
          public
            constructor Create(ALoopType: TLoopType);
            destructor Destroy(); override;
     
            function AddVertex(const ARawData: string): TVertex;
     
            property LoopType: TLoopType read FLoopType;
            property Vertices: TVertices read FVertices;
          end;
          TLoops = class(System.Generics.Collections.TObjectList<TLoop>);
     
          TFacetType = (ftFacetNormal); // Anormal ???
          TFacet = class(TObject)
          private
            FFacetType: TFacetType;
            FRawData: string;
            FCoords: TCoords;
            FLoops: TLoops;
          public
            constructor Create(AFacetType: TFacetType; const ARawData: string);
            destructor Destroy(); override;
     
            function ParseCoord(): Integer;
            function AddLoop(ALoopType: TLoopType): TLoop;
     
            property FacetType: TFacetType read FFacetType;
            property RawData: string read FRawData;
            property Coords: TCoords read FCoords;
            property Loops: TLoops read FLoops;
          end;
          TFacets = class(System.Generics.Collections.TObjectList<TFacet>);
     
      private
        FName: string;
        FStrictLoading: Boolean;
        FFacets: TFacets;
     
        procedure LoadHeader(AFileContent: TStringList);
        procedure LoadFacets(AFileContent: TStringList; AStartIndex, AEndIndex: Integer);
        procedure LoadLoops(AFileContent: TStringList; var AStartIndex: Integer; const AEndIndex: Integer; AFacet: TFacet);
        procedure LoadVertices(AFileContent: TStringList; var AStartIndex: Integer; const AEndIndex: Integer; ALoop: TLoop);
     
        class function ParseCoord(const ARawData: string; out ACoords: TCoords): Integer;
     
      public
        constructor Create();
        destructor Destroy(); override;
     
        procedure LoadFromFile(const ASTLFileName: string);
        procedure LoadFromStream(const ASTLStream: TStream);
        procedure SaveToFile(const ASTLFileName: string);
     
        property Name: string read FName;
        property StrictLoading: Boolean read FStrictLoading write FStrictLoading;
        property Facets: TFacets read FFacets;
      end;
     
    implementation
     
    uses
      System.StrUtils;
     
    { TSTL2OBJConverter }
     
    //------------------------------------------------------------------------------
    constructor TSTL2OBJConverter.Create();
    begin
      inherited Create();
     
      FFacets := TFacets.Create(True);
    end;
     
    //------------------------------------------------------------------------------
    destructor TSTL2OBJConverter.Destroy();
    begin
      FreeAndNil(FFacets);
     
      inherited Destroy();
    end;
     
    (*
    solid name
    facet normal ni nj nk
       outer loop
         vertex v1x v1y v1z
         vertex v2x v2y v2z
         vertex v3x v3y v3z
       endloop
    endfacet
    endsolid name
    *)
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadFromStream(const ASTLStream: TStream);
    var
      StreamContent: TStringList;
    begin
      StreamContent := TStringList.Create();
      try
        StreamContent.LoadFromStream(ASTLStream);
        LoadHeader(StreamContent);
      finally
        StreamContent.Free();
      end;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadFromFile(const ASTLFileName: string);
    var
      FileContent: TStringList;
    begin
      FileContent := TStringList.Create();
      try
        FileContent.LoadFromFile(ASTLFileName);
        LoadHeader(FileContent);
      finally
        FileContent.Free();
      end;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadHeader(AFileContent: TStringList);
    const
      FILE_HEADER_PREFIX = 'solid ';
      FILE_HEADER_PREFIX_LEN = Length(FILE_HEADER_PREFIX);
      FILE_FOOTER_PREFIX = 'endsolid ';
      FILE_FOOTER_PREFIX_LEN = Length(FILE_FOOTER_PREFIX);
    var
      FirstLine, EndLine: string;
      LineCount: Integer;
    begin
      LineCount := AFileContent.Count;
      if LineCount >= 9 then
      begin
        FirstLine := AFileContent[0];
        if StartsStr(FILE_HEADER_PREFIX, FirstLine) then
        begin
          Dec(LineCount);
          EndLine := AFileContent[LineCount];
          if StartsStr(FILE_FOOTER_PREFIX, EndLine) then
          begin
            FName := Copy(FirstLine, FILE_HEADER_PREFIX_LEN);
            if FName <> Copy(EndLine, FILE_FOOTER_PREFIX_LEN) then
              raise ESTL2OBJConverterError.Create('Name in header and footer mismatch');
     
            LoadFacets(AFileContent, 1, LineCount - 1);
          end
          else
            raise ESTL2OBJConverterError.Create('Footer not found');
        end
        else
          raise ESTL2OBJConverterError.Create('Header not found');
      end
      else
        raise ESTL2OBJConverterError.Create('Content too small');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadFacets(AFileContent: TStringList; AStartIndex, AEndIndex: Integer);
    const
      FACET_NORMAL_PREFIX = 'facet normal ';
      FACET_NORMAL_PREFIX_LEN = Length(FACET_NORMAL_PREFIX);
    var
      I: Integer;
      Line: string;
      Facet: TFacet;
    begin
      FFacets.Clear();
     
      I := AStartIndex;
      while I <= AEndIndex do
      begin
        Line := AFileContent[I];
        if StartsStr(FACET_NORMAL_PREFIX, Line) then
        begin
          Facet := TFacet.Create(ftFacetNormal, Copy(Line, FACET_NORMAL_PREFIX_LEN));
          try
            FFacets.Add(Facet);
          except
            FreeAndNil(Facet);
            raise;
          end;
     
          if Facet.ParseCoord() < 3 then
            if FStrictLoading then
              raise ESTL2OBJConverterError.Create('Coord is expected');
     
          Inc(I);
     
          LoadLoops(AFileContent, I, AEndIndex, Facet);
        end
        else if FStrictLoading then
          raise ESTL2OBJConverterError.Create('Facet normal is expected')
        else
          Inc(I);
      end;
     
      if Facets.Count = 0 then
        raise ESTL2OBJConverterError.Create('Facet normal not found');
    end;
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadLoops(AFileContent: TStringList; var AStartIndex: Integer; const AEndIndex: Integer; AFacet: TFacet);
    const
      OUTER_LOOP_PREFIX = 'outer loop';
      ENDFACET_PREFIX = 'endfacet';
    var
      I: Integer;
      Line: string;
      Loop: TLoop;
    begin
      I := AStartIndex;
      while I <= AEndIndex do
      begin
        Line := TrimLeft(AFileContent[I]);
        if StartsStr(OUTER_LOOP_PREFIX, Line) then
        begin
          Loop := AFacet.AddLoop(ltOuterLoop);
     
          Inc(I);
          LoadVertices(AFileContent, I, AEndIndex, Loop);
        end
        else if StartsStr(ENDFACET_PREFIX, Line) then
        begin
          AStartIndex := I + 1;
          Exit;
        end
        else if FStrictLoading then
          raise ESTL2OBJConverterError.Create('Outer Loop is expected')
        else
          Inc(I);
      end;
     
      if AFacet.Loops.Count = 0 then
        raise ESTL2OBJConverterError.Create('Outer Loop not found')
      else
        AStartIndex := I;
    end;
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.LoadVertices(AFileContent: TStringList; var AStartIndex: Integer; const AEndIndex: Integer; ALoop: TLoop);
    const
      VERTEX_PREFIX = 'vertex ';
      VERTEX_PREFIX_LEN = Length(VERTEX_PREFIX);
      ENDLOOP_PREFIX = 'endloop';
    var
      I: Integer;
      Line: string;
      Vertex: TVertex;
    begin
      I := AStartIndex;
      while I <= AEndIndex do
      begin
        Line := TrimLeft(AFileContent[I]);
        if StartsStr(VERTEX_PREFIX, Line) then
        begin
          Vertex := ALoop.AddVertex(Copy(Line, VERTEX_PREFIX_LEN));
          if Vertex.ParseCoord() < 3 then
            if FStrictLoading then
              raise ESTL2OBJConverterError.Create('Coord is expected');
     
          Inc(I);
        end
        else if StartsStr(ENDLOOP_PREFIX, Line) then
        begin
          AStartIndex := I + 1;
          Exit;
        end
        else if FStrictLoading then
          raise ESTL2OBJConverterError.Create('Vertex is expected')
        else
          Inc(I);
      end;
     
      if ALoop.Vertices.Count = 0 then
        raise ESTL2OBJConverterError.Create('Vertex not found')
      else
        AStartIndex := I;
    end;
     
    //------------------------------------------------------------------------------
    class function TSTL2OBJConverter.ParseCoord(const ARawData: string; out ACoords: TCoords): Integer;
    var
      iXs, iXe, iYs, iYe, iZs: Integer;
      X, Y, Z: string;
      fsPoint, fsVirgule: TFormatSettings;
    begin
      Result := 0;
     
      fsPoint := TFormatSettings.Create();
      fsPoint.DecimalSeparator := '.';
     
      fsVirgule := TFormatSettings.Create();
      fsVirgule.DecimalSeparator := ',';
     
      iXs := 1;
      iXe := Pos(' ', ARawData);
      if iXe > 0 then
      begin
        X := Copy(ARawData, iXs, iXe - iXs);
        if TryStrToFloat(X, ACoords[ctX], fsPoint) or TryStrToFloat(X, ACoords[ctX], fsVirgule) then
          Inc(Result);
     
        iYs := iXe + 1;
        iYe := Pos(' ', ARawData, iYs);
        if iYe > 0 then
        begin
          Y := Copy(ARawData, iYs, iYe - iYs);
          if TryStrToFloat(Y, ACoords[ctY], fsPoint) or TryStrToFloat(Y, ACoords[ctY], fsVirgule) then
            Inc(Result);
     
          iZs := iYe + 1;
          Z := Copy(ARawData, iZs);
          if TryStrToFloat(Z, ACoords[ctZ], fsPoint) or TryStrToFloat(Z, ACoords[ctZ], fsVirgule) then
            Inc(Result);
        end;
      end;
    end;
     
     
    //------------------------------------------------------------------------------
    procedure TSTL2OBJConverter.SaveToFile(const ASTLFileName: string);
    begin
     
    end;
     
    { TSTL2OBJConverter.TFacet }
     
    //------------------------------------------------------------------------------
    constructor TSTL2OBJConverter.TFacet.Create(AFacetType: TFacetType; const ARawData: string);
    begin
      inherited Create();
     
      FFacetType := AFacetType;
      FRawData := TrimLeft(ARawData);
     
      FLoops := TLoops.Create(True);
    end;
     
    //------------------------------------------------------------------------------
    destructor TSTL2OBJConverter.TFacet.Destroy();
    begin
      FreeAndNil(FLoops);
     
      inherited Destroy();
    end;
     
    //------------------------------------------------------------------------------
    function TSTL2OBJConverter.TFacet.AddLoop(ALoopType: TLoopType): TLoop;
    begin
      Result := TLoop.Create(ALoopType);
      try
        FLoops.Add(Result);
      except
        FreeAndNil(Result);
        raise;
      end;
    end;
     
    //------------------------------------------------------------------------------
    function TSTL2OBJConverter.TFacet.ParseCoord(): Integer;
    begin
      Result := TSTL2OBJConverter.ParseCoord(FRawData, FCoords);
    end;
     
    { TSTL2OBJConverter.TLoop }
     
    //------------------------------------------------------------------------------
    constructor TSTL2OBJConverter.TLoop.Create(ALoopType: TLoopType);
    begin
      inherited Create();
     
      FLoopType := ALoopType;
     
      FVertices := TVertices.Create(True);
    end;
     
    //------------------------------------------------------------------------------
    destructor TSTL2OBJConverter.TLoop.Destroy();
    begin
      FreeAndNil(FVertices);
     
      inherited Destroy();
    end;
     
    //------------------------------------------------------------------------------
    function TSTL2OBJConverter.TLoop.AddVertex(const ARawData: string): TVertex;
    begin
      Result := TVertex.Create(ARawData);
      try
        FVertices.Add(Result);
      except
        FreeAndNil(Result);
        raise;
      end;
    end;
     
    { TSTL2OBJConverter.TVertex }
     
    //------------------------------------------------------------------------------
    constructor TSTL2OBJConverter.TVertex.Create(const ARawData: string);
    begin
      inherited Create();
     
      FRawData := TrimLeft(ARawData);
    end;
     
    //------------------------------------------------------------------------------
    function TSTL2OBJConverter.TVertex.ParseCoord(): Integer;
    begin
      Result := TSTL2OBJConverter.ParseCoord(FRawData, FCoords);
    end;
     
    end.
    Code : 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
    unit STL2OBJ_MainForm;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
      STL2OBJConverter, Vcl.ComCtrls;
     
    type
      TForm1 = class(TForm)
        MemoSTL: TMemo;
        pnlActions: TPanel;
        btnLoadSTL: TButton;
        pnlRawContents: TPanel;
        MemoOBJ: TMemo;
        SplitterRawContents: TSplitter;
        pnlContents: TPanel;
        tvSTL: TTreeView;
        SplitterContents: TSplitter;
        pnlStructuredContent: TPanel;
        procedure btnLoadSTLClick(Sender: TObject);
      private
        { Déclarations privées }
        FSTL2OBJConverter: TSTL2OBJConverter;
      public
        { Déclarations publiques }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy(); override;
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    constructor TForm1.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
     
      FSTL2OBJConverter := TSTL2OBJConverter.Create();
    end;
     
    destructor TForm1.Destroy;
    begin
      FreeAndNil(FSTL2OBJConverter);
     
      inherited Destroy();
    end;
     
     
    procedure TForm1.btnLoadSTLClick(Sender: TObject);
    const
      COORD_TEXTS: array[TSTL2OBJConverter.TCoordType] of string = ('X', 'Y', 'Z');
    var
      Stream: TMemoryStream;
      iFacet, iLoop, iVertex: Integer;
      iCoord: TSTL2OBJConverter.TCoordType;
      RootNode, FacetNode, LoopNode, VertexNode: TTreeNode;
      Facet: TSTL2OBJConverter.TFacet;
      Loop: TSTL2OBJConverter.TLoop;
      Vertex: TSTL2OBJConverter.TVertex;
    begin
      Stream := TMemoryStream.Create();
      try
        MemoSTL.Lines.SaveToStream(Stream);
        Stream.Seek(0, soBeginning);
     
        FSTL2OBJConverter.LoadFromStream(Stream);
     
        tvSTL.Items.Clear();
     
        tvSTL.Items.BeginUpdate();
        try
          RootNode := tvSTL.Items.AddFirst(nil, FSTL2OBJConverter.Name);
     
          for iFacet := 0 to FSTL2OBJConverter.Facets.Count - 1 do
          begin
            Facet := FSTL2OBJConverter.Facets[iFacet];
            FacetNode := tvSTL.Items.AddChild(RootNode, Facet.RawData);
     
            for iCoord := Low(Facet.Coords) to High(Facet.Coords) do
              tvSTL.Items.AddChild(FacetNode, Format('%s: %f', [COORD_TEXTS[iCoord], Facet.Coords[iCoord]]));
     
           for iLoop := 0 to Facet.Loops.Count - 1 do
            begin
              Loop := Facet.Loops[iLoop];
              LoopNode := tvSTL.Items.AddChild(FacetNode, Format('Loop N°%d', [iLoop]));
     
              for iVertex := 0 to Loop.Vertices.Count - 1 do
              begin
                Vertex := Loop.Vertices[iVertex];
                VertexNode := tvSTL.Items.AddChild(LoopNode, Vertex.RawData);
     
                for iCoord := Low(Vertex.Coords) to High(Vertex.Coords) do
                  tvSTL.Items.AddChild(VertexNode, Format('%s: %f', [COORD_TEXTS[iCoord], Vertex.Coords[iCoord]]));
              end;
            end;
          end;
        finally
          tvSTL.Items.EndUpdate();
        end;
      finally
        Stream.Free();
      end;
    end;
     
     
    end.
    Code dfm : 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
     
    object Form1: TForm1
      Left = 0
      Top = 0
      Caption = 'Form1'
      ClientHeight = 505
      ClientWidth = 965
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      PixelsPerInch = 96
      TextHeight = 13
      object pnlActions: TPanel
        Left = 872
        Top = 0
        Width = 93
        Height = 505
        Align = alRight
        Caption = 'pnlActions'
        ShowCaption = False
        TabOrder = 0
        object btnLoadSTL: TButton
          Left = 5
          Top = 2
          Width = 75
          Height = 25
          Caption = 'Load STL'
          TabOrder = 0
          OnClick = btnLoadSTLClick
        end
      end
      object pnlContents: TPanel
        Left = 0
        Top = 0
        Width = 872
        Height = 505
        Align = alClient
        Caption = 'pnlContents'
        ShowCaption = False
        TabOrder = 1
        ExplicitLeft = 1
        ExplicitTop = 164
        ExplicitWidth = 870
        ExplicitHeight = 340
        object SplitterContents: TSplitter
          Left = 545
          Top = 1
          Height = 503
          ExplicitLeft = 640
          ExplicitTop = 96
          ExplicitHeight = 100
        end
        object pnlRawContents: TPanel
          Left = 1
          Top = 1
          Width = 544
          Height = 503
          Align = alLeft
          Caption = 'pnlRawContents'
          ShowCaption = False
          TabOrder = 0
          object SplitterRawContents: TSplitter
            Left = 1
            Top = 161
            Width = 542
            Height = 3
            Cursor = crVSplit
            Align = alTop
            ExplicitWidth = 137
          end
          object MemoSTL: TMemo
            Left = 1
            Top = 1
            Width = 542
            Height = 160
            Align = alTop
            Lines.Strings = (
              'MemoSTL')
            TabOrder = 0
            ExplicitLeft = 3
            ExplicitTop = -2
            ExplicitWidth = 868
          end
          object MemoOBJ: TMemo
            Left = 1
            Top = 164
            Width = 542
            Height = 338
            Align = alClient
            Lines.Strings = (
              'MemoOBJ')
            TabOrder = 1
            ExplicitWidth = 870
            ExplicitHeight = 340
          end
        end
        object pnlStructuredContent: TPanel
          Left = 548
          Top = 1
          Width = 323
          Height = 503
          Align = alClient
          Caption = 'pnlStructuredContent'
          ShowCaption = False
          TabOrder = 1
          ExplicitLeft = 616
          ExplicitTop = 88
          ExplicitWidth = 185
          ExplicitHeight = 41
          object tvSTL: TTreeView
            Left = 1
            Top = 1
            Width = 321
            Height = 501
            Align = alClient
            Indent = 19
            TabOrder = 0
            ExplicitLeft = 2
            ExplicitTop = 0
          end
        end
      end
    end

    Voici l'affichage, j'ai géré le . et , car le wiki lui indique que . mais ton code indique , donc il y a surement une raison

    Nom : Sans titre.png
Affichages : 43
Taille : 36,0 Ko
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonjour Shailetroll
    viens essayer ton programme

    j'ai rajouté un bouton pour remplir premier Memo
    avec le fichier STL
    mais j'ai des erreurs
    déjà a sa
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if StartsStr(FILE_HEADER_PREFIX, FirstLine) then
    même si le mot clé est dans la phrase il ignore
    donc je les ais tous remplacés par des POS(
    mais je vois aussi que rien ne s'écrit dans les autres Memo
    car jamais sollicité
    ou alors j'ai du faire quelque chose de pas conforme
    merci en tout cas pour votre aide

  9. #9
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 161
    Par défaut
    Oui, je n'ai pas codé un lecture de fichier, faut l'écrire ou coller le contenu dans le Memo sinon tu peux ajouter un TEdit avec le nom du fichier et utiliser LoadFromFile au lieu de LoadFromStream, le Memo c'est juste pour la mise au point
    Non, j'ai pas fait la partie écriture de l'OBJ, juste le remplissage du TTreeView.

    StartsStr c'est une fonction de StrUtilsJe ne comprends pas votre problème, ça existe depuis D6 ou alors votre fichier STL contient des espaces que je n'ai pas géré, j'ai pris la structure du wiki et encore, semble que cela soit une version "pretty print" car semble que le fichier peut exister sans indentation sans retour-charriot, dans ce cas, faudrait repenser la méthode de lecture depuis une string ou un TStringStream.
    Donc remplacer par un pos n'est pas suffisant, il faut prendre en compte son retour pour les Copy qui suivent


    Si vous avez un fichier STL et son équivalent OBJ, fournissez-nous un ZIP, ça m'aidera à compléter pour l'OBJ
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonjour
    voila un fichier mais il n'est pas différent du tien

    pyra.zip

  11. #11
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 161
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 161
    Par défaut
    OK pour le STL et quel serait le fichier OBJ souhaité ?
    Pour voir l'objectif de conversion

    En parallèle, regarde si tu peux pas remplir le TModel3D à partir des objets Facets et Vertices, tu maitriseras encore mieux ton modèle 3D si tu comprends vraiment son fonctionnement.

    Citation Envoyé par tintin62 Voir le message
    voila un fichier mais il n'est pas différent du tien
    Pourtant, il est différent
    Il y a une indentation en plus au niveau du "facet normal", un simple TrimLeft en plus ... après tout, c'est comme tous les autres niveaux.
    TrimLeft oui, c'est par flemme, on peut le faire avec un Pos et gérer l'Offset dans le Copy.
    Nom : Sans titre.png
Affichages : 37
Taille : 47,4 Ko

    Par contre, je pense que c'est n'est pas le fichier d'origine, cela commence par solid TOTO, est-ce que le name est optionnel ?
    Ne connaissant pas le format, j'ai codé selon les infos du wiki, j'ai retiré l'obligation d'avoir un Name non vide.
    Dans le zip, cela supporte rien après le mot "solid" : STL2OBJ.Forum.zip


    Sinon, c'est un fichier minuscule, c'est quoi un gros fichier ?
    Envoie ton plus gros fichiers (sans le modifier, brut tel qu'il est d'origine)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 328
    Par défaut
    bonjour Shailetroll
    maintenant comment se servir des données
    avec Tmodel3d ou avec un Tmesh
    je commence avec FMX encore trop a apprendre
    donc je cherche sur tous
    mais pour moi je crois que je vais partir sur Tmesh
    merci pour tous si quelqu'un as des exemples pour remplir
    des Tmesh je suis preneur

  13. #13
    Membre Expert
    Avatar de ALWEBER
    Homme Profil pro
    Expert Delphi
    Inscrit en
    Mars 2006
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Expert Delphi

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 548
    Billets dans le blog
    10
    Par défaut
    Je vais faire un essai avec Claude.AI

Discussions similaires

  1. Transformer STL en *.obj
    Par Lost in dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 28/01/2010, 19h41
  2. conversion d'un pointeur de données vers un STL vector
    Par velkouby dans le forum SL & STL
    Réponses: 7
    Dernier message: 29/01/2008, 17h22
  3. STL/vector : conversion indice : "int" en iterateur
    Par sebkramm dans le forum SL & STL
    Réponses: 7
    Dernier message: 29/09/2007, 15h06
  4. parser IGES/STEP/STL/OBJ - COLLADA/RIB/POVRAY/X
    Par infernal1022 dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 15/06/2007, 11h12
  5. Réponses: 5
    Dernier message: 12/01/2005, 21h58

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