2

I want to create a triangluar mesh structure in Delphi XE5.

The main TMyMesh class has generic TObjectLists to hold the list of vertices, faces, etc.

Let's say I have to calculate somthing for every face of the mesh. I could let take the TMyMesh class care of this:

TMyVertex=class(TComponent)
  Vertex: TPoint3D;
  //other fields and methods
end;

TMyTriangleFace=class(TComponent)
  Vertices: Array [0..2] of Integer;
  //other fields and methods
end;

TMyMesh=class(TComponent)
  ListOfVertices: TObjectList<TMyVertex>;
  ListOfTriangleFaces: TObjectList<TMyTriangleFace>;
  procedure CreateListOfTriangleFaces;
  procedure DoSomethingWithTheFace(const FaceNumber: Integer);
  procedure DoSomethingWithAllFaces;
end;

procedure TMyMesh.CreateListOfTriangleFaces;
begin
  for i := 0 to NumberOfTriangleFaces-1 do
  begin
    ListOfTriangleFaces.Add(TMyTraingleFace.Add(nil));
  end;
end;

procedure TMyMesh.DoSomethingWithTheFace(const AFaceNumber: Integer);
begin
  AVertex:=ListOfVertices[ListOfFaces[AFaceNumber].Vertices[0]];
  //do something
end;

procedure TMyMesh.DoSomethingWithAllFaces;
begin
  for i := 0 to ListOfFaces.Count-1 do
  begin
    DoSomethingWithTheFace(i);
  end;
end;

Or I could delegate it to the TMyTriangleFace class:

TMyVertex=class(TComponent)
  Vertex: TPoint3D;
  //other fields and methods
end;

TMyTriangleFace=class(TComponent)
  Vertices: Array [0..2] of Integer;
  procedure DoSomethingWithTheFace;
  //other fields and methods
end;

TMyMesh=class(TComponent)
  ListOfVertices: TObjectList<TMyVertex>;
  ListOfTriangleFaces: TObjectList<TMyTriangleFace>;
  procedure CreateListOfTriangleFaces;
  procedure DoSomethingWithAllFaces;
end;

procedure TMyTriangleFace.DoSomethingWithTheFace;
begin
  AVertex:=TMyMesh(Owner).ListOfVertices[Vertices[0]];
  //do something
end;

procedure TMyMesh.CreateListOfTriangleFaces;
begin
  for i := 0 to NumberOfTriangleFaces-1 do
  begin
    ListOfTriangleFaces.Add(TMyTraingleFace.Add(Self));
  end;
end;

procedure TMyMesh.DoSomethingWithAllFaces;
begin
  for i := 0 to ListOfFaces.Count-1 do
  begin
    ListOfTriangleFaces[i].DoSomethingWithTheFace;
  end;
end;

In this case I would need to give the TMyTriangleFace class access to the ListOfVertices. I could do this by passing the TMyMesh as owner in the procedure CreateListOfTriangleFaces.

In my understanding the second part should be the better code (Law of Demeter). But passing on TMyMesh as the owner is maybe not so nice.

What is the best practice to do this? Maybe both solutions are going in the wrong direction and there is a much better solution?

Thank you very much!

user3384674
  • 759
  • 8
  • 28
  • 1
    You want to use values as much as possible. Making everything a component will result in appalling perf. – David Heffernan Mar 05 '14 at 18:15
  • This question appears to be off-topic because it is asking for a code review. The question would better be asked at the Code Review stack exchange site. – David Heffernan Mar 05 '14 at 18:16
  • Does not look like code review to me. Sure there are large code samples, but in the essence it is about OOP approach vs data storage. If OOP should be that granular or simpler approaches are beneficial. – Kromster Mar 06 '14 at 04:37

1 Answers1

3

Creating a new object for every vertex and triangle is very inefficient because of all the extra initialization overhead and individual memory allocations. Also access will be inefficient too due to data being sparse in memory (interleaved with objects headers Delphi creates?) and functions calls.

As David comments, it would be much faster to have everything in a single TMyMesh class with vertices and indices as array of records.

Kromster
  • 7,181
  • 7
  • 63
  • 111
  • More on records vs classes for data storage: http://stackoverflow.com/questions/1876879/records-in-delphi – Kromster Mar 05 '14 at 20:23
  • Thanks! I will not use objects then. Should I use simple dynamic array of records or is it ok to use TList? – user3384674 Mar 05 '14 at 22:14
  • 1
    I've made a question about that: http://stackoverflow.com/questions/22215029/what-are-the-pros-and-cons-of-using-dynamic-array-of-records-vs-tlisttmyrecord – Kromster Mar 06 '14 at 04:33
  • @user It doesn't matter in terms of performance. But the `TList` container is much more usable. – David Heffernan Mar 06 '14 at 18:53