forked from pglowack/MoleculeHero
-
Notifications
You must be signed in to change notification settings - Fork 1
/
MolHero.DMMain.pas
executable file
·156 lines (121 loc) · 4.05 KB
/
MolHero.DMMain.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
unit MolHero.DMMain;
interface
uses
System.SysUtils, System.Classes, FMX.Controls3D,
MolHero.MoleculeModel, MolHero.Materials;
type
TDMMain = class(TDataModule)
private
FMolecule: TMolecule;
FAtomMaterials: TAtomMaterials;
procedure LoadMolecule(const ctr: TControl3D; const mol: TMolecule; const mats: TAtomMaterials);
function AtomicNrToScale(nr: byte): double;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetMoleculeCount: integer;
function GetMoleculeDisplayName(i: integer): string;
procedure GetMoleculeByIndex(const index: integer; const AMolecule: TMolecule);
procedure LoadMoleculeToCtrl3D(const ctrl: TControl3D; const m: TMolecule);
procedure LoadMoleculeByIndex(const ctrl: TControl3D; const index: integer);
property CurrentMolecule: TMolecule read FMolecule;
end;
var
DMMain: TDMMain;
implementation
{%CLASSGROUP 'FMX.Controls.TControl'}
uses System.Types, System.Math, System.Math.Vectors, FMX.Objects3D,
MolHero.ImportPDB, MolHero.FormRes;
{$R *.dfm}
{ TDMMain }
function TDMMain.AtomicNrToScale(nr: byte): double;
begin
Result := 1; // to be implemented
end;
constructor TDMMain.Create(AOwner: TComponent);
begin
inherited;
FAtomMaterials := TAtomMaterials.Create;
if FormRes = nil then
FormRes := TFormRes.Create(AOwner);
end;
destructor TDMMain.Destroy;
begin
FMolecule.Free;
FAtomMaterials.Free;
inherited;
end;
function TDMMain.GetMoleculeDisplayName(i: integer): string;
begin
Result := FormRes.GetMoleculeName(i);
end;
procedure TDMMain.GetMoleculeByIndex(const index: integer;
const AMolecule: TMolecule);
var pdb: TStringDynArray;
begin
pdb := FormRes.GetMoleculePDB(index);
try
GetMoleculeFromStrings(pdb, aMolecule);
aMolecule.DisplayName := FormRes.GetMoleculeName(index);
finally
Finalize(pdb);
end;
end;
function TDMMain.GetMoleculeCount: integer;
begin
Result := FormRes.GetMoleculeCount;
end;
procedure TDMMain.LoadMoleculeToCtrl3D(const ctrl: TControl3D; const m: TMolecule);
begin
LoadMolecule(ctrl, m, FAtomMaterials);
end;
procedure TDMMain.LoadMolecule(const ctr: TControl3D;
const Mol: TMolecule; const mats: TAtomMaterials);
var i: integer; sph: TSphere; atom: TAtomData; scale: double;
bond: TBondData; pStart, pEnd, pMid: TPoint3D; cyl: TCylinder;
begin
ctr.DeleteChildren;
for i := 0 to Mol.Atoms.Count-1 do
begin
atom := Mol.Atoms[i];
sph := TSphere.Create(ctr);
sph.MaterialSource := mats.GetAtomMaterial(atom.AtomKind);
scale := AtomicNrToScale(atom.AtomKind);
sph.Scale.X := scale;
sph.Scale.Y := scale;
sph.Scale.Z := scale;
sph.Position.X := atom.Pos.X;
sph.Position.Y := atom.Pos.Y;
sph.Position.Z := atom.Pos.Z;
sph.TagString := 'Atom ' + i.ToString + ' [' + sph.Position.ToString + ']';
ctr.AddObject(sph);
end;
for i := 0 to Mol.Bonds.Count-1 do
begin
bond := Mol.Bonds[i];
pStart := mol.Atoms[bond.IdStart].Pos;
pEnd := mol.Atoms[bond.IdEnd].Pos;
pMid := Point3D((pStart.X+pEnd.X)/2,(pStart.Y+pEnd.Y)/2,(pStart.Z+pEnd.Z)/2);
cyl := TCylinder.Create(ctr);
cyl.Position.Point := pMid;
cyl.Height := pStart.Distance(pEnd);
cyl.Width := 0.1;
cyl.Depth := 0.1;
cyl.RotationAngle.Z := -180/Pi*ArcTan2(pEnd.X-pStart.X, pEnd.Y-pStart.Y);
cyl.RotationAngle.X := 180/Pi*ArcTan2(pEnd.Z-pStart.Z, Sqrt(Sqr(pEnd.Y-pStart.Y)+Sqr(pEnd.X-pStart.X)));
cyl.MaterialSource := mats.GetAtomMaterial(1); // temp fake implementataion
cyl.TagString := 'Bond ' + i.ToString + ' [' + bond.IdStart.ToString + '--' + bond.IdEnd.ToString + ']';
ctr.AddObject(cyl);
end;
end;
procedure TDMMain.LoadMoleculeByIndex(const ctrl: TControl3D;
const index: integer);
begin
if FMolecule = nil then
FMolecule := TMolecule.Create
else
FMolecule.Clear;
GetMoleculeByIndex(index, FMolecule);
LoadMoleculeToCtrl3D(ctrl, FMolecule);
end;
end.