boyington
Hält's aus hier
Beiträge: 2
|
Verfasst: Do 19.04.12 22:19
Hallo liebe Delphi Fans,
also ich bin Delphi-Anfänger und muss ein Delphiprogramm schreiben, das CAD-Dateien im STL-Format (Binär) öffnet und 3D-Modell von diesem Bauteil zeichnet, anschließend kann man mit Mouse-Click einen beliebigen Bereich direkt auf dem angezeigten 3D-Modell markieren (der Bereich muss auf der Oberfläche des Bauteils liegen).
Das Programm muss ich später als Entgratprogramm erweitern, nach der Markierung des zu entgratenden Bereiches vom Bauteil sagt das Entgratprogramm dem KUKA Industrieroboter, wo der genau am Bauteil entgraten soll. Natürlich das mache ich später.
Nun beschäfige ich mich nur mit ersten 3 kleinen Aufgaben:
1. STL-Datei (Binär) öffnen
2. mit Hilfe von Direct3D das 3D-Modell zeichnen und anzeigen.
3. den Bereich auf der Oberfläche des 3D-Modells markieren und dann die Koordinaten anzeigen.
1 und 2 habe ich schon gemacht, aber für 3, habe ich im Moment keine Idee, wie ich es realisieren soll, deshalb bitte ich euch um Hilfe
vielen Dank im Voraus!
Gruss
Lee Moderiert von Martok: Beiträge zusammengefasstWeiß nicht, ob es besser wäre, die Quelltexte von meinem Programm hier zu posten.
Inhalt von KRL_Gen.dpr
----------------------------------------
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| program KRL_Gen;
uses Forms, Main in '..\KRL_Gen_mit Schiebregler\Main.pas' , Visu in 'Visu.pas' ;
{$R *.RES}
begin Application.Initialize; Application.CreateForm(TfrmMain, frmMain); Application.CreateForm(TfrmVisu, frmVisu); Application.Run; end. |
Moderiert von Martok: Delphi-Tags hinzugefügt
Moderiert von Martok: Beiträge zusammengefasst
Inhalt von Main.pas
-----------------------------
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:
| unit Main;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, Visu, Math, ComCtrls;
type TVektor = record x, y, z: real; end; TDreieck = record n: TVektor; p: array[1..3] of TVektor; end; TfrmMain = class(TForm) mnuMain: TMainMenu; mnuDatei: TMenuItem; mnuLaden: TMenuItem; mnuBeenden: TMenuItem; TrackBar1: TTrackBar; TrackBar2: TTrackBar; procedure mnuBeendenClick(Sender: TObject); procedure mnuLadenClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure TrackBar1Change(Sender: TObject); private xBauteilMin, xBauteilMax, yBauteilMin, yBauteilMax, zBauteilMin, zBauteilMax: real; function STLLaden(Dateiname: TFileName; hList: TList): boolean; procedure Abmessungen(hList: TList); procedure Zentrieren(hList: TList); public Bauteilmittelpunkt: TVektor; lstDreiecke: TList; hMax: real; end;
var frmMain: TfrmMain;
implementation
{$R *.DFM}
procedure TfrmMain.mnuBeendenClick(Sender: TObject); begin Close; end;
procedure TfrmMain.mnuLadenClick(Sender: TObject); begin if STLLaden('3loch.stl', lstDreiecke) then MessageDlg('Fehler beim Einlesen.', mtError, [mbOK], 0) else begin Abmessungen(lstDreiecke); Zentrieren(lstDreiecke); frmVisu.Show; end; end;
function TfrmMain.STLLaden(Dateiname: TFileName; hList: TList): boolean; var AsciiDatei: System.Text; BinDatei : File; hStr : string; hDreieck : ^TDreieck; i, Zeile, hPos : integer; BinKopf : array[1..80] of char; BinAnz : dword; BinWerte : array[1..12] of single; BinFrei : array[1..2] of char; AnzBinRead: integer;
function NaechsterWert: real; var h: integer; begin h := pos(' ', hStr); while h = 1 do begin Delete(hStr, 1, 1); h := pos(' ', hStr); end; DecimalSeparator := '.'; if h > 0 then begin result := StrToFloat(Copy(hStr, 0, h-1)); hStr := Copy(hStr, h+1, Length(hStr)-h); end else result := StrToFloat(hStr); end;
begin result := false; if FileExists(Dateiname) then begin if false then begin AssignFile(AsciiDatei, Dateiname); Reset(AsciiDatei); if not(eof(AsciiDatei)) then begin Readln(AsciiDatei, hStr); if Copy(hStr, 0, 5) = 'solid' then begin Zeile := 1;
while not(eof(AsciiDatei)) and not(result) do begin Readln(AsciiDatei, hStr); if Pos('endsolid', hStr) = 0 then begin case Zeile of 1: begin hPos := Pos('facet normal', hStr); if hPos > 0 then begin New(hDreieck); hStr := Copy(hStr, hPos+13, length(hStr)-13-hPos+1); hDreieck^.n.x := NaechsterWert; hDreieck^.n.y := NaechsterWert; hDreieck^.n.z := NaechsterWert; inc(Zeile) end else result := true; end; 2: begin if Pos('outer loop', hStr) > 0 then inc(Zeile) else result := true; end; 3, 4, 5: begin hPos := Pos('vertex', hStr); if hPos > 0 then begin hStr := Copy(hStr, hPos+7, length(hStr)-7-hPos+1); hDreieck^.p[Zeile-2].x := NaechsterWert; hDreieck^.p[Zeile-2].y := NaechsterWert; hDreieck^.p[Zeile-2].z := NaechsterWert; inc(Zeile); end else result := true; end; 6: begin if Pos('endloop', hStr) > 0 then inc(Zeile) else result := true; end; 7: begin if Pos('endfacet', hStr) > 0 then begin hList.Add(HDreieck); Zeile := 1 end else result := true; end; end; end; end; end else result := true; end else result := true; CloseFile(AsciiDatei); end else begin AssignFile(BinDatei, Dateiname); Reset(BinDatei, 1); BlockRead(BinDatei, BinKopf, SizeOf(BinKopf), AnzBinRead); if AnzBinRead = SizeOf(BinKopf) then begin BlockRead(BinDatei, BinAnz, SizeOf(BinAnz), AnzBinRead); if AnzBinRead = SizeOf(BinAnz) then begin for i := 1 to BinAnz do begin BlockRead(BinDatei, BinWerte, SizeOf(BinWerte), AnzBinRead); if AnzBinRead = SizeOf(BinWerte) then begin BlockRead(BinDatei, BinFrei, SizeOf(BinFrei), AnzBinRead); if AnzBinRead = SizeOf(BinFrei) then begin New(hDreieck); hDreieck^.n.x := BinWerte[1]; hDreieck^.n.y := BinWerte[2]; hDreieck^.n.z := BinWerte[3]; hDreieck^.p[1].x := BinWerte[4]; hDreieck^.p[1].y := BinWerte[5]; hDreieck^.p[1].z := BinWerte[6]; hDreieck^.p[2].x := BinWerte[7]; hDreieck^.p[2].y := BinWerte[8]; hDreieck^.p[2].z := BinWerte[9]; hDreieck^.p[3].x := BinWerte[10]; hDreieck^.p[3].y := BinWerte[11]; hDreieck^.p[3].z := BinWerte[12]; hList.Add(hDreieck); end else result := true; end else result := true; end; end else result := true end else result := true; CloseFile(BinDatei); end;
end else result := true; end;
procedure TfrmMain.FormCreate(Sender: TObject); begin lstDreiecke := TList.Create; end;
procedure TfrmMain.FormDestroy(Sender: TObject); var hDreieck: ^TDreieck; i: integer; begin for i := 0 to lstDreiecke.Count-1 do begin hDreieck := lstDreiecke[i]; Dispose(hDreieck); end; lstDreiecke.Free; end;
procedure TfrmMain.Abmessungen(hList: TList); var i, j: integer; hDreieck: ^TDreieck; begin DecimalSeparator := '.'; xBauteilMin := 1e30; yBauteilMin := 1e30; zBauteilMin := 1e30; xBauteilMax := -1e30; yBauteilMax := -1e30; zBauteilMax := -1e30; for i := 0 to hList.Count-1 do begin hDreieck := hList[i]; for j := 1 to 3 do begin xBauteilMin := Min(xBauteilMin, hDreieck^.p[j].x); yBauteilMin := Min(yBauteilMin, hDreieck^.p[j].y); zBauteilMin := Min(zBauteilMin, hDreieck^.p[j].z); xBauteilMax := Max(xBauteilMax, hDreieck^.p[j].x); yBauteilMax := Max(yBauteilMax, hDreieck^.p[j].y); zBauteilMax := Max(zBauteilMax, hDreieck^.p[j].z); end; end; hMax := Max(xBauteilMax - xBauteilMin, yBauteilMax - yBauteilMin); hMax := Max(hMax, zBauteilMax - zBauteilMin); end;
procedure TfrmMain.Zentrieren(hList: TList); var i, j: integer; hDreieck: ^TDreieck; begin Bauteilmittelpunkt.x := (xBauteilMin + xBauteilMax) / 2; Bauteilmittelpunkt.y := (yBauteilMin + yBauteilMax) / 2; Bauteilmittelpunkt.z := (zBauteilMin + zBauteilMax) / 2; for i := 0 to hList.Count-1 do begin hDreieck := hList[i]; for j := 1 to 3 do begin hDreieck^.p[j].x := hDreieck^.p[j].x - Bauteilmittelpunkt.x; hDreieck^.p[j].y := hDreieck^.p[j].y - Bauteilmittelpunkt.y; hDreieck^.p[j].z := hDreieck^.p[j].z - Bauteilmittelpunkt.z; end; end; end;
procedure TfrmMain.TrackBar1Change(Sender: TObject); begin frmVisu.D3DRender; end;
end. |
Moderiert von Martok: Delphi-Tags hinzugefügt
Moderiert von Martok: Beiträge zusammengefasst
Inhalt von Visu.pas
-------------------------
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:
| unit Visu;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Direct3D8, d3dx8, ExtCtrls, ComCtrls, StdCtrls, KEditInt, Math;
const Fovy = Pi/50; type TMyVertex = packed record x, y, z, nx, ny, nz: single; color : dword; end;
const D3D8T_CUSTOMVERTEX : dword = D3DFVF_XYZ or D3DFVF_DIFFUSE or D3DFVF_NORMAL ;
type TfrmVisu = class(TForm) ppxVisu: TPaintBox; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormPaint(Sender: TObject); procedure FormDeactivate(Sender: TObject); procedure FormDestroy(Sender: TObject); private lpd3d : IDIRECT3D8; lpd3ddevice : IDirect3DDevice8; D3DDevCaps : TD3DCaps8; Licht: D3DLIGHT8; BauteilVB : IDirect3DVertexBuffer8; HwVertexProcess: boolean; Bauteil: array of TMyVertex; procedure FatalError(hr : HResult; FehlerMsg : string); procedure D3DInit; procedure D3DShutdown; procedure D3DInitScene; procedure D3DKillScene; public Eye: TD3DXVECTOR3; procedure D3DRender; end;
var frmVisu: TfrmVisu;
implementation
uses Main;
{$R *.DFM}
procedure TfrmVisu.FormCreate(Sender: TObject); begin lpd3d := nil; lpd3ddevice := nil; BauteilVB := nil; end;
procedure TfrmVisu.FatalError(hr : HResult; FehlerMsg : string); var s : string; begin if hr<>0 then s:=D3DXErrorString(hr)+#13+FehlerMsg else s:=FehlerMsg; D3DKillScene; D3DShutdown; MessageDlg(s,mtError,[mbOK],0); Close; end;
procedure TfrmVisu.D3DInit; var hr : HRESULT; d3dpp : TD3DPRESENTPARAMETERS; d3ddm : TD3DDISPLAYMODE; vp : integer; i, j, k: integer; hDreieck: ^TDreieck; begin SetLength(Bauteil, 3*(frmMain.lstDreiecke.Count)); k := 0; for i := 0 to frmMain.lstDreiecke.Count-1 do begin hDreieck := frmMain.lstDreiecke[i]; for j := 1 to 3 do begin Bauteil[k].x := hDreieck^.p[j].x; Bauteil[k].y := hDreieck^.p[j].y; Bauteil[k].z := -hDreieck^.p[j].z; Bauteil[k].nx := hDreieck^.n.x; Bauteil[k].ny := -hDreieck^.n.y; Bauteil[k].nz := -hDreieck^.n.z; Bauteil[k].color := $FFFFFF; inc(k); end; end;
lpd3d:=Direct3DCreate8(D3D_SDK_VERSION);
if(lpd3d=nil) then FatalError(0,'Fehler beim Erstellen von Direct3D!');
ZeroMemory(@d3dpp,sizeof(d3dpp)); with d3dpp do begin SwapEffect:=D3DSWAPEFFECT_DISCARD; hDeviceWindow := frmVisu.Handle; EnableAutoDepthStencil := TRUE; AutoDepthStencilFormat := D3DFMT_D16;
Windowed := true; hr:=lpd3d.GetAdapterDisplayMode(D3DADAPTER_DEFAULT,d3ddm); if failed(hr) then FatalError(hr,'Fehler beim Ermitteln des Dislaymodes'); BackBufferFormat := d3ddm.Format; end;
hr:=lpd3d.GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3dDevCaps); if FAILED(hr) then FatalError(hr,'Fehler beim Abfragen der DevCaps'); HwVertexProcess:=D3dDevCaps.DevCaps and D3DDEVCAPS_HWTRANSFORMANDLIGHT <> 0;
if HwVertexProcess then vp:=D3DCREATE_HARDWARE_VERTEXPROCESSING else vp:=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
hr:=lpd3d.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Handle, vp, d3dpp, lpd3ddevice); if FAILED(hr) then FatalError(hr,'Fehler beim Erzeugen des 3D-Device'); end;
procedure TfrmVisu.D3DShutdown; begin if assigned(lpd3ddevice) then lpd3ddevice:=nil; if assigned(lpd3d) then lpd3d:=nil; end;
procedure TfrmVisu.D3DInitScene; var hr : HRESULT; vbVertices : pByte; ProjMatrix : TD3DXMATRIX; Gr: Integer; EntfLicht : single; begin Gr := SizeOf(TMyVertex) * Length(Bauteil); if assigned(lpd3ddevice) then with lpd3ddevice do begin hr:=CreateVertexBuffer (Gr, D3DUSAGE_WRITEONLY, D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, BauteilVB); if FAILED(hr) then FatalError(hr,'Fehler beim Erstellen des Vertex-Buffers');
with BauteilVB do begin hr:=Lock(0,Gr,vbVertices,0); if FAILED(hr) then FatalError(hr,'Fehler beim Locken des Vertex-Buffers'); Move(Bauteil[0],vbVertices^,Gr); Unlock; end;
Eye.x := 0; Eye.y := 0; Eye.z := -frmMain.hMax/2/tan(Fovy/2); EntfLicht := 2*Eye.z;
Licht._Type := D3DLIGHT_DIRECTIONAL; Licht.Diffuse := D3DXCOLOR(1, 1, 1, 1); Licht.Position := D3DXVECTOR3(EntfLicht, 0, 0); Licht.Direction := D3DXVECTOR3(1, 1, 1); SetLight(0, Licht); LightEnable(0, true);
Licht.Position := D3DXVECTOR3(0, -EntfLicht, 0); Licht.Direction := D3DXVECTOR3(-1, -1, -1); SetLight(1, Licht); LightEnable(1, true);
SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
D3DXMatrixPerspectiveFovLH(ProjMatrix, Fovy, ppxVisu.Width/ppxVisu.Height, 1.0, SetTransform(D3DTS_PROJECTION, ProjMatrix); end; end;
procedure TfrmVisu.D3DKillScene; begin BauteilVB := nil; end;
procedure TfrmVisu.D3DRender; var ViewMatrix, RotMatrix, RotMatrixX, RotMatrixY, WorldMatrix: TD3DXMATRIX; At, Up: TD3DXVECTOR3; begin if assigned(lpd3ddevice) then with lpd3ddevice do begin Clear(0, nil, D3DCLEAR_TARGET or D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(200,0,100), 1, 0 );
if SUCCEEDED(BeginScene) then begin
At := D3DXVECTOR3(0, 0, -1); Up := D3DXVECTOR3(0, 1, 0); D3DXMatrixLookAtLH (ViewMatrix, Eye, At, Up); D3DXMatrixRotationX(RotMatrixX, frmMain.TrackBar1.Position/180*pi); D3DXMatrixRotationY(RotMatrixY, frmMain.TrackBar2.Position/180*pi); D3DXMatrixMultiply(RotMatrix, RotMatrixX, RotMatrixY);
D3DXMatrixMultiply(ViewMatrix, RotMatrix, ViewMatrix); D3DXMatrixIdentity(WorldMatrix); SetTransform(D3DTS_VIEW, ViewMatrix); SetTransform(D3DTS_WORLD, WorldMatrix); SetVertexShader(D3D8T_CUSTOMVERTEX);
SetStreamSource(0,BauteilVB,sizeof(TMyVertex)); DrawPrimitive(D3DPT_TRIANGLELIST, 0, frmMain.lstDreiecke.Count);
SetStreamSource(0, BauteilVB, SizeOf(TMyVertex)); SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
EndScene; end; Present(nil,nil,0,nil); end; end;
procedure TfrmVisu.FormShow(Sender: TObject); begin D3DInit; D3DInitScene; D3DRender; end;
procedure TfrmVisu.FormClose(Sender: TObject; var Action: TCloseAction); begin D3DKillScene; D3DShutdown; end;
procedure TfrmVisu.FormPaint(Sender: TObject); begin D3DRender; end;
procedure TfrmVisu.FormDeactivate(Sender: TObject); begin D3DRender; end;
procedure TfrmVisu.FormDestroy(Sender: TObject); begin Close; end;
end. |
Moderiert von Martok: Delphi-Tags hinzugefügt
|