Wykorzystanie obiektów z 3dsMax i Solid Works w OpenGL
Oleksy_Adam
Wykorzystanie obiektów z 3dsMax i Solid Works w OpenGl
<justify> Jest to mój pierwszy artykuł na forum 4programmers i mam nadzieję, że nie ostatni. Będzie on dotyczył wykorzystania złożonych modeli 3d w aplikacji korzystającej z biblioteki OpenGl. Wiadomo, że ręczne modelowanie (mam tu na myśli składanie trójkątów) jest bardzo trudne i czasochłonne. Jeżeli chce się być wydajnym grafikiem ? programistą należy używać specjalnych programów przeznaczonych do modelowania obiektów przestrzennych. Większość programów ma możliwość zapisu projektu do pliku tekstowego. Różnice jednak w sposobie zapisu są tak duże, że nie ma możliwości pogodzenia owej metody. Jest jednak obejście tego problemu, a mianowicie pliki StereoLith (*.stl). Są one nazwijmy ?znormalizowane, tak więc nie ma znaczenia który program je wygenerował. Owe pliki mogą występować w postaci binarnej i tekstowej. Dalsze rozważania tyczyć się będą plików w postaci tekstu, tak więc należy podczas zapisu zaznaczyć opcję ASCII. W plikach stl obiekty są opisywane za pomocą płaszczyzn, trójkątów i wierzchołków. Oto przykładowy plik stl opisujący prostopadłościan (aby nie zaciemniać podaję tylko fragment): </justify> <font name="Courier New"> solid Part1 facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 0.000000e+000 5.000000e+001 vertex 0.000000e+000 7.402906e+001 5.000000e+001 vertex 0.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 0.000000e+000 0.000000e+000 vertex 0.000000e+000 7.402906e+001 5.000000e+001 vertex 0.000000e+000 7.402906e+001 0.000000e+000 endloop endfacet endsolid </span> <justify> Aby możliwe było wykorzystanie owego pliku w aplikacji delphi należy dokonać jego przekształcenia na właściwy format OpnGl?a czyli:</justify> ? Faced normal na glNormal3f() ? Vertex na glVertex3f() <justify> Zadanie nie jest trudne do zrealizowania. Poniżej zamieszczam kod programu do konwersji pliku *.stl na plik *.inc, którego efekt działania widać ponizej: </justify>glNormal3f( -1.000000e+000,0.000000e+000,0.000000e+000 );
glVertex3f( 0.000000e+000,0.000000e+000,5.000000e+001 );
glVertex3f( 0.000000e+000,7.402906e+001,5.000000e+001 );
glVertex3f( 0.000000e+000,0.000000e+000,0.000000e+000 );
glNormal3f( -1.000000e+000,0.000000e+000,0.000000e+000 );
glVertex3f( 0.000000e+000,0.000000e+000,0.000000e+000 );
glVertex3f( 0.000000e+000,7.402906e+001,5.000000e+001 );
glVertex3f( 0.000000e+000,7.402906e+001,0.000000e+000 );
Oto kod programu (dla czytelności napisany jako aplikacja konsolowa):
program Stl2Inc;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
IncFile, StlFile :TextFile;
IncLine, StlLine :string;
IncName, StlName :string;
i, n :Byte;
begin
if ParamCount = 0 then
begin
WriteLn('Złe argumenty');
WriteLn('STLCONV.EXE plik.stl');
WriteLn('Naciśnij Enter...');
ReadLn;
Halt(1);
end; // if ParamCount
StlName := ParamStr(1);
IncName := Copy(StlName, 1, (Length(StlName)-3))+'inc';
AssignFile(StlFile, StlName);
Reset(StlFile);
AssignFile(IncFile, IncName);
Rewrite(IncFile);
while not Eof(StlFile) do
begin
ReadLn(StlFile, StlLine);
n := 1;
while ((StlLine[n] <> 'v') and (n <= Length(StlLine)-2)) do Inc(n);
if StlLine[n] = 'v' then
begin
IncLine := Copy(StlLine, n+6, Length(StlLine)-n);
for i := 2 to Length(IncLine)-2 do
if IncLine[i] = ' ' then IncLine[i] := ',';
IncLine := ' glVertex3f(' + IncLine + ');';
WriteLn(IncFile, IncLine);
end; // if StlLine
n := 1;
while ((StlLine[n] <> 'n') and (n <= Length(StlLine)-2)) do Inc(n);
if Copy(StlLine, n, 6) = 'normal' then
begin
IncLine := Copy(StlLine, n+6, Length(StlLine)-n);
for i := 2 to Length(IncLine)-2 do
if IncLine[i] = '' then IncLine := ',';
IncLine := ' glNormal3f(' + IncLine + ');';
WriteLn(IncFile, IncLine);
end; // if Copy(...
end; //while not Eof
CloseFile(StlFile);
CloseFile(IncFile);
end.
Gdy już mamy przekształcony plik nie pozostaje nam nic innego jak umieścić go w kodzie procedury rysującej w klamrze:
glBegin(GL_TRIANGLES);
{$I PLIK.INC}
glEnd();
Oto cała metoda na uproszczenie sobie życia podczas pisania aplikacji w OpenGl. Ode mnie już wszystko. Mam nadzieję, że komuś się przyda. Jeżeli coś zostało przeoczone to przepraszam i proszę o dopisanie.
Ten kod "zapomina" wstawiać przecinki w linijkach glNormal3f... Zamiast:
if IncLine[i] = '' then IncLine := ',';
powinno być
if IncLine[i] = ' ' then IncLine[i] := ',';
Nie slyszalem o plikach .stl natomiast standardem wymiany informacji o obiektach 3D sa pliki .dxf opracowane przez AutoDesk.
@Oleksy_Adam: nie chodzi mi o wersję dla C. Edytory mają coś takiego jak eksport do pliku *.c - wygląda to tak, że masz tablice vertices, normals, texturecoord, itd. Np. Anim8or ma coś takiego, zassij to zobaczysz.
Wstępnie nawet nie pomyślałem o generowaniu obiektu do pliku *.c. Oczywiście, że popracuję nad wersją dla C.
a co z plikami Wavefront(*.obj)? albo .vtx albo generowaniem do pliku źródłowego (.c)