MathgeomGLS
295 строк · 7.4 Кб
1unit fIsoSurfaces;
2
3interface
4
5uses
6Winapi.OpenGL,
7Winapi.Windows,
8Winapi.Messages,
9System.SysUtils,
10System.Variants,
11System.Classes,
12Vcl.Graphics,
13Vcl.Controls,
14Vcl.ExtCtrls,
15Vcl.StdCtrls,
16Vcl.ComCtrls,
17Vcl.Buttons,
18Vcl.Forms,
19Vcl.Dialogs,
20
21GLS.SceneViewer,
22
23GLS.BaseClasses,
24GLS.Scene,
25GLS.Objects,
26GLS.Coordinates,
27GLS.Color,
28GLS.VectorGeometry,
29GLS.Mesh,
30GLS.VectorFileObjects,
31GLS.State,
32GLS.GeomObjects,
33GLS.Extrusion,
34GLS.VectorTypesExt,
35GLS.IsosurFace,
36GLS.SimpleNavigation,
37GLS.Material;
38
39type
40TForm1 = class(TForm)
41Scene: TGLScene;
42Viewer: TGLSceneViewer;
43Camera: TGLCamera;
44dcWorld: TGLDummyCube;
45Light: TGLLightSource;
46meshSurf: TGLMesh;
47SimpleNavigation: TGLSimpleNavigation;
48freeSurf: TGLFreeForm;
49PanelLeft: TPanel;
50rgSurface: TRadioGroup;
51Label2: TLabel;
52edIsoValue: TEdit;
53bbRunMC: TBitBtn;
54cbFillLines: TCheckBox;
55rgScalarField: TRadioGroup;
56rgFaceCulling: TRadioGroup;
57tbIsoValue: TTrackBar;
58procedure FormDestroy(Sender: TObject);
59procedure cbFillLinesClick(Sender: TObject);
60procedure FormCreate(Sender: TObject);
61procedure bbRunMCClick(Sender: TObject);
62procedure rgSurfaceClick(Sender: TObject);
63procedure rgScalarFieldClick(Sender: TObject);
64procedure rgFaceCullingClick(Sender: TObject);
65procedure tbIsoValueChange(Sender: TObject);
66private
67meshObj: TGLMeshObject;
68MC: TGLMarchingCube;
69end;
70
71(*
72// Sphere surface
73function SFSphere(X, Y, Z: Extended): TScalarValue;
74// Minkowski space (http://mathworld.wolfram.com)
75function SFMinkowski(X, Y, Z: Extended): TScalarValue;
76// Klein Bottle (http://mathworld.wolfram.com)
77function SFKleinBottle(X, Y, Z: Extended): TScalarValue;
78// Chmutov-surface-1 (http://mathworld.wolfram.com)
79function SFChmutov1(X, Y, Z: Extended): TScalarValue;
80// Chmutov-surface-2 (http://mathworld.wolfram.com)
81function SFChmutov2(X, Y, Z: Extended): TScalarValue;
82// Toroidal surface (phantasy!)
83function SFToroidal(X, Y, Z: Extended): TScalarValue;
84// Double torus Surface (phantasy!)
85function SFDoubleTorus(X, Y, Z: Extended): TScalarValue;
86*)
87const
88DemoScalarField: array [0 .. 6] of
89record
90// xMin, xMax, yMin, yMax, zMin, zMax:Single; // default -0.5..0.5
91ScalarField: TScalarField;
92IsoValue: TScalarValue
93end = ((ScalarField: SFSphere; IsoValue: 0.3),
94(ScalarField: SFMinkowski; IsoValue: 0.0),
95(ScalarField: SFKleinBottle; IsoValue: 0.0),
96(ScalarField: SFChmutov1; IsoValue: 3.0),
97(ScalarField: SFChmutov2; IsoValue: 3.0),
98(ScalarField: SFToroidal; IsoValue: 3.0),
99(ScalarField: SFDoubleTorus; IsoValue: 0.015));
100
101var
102Form1: TForm1;
103
104//===========================================
105implementation
106//===========================================
107
108{$R *.dfm}
109
110(*
111// Test surface functions
112function SFSphere(X, Y, Z: Extended): TScalarValue;
113begin
114Result := sqr(X) + sqr(Y) + sqr(Z)
115end;
116
117function SFToroidal(X, Y, Z: Extended): TScalarValue;
118const
119FScale = 7;
120a = 2.5;
121begin
122X := FScale * X;
123Y := FScale * Y;
124Z := FScale * Z;
125Result := (sqr(sqrt(sqr(X) + sqr(Y)) - a) + sqr(Z)) *
126(sqr(sqrt(sqr(Y) + sqr(Z)) - a) + sqr(X)) *
127(sqr(sqrt(sqr(Z) + sqr(X)) - a) + sqr(Y));
128end;
129
130function SFDoubleTorus(X, Y, Z: Extended): TScalarValue;
131const
132FScale = 2.25;
133begin
134X := FScale * X;
135Y := FScale * Y;
136Z := FScale * Z;
137Result := PowerInteger(X, 8) + PowerInteger(X, 4) - 2 * PowerInteger(X, 6) - 2
138* sqr(X) * sqr(Y) + 2 * PowerInteger(X, 4) * sqr(Y) +
139PowerInteger(Y, 4) + sqr(Z)
140end;
141
142function SFChmutov1(X, Y, Z: Extended): TScalarValue;
143const
144FScale = 2.5;
145begin
146X := FScale * X;
147Y := FScale * Y;
148Z := FScale * Z;
149Result := 8 * (sqr(X) + sqr(Y) + sqr(Z)) - 8 *
150(PowerInteger(X, 4) + PowerInteger(Y, 4) + PowerInteger(Z, 4));
151end;
152
153function SFChmutov2(X, Y, Z: Extended): TScalarValue;
154const
155FScale = 2.5;
156begin
157X := FScale * X;
158Y := FScale * Y;
159Z := FScale * Z;
160Result := 2 * (sqr(X) * sqr(3 - 4 * sqr(X)) + sqr(Y) * sqr(3 - 4 * sqr(Y)) +
161sqr(Z) * sqr(3 - 4 * sqr(Z)));
162end;
163
164function SFKleinBottle(X, Y, Z: Extended): TScalarValue;
165const
166FScale = 7.5;
167begin
168X := FScale * X;
169Y := FScale * Y;
170Z := FScale * Z;
171Result := (sqr(X) + sqr(Y) + sqr(Z) + 2 * Y - 1) *
172(sqr(sqr(X) + sqr(Y) + sqr(Z) - 2 * Y - 1) - 8 * sqr(Z)) + 16 * X * Z *
173(sqr(X) + sqr(Y) + sqr(Z) - 2 * Y - 1);
174end;
175
176function SFMinkowski(X, Y, Z: Extended): TScalarValue;
177const
178FScale = 7;
179begin
180X := FScale * X;
181Y := FScale * Y;
182Z := FScale * Z;
183Result := (sqr(X) - sqr(Y) - sqr(Z) - 2) * (sqr(X) - sqr(Y) - sqr(Z) + 2) *
184(sqr(X) - sqr(Y) - sqr(Z) - 4) * (sqr(X) - sqr(Y) - sqr(Z) + 4) *
185(sqr(X) - sqr(Y) - sqr(Z));
186end;
187
188*)
189
190//----------------------------------------------------
191
192procedure TForm1.FormCreate(Sender: TObject);
193begin
194MC := TGLMarchingCube.Create(100, 100, 100);
195
196meshObj := TGLMeshObject.CreateOwned(freeSurf.MeshObjects);
197meshObj.Mode := momFaceGroups;
198
199Light.Position.SetPoint(100, 200, 300);
200Light.Ambient.SetColor(0.6, 0.6, 0.0, 0.1);
201Light.Diffuse.SetColor(0.2, 0.4, 1.0, 0.1);
202Light.Specular.SetColor(1.0, 1.0, 1.0, 0.1);
203
204if rgSurface.ItemIndex = 0 then // using GLFreeForm
205meshSurf.Visible := False
206else // using GLMesh
207freeSurf.Visible := False;
208
209cbFillLinesClick(Self);
210bbRunMCClick(Self)
211end;
212
213procedure TForm1.FormDestroy(Sender: TObject);
214begin
215MC.Free;
216meshObj.Free;
217end;
218
219procedure TForm1.cbFillLinesClick(Sender: TObject);
220begin
221if rgSurface.ItemIndex = 0 then // using TGLFreeForm
222begin
223if cbFillLines.Checked then
224freeSurf.Material.PolygonMode := pmFill
225else
226freeSurf.Material.PolygonMode := pmLines
227end
228else // using TGLMesh
229begin
230if cbFillLines.Checked then
231meshSurf.Material.PolygonMode := pmFill
232else
233meshSurf.Material.PolygonMode := pmLines
234end;
235end;
236
237procedure TForm1.rgScalarFieldClick(Sender: TObject);
238begin
239edIsoValue.Text := FloatToStr(DemoScalarField[rgScalarField.ItemIndex].IsoValue);
240bbRunMCClick(Self)
241end;
242
243procedure TForm1.rgFaceCullingClick(Sender: TObject);
244begin
245if rgSurface.ItemIndex = 0 then
246freeSurf.Material.FaceCulling := TGLFaceCulling(rgFaceCulling.ItemIndex)
247else
248meshSurf.Material.FaceCulling := TGLFaceCulling(rgFaceCulling.ItemIndex);
249end;
250
251procedure TForm1.bbRunMCClick(Sender: TObject);
252var
253IsoValue: TScalarValue;
254begin
255// try to accept user value, but if uncorrect assign a correct demo value
256IsoValue := StrToFloatDef(edIsoValue.Text, DemoScalarField[rgScalarField.ItemIndex].IsoValue);
257edIsoValue.Text := FormatFloat('0.0000', IsoValue);
258
259MC.FillVoxelData(IsoValue, DemoScalarField[rgScalarField.ItemIndex].ScalarField);
260MC.Run;
261
262if rgSurface.ItemIndex = 0 then // using GLFreeForm
263begin
264meshObj.Free;
265meshObj := TGLMeshObject.CreateOwned(freeSurf.MeshObjects);
266meshObj.Mode := momFaceGroups;
267MC.CalcMeshObject(meshObj, 0.6);
268end
269else // using GLMesh
270MC.CalcVertices(meshSurf.Vertices);
271Viewer.Invalidate;
272end;
273
274procedure TForm1.rgSurfaceClick(Sender: TObject);
275begin
276if rgSurface.ItemIndex = 0 then // using GLFreeForm
277begin
278meshSurf.Visible := False;
279freeSurf.Visible := True;
280end
281else // using GLMesh
282begin
283freeSurf.Visible := False;
284meshSurf.Visible := True;
285end;
286cbFillLinesClick(Self);
287rgScalarFieldClick(Self);
288end;
289
290procedure TForm1.tbIsoValueChange(Sender: TObject);
291begin
292edIsoValue.Text := FloatToStr(tbIsoValue.Position/10);
293end;
294
295end.
296