Hello! Help me please!
I have many TGLCylinder and TGLFreeForm. I need export all scene to .obj or .3ds or *.stl.
How can i do this?
Ps Maybe need combine all objects in one TGLFreeForm..
Sorry my english Tnank you in advance.
uses ..., GLFile3ds, GLVectorLists, GLFileSTL; ... procedure AddExportFile(FF:TGLFreeForm); var i:integer; dataFace:TSTLFace; list:TaffineVectorlist; begin //ExportList = TStringList FormatSettings.DecimalSeparator:='.'; list:=FF.MeshObjects.ExtractTriangles; if list.Count>0 then begin try i:=0; ExportList.Add('solid TestObj'); with dataFace do while i<list.Count do begin normal:=CalcPlaneNormal(list[i], list[i+1], list[i+2]); v1:=VectorTransform(list[i],TGLFREeform(FF).AbsoluteMatrix); v2:=VectorTransform(list[i+1],TGLFREeform(FF).AbsoluteMatrix); v3:=VectorTransform(list[i+2],TGLFREeform(FF).AbsoluteMatrix); ExportList.Add(format('facet normal %.6f %.6f %.6f',[normal.X,normal.Y,normal.Z])); ExportList.Add('outer loop'); ExportList.Add(format('vertex %.6f %.6f %.6f',[v1.X,v1.Y,v1.Z])); ExportList.Add(format('vertex %.6f %.6f %.6f',[v2.X,v2.Y,v2.Z])); ExportList.Add(format('vertex %.6f %.6f %.6f',[v3.X,v3.Y,v3.Z])); ExportList.Add('endloop'); ExportList.Add('endfacet'); Inc(i, 3); end; ExportList.Add('endsolid TestObj'); finally list.Free; end; end; FormatSettings.DecimalSeparator:=','; end;
Work for FreeForm. How can i do this for TGLCylinder?
Hi you must use FreeForm instead TGLCylinder. You can easly convert it. See MeshUtils.pas or something like that. See also this discussion https://sourceforge.net/p/glscene/discussion/93606/thread/889219fc/
Jerome Delauney, thank you! I will do as you advise.
Combine all GLFreeForm and export to one .Obj:
Bad code is below:
unit GLFileOBJ; //File GLFileOBJ.pas ... interface uses ... var My_VCount,My_FCount:integer; //<- Bad global variable ... procedure TGLOBJVectorFile.SaveToStream(aStream: TStream); var OldDecimalSeparator:char; tMy_VCount:integer; procedure Write(const s: AnsiString); begin if s <> '' then aStream.Write(s[1], Length(s)); end; procedure WriteLn(const s: string); begin Write(AnsiString(s)); Write(#13#10); end; procedure WriteHeader; begin WriteLn('# My OBJ-File exported by GLScene'); WriteLn(''); end; procedure WriteVertices; var s: string; j, i, n: integer; v:Tvector3f; begin n := 0; for j := 0 to Owner.MeshObjects.Count - 1 do begin //Writeln(Format('# Mesh %d', [j + 1])); with Owner.MeshObjects[j].Vertices do begin for i := 0 to Count - 1 do begin //Use absolute matrix v:=VectorTransform(List^[i],TGLFREeform(Owner).AbsoluteMatrix); s := Format('v %g %g %g', [v.V[0], v.V[1], v.V[2]]); Writeln(s); inc(tMy_VCount); end; Inc(n, Count); end; end; WriteLn(Format('# %d Vertices', [n])); WriteLn(''); end; procedure WriteNormals; var s: string; j, i, n: integer; begin n := 0; for j := 0 to Owner.MeshObjects.Count - 1 do begin with Owner.MeshObjects[j].Normals do begin for i := 0 to Count - 1 do begin s := Format('vn %g %g %g', [List^[i].V[0], List^[i].V[1], List^[i].V[2]]); Writeln(s); end; Inc(n, Count); end; end; WriteLn(Format('# %d Normals', [n])); WriteLn(''); end; procedure WriteTexCoords; var s: string; j, i, n: integer; begin n := 0; for j := 0 to Owner.MeshObjects.Count - 1 do begin with Owner.MeshObjects[j].TexCoords do begin for i := 0 to Count - 1 do begin s := Format('vt %g %g', [List^[i].V[0], List^[i].V[1]]); Writeln(s); end; Inc(n, Count); end; end; WriteLn(Format('# %d Texture-Coordinates', [n])); WriteLn(''); end; procedure WriteOBJFaceGroup(aFaceGroup: TOBJFGVertexNormalTexIndexList; o: Integer = 0); var vIdx, nIdx, tIdx: integer; i, Index, Polygon: integer; Line, t: string; begin with aFaceGroup do begin Index := 0; for Polygon := 0 to PolygonVertices.Count - 1 do begin Line := 'f '; for i := 1 to PolygonVertices[Polygon] do begin vIdx := VertexIndices[Index] + 1 + o; nIdx := NormalIndices[Index] + 1 + o; tIdx := TexCoordIndices[Index] + 1 + o; t := IntToStr(vIdx) + '/'; if tIdx = -1 then t := t + '/' else t := t + IntToStr(tIdx) + '/'; if nIdx = -1 then t := t + '/' else t := t + IntToStr(nIdx) + '/'; Line := Line + Copy(t, 1, length(t) - 1) + ' '; inc(Index); end; Writeln(Line); end; end; Writeln(''); end; procedure WriteVertexIndexList(fg: TFGVertexIndexList; o: Integer = 0); var i, n: Integer; begin case fg.Mode of fgmmTriangles: begin n := fg.VertexIndices.Count - 3; i := 0; while i <= n do begin Writeln(Format('f %d/%0:d %d/%1:d %d/%2:d', [fg.VertexIndices[i] + 1 + o, fg.VertexIndices[i + 1] + 1 + o, fg.VertexIndices[i + 2] + 1 + o])); Inc(i, 3); end; end; fgmmTriangleFan: begin Write('f '); n := fg.VertexIndices.Count - 1; i := 0; while i <= n do begin if i < n then Write(AnsiString(Format('%d/%0:d ', [fg.VertexIndices[i] + 1 + o]))) else Writeln(Format('%d/%0:d', [fg.VertexIndices[i] + 1 + o])); Inc(i); end; end; fgmmTriangleStrip: begin n := fg.VertexIndices.Count - 3; i := 0; while i <= n do begin Writeln(Format('f %d/%0:d %d/%1:d %d/%2:d', [fg.VertexIndices[i] + 1 + o, fg.VertexIndices[i + 1] + 1 + o, fg.VertexIndices[i + 2] + 1 + o])); Inc(i); end; end; end; end; procedure WriteFaceGroups; var j, i, k: Integer; fg: TGLFaceGroup; MoName: string; begin k := 0; for j := 0 to Owner.MeshObjects.Count - 1 do begin MoName := Owner.MeshObjects[j].Name; if MoName = '' then MoName := Format('Mesh%d', [j + 1+My_FCount]); Writeln('g ' + MoName); for i := 0 to Owner.MeshObjects[j].FaceGroups.Count - 1 do begin Writeln(Format('s %d', [i + 1])); fg := Owner.MeshObjects[j].FaceGroups[i]; if fg is TOBJFGVertexNormalTexIndexList then WriteOBJFaceGroup(TOBJFGVertexNormalTexIndexList(fg), k+My_VCount) else if fg is TFGVertexIndexList then WriteVertexIndexList(TFGVertexIndexList(fg), k+My_VCount) else Assert(False); //unsupported face group end; //advance vertex index offset Inc(k, Owner.MeshObjects[j].Vertices.Count); end; end; begin Assert(Owner is TGLFreeForm, 'Can only save FreeForms.'); OldDecimalSeparator := GetDecimalSeparator; SetDecimalSeparator('.'); { Better not call anything that wants the system-locale intact from this block } try tMy_VCount:=0; WriteHeader; WriteVertices; WriteNormals; WriteTexCoords; WriteFaceGroups; My_VCount:=My_VCount+tMy_VCount; inc(My_FCount); finally SetDecimalSeparator(OldDecimalSeparator); end; end; //Use bad code: procedure TForm1.PanelClick(Sender: TObject); var aStream:TStream; OVF:TGLOBJVectorFile; ExportList:TStringList; begin //Model_1, Model_2 = TGLFreeForm My_FCount:=0; My_VCount:=0; ExportList:=TStringList.Create; aStream:=TMemoryStream.Create; OVF:=TGLOBJVectorFile.Create(Model_1); OVF.SaveToStream(aStream); OVF:=TGLOBJVectorFile.Create(Model_2); OVF.SaveToStream(aStream); aStream.Position:=0; ExportList.LoadFromStream(aStream); ExportList.SaveToFile(extractfilepath(paramstr(0))+'TestExport.OBJ'); ExportList.Free; end;
Log in to post a comment.
Hello!
Help me please!
I have many TGLCylinder and TGLFreeForm.
I need export all scene to .obj or .3ds or *.stl.
How can i do this?
Ps
Maybe need combine all objects in one TGLFreeForm..
Sorry my english
Tnank you in advance.
Work for FreeForm.
How can i do this for TGLCylinder?
Last edit: Roman 2016-07-19
Hi you must use FreeForm instead TGLCylinder. You can easly convert it. See MeshUtils.pas or something like that. See also this discussion https://sourceforge.net/p/glscene/discussion/93606/thread/889219fc/
Jerome Delauney, thank you!
I will do as you advise.
Combine all GLFreeForm and export to one .Obj:
Bad code is below: