Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   CSG mit GLScene (https://www.delphipraxis.net/188753-csg-mit-glscene.html)

Bambini 4. Apr 2016 16:44

CSG mit GLScene
 
Ich habe ein Problem mit dem Boolean CSG Operationen von GLScene.
Wenn 2 Körper in der gleichen Ebene liegen, werden bei der CSG Operation Substract die flächen die sich überschneiden nicht abgezogen.

Hier ein kleines Demo Programm, welches 2 Quadrate von einander abzieht:
Delphi-Quellcode:

uses
  GLVectorGeometry, GLVectorFileObjects, GLVectorLists, GLGLUTesselation, GLMeshCSG;

procedure AddFace(AGLMesh : TGLBaseMesh; const ACorners : array of TAffineVector);
var
  LVertexes  : TAffineVectorList;
  i          : Integer;
  LNormal    : TAffineVector;
begin
  LVertexes := TAffineVectorList.Create;
  try
     for i := Low(ACorners) to High(ACorners) do
        LVertexes.Add(ACorners[i]);

     LNormal := CalcPlaneNormal(ACorners[0], ACorners[1], ACorners[2]);

     (* Fläche in Dreiecke zerlegen *)
     DoTesselate(LVertexes, AGLMesh, @LNormal, False);
  finally
     LVertexes.Free;
  end;
end;


procedure TForm3.Button1Click(Sender: TObject);
var
  LCorners      : array[1..4] of TAffineVector;
  LOffset       : TAffineVector;
  LGLMesh1       : TGLBaseMesh;
  LGLMesh2       : TGLBaseMesh;
  LGLMeshResult : TGLBaseMesh;
  i: Integer;
begin

  LCorners[1] := AffineVectorMake(0, 0, 0);
  LCorners[2] := AffineVectorMake(2, 0, 0);
  LCorners[3] := AffineVectorMake(2, 2, 0);
  LCorners[4] := AffineVectorMake(0, 2, 0);

  LOffset    := AffineVectorMake(1, 0, 0);

  LGLMesh1       := TGLBaseMesh.Create(nil);
  LGLMesh2       := TGLBaseMesh.Create(nil);
  LGLMeshResult := TGLBaseMesh.Create(nil);
  try
     (* Eine XY Seite mit der Kantenlänge 2 *)
     AddFace(LGLMesh1, [LCorners[1], LCorners[2], LCorners[3], LCorners[4]]);

     (* Die Seite um 1 nach X Verschieben *)
     for i := Low(LCorners) to High(LCorners) do
        AddVector(LCorners[i], LOffset);

     (* Die verschobene Seite in das 2. Mesh *)
     AddFace(LGLMesh2, [LCorners[1], LCorners[2], LCorners[3], LCorners[4]]);

     (* Beide Flächen subtrahieren *)
     TMeshObject.CreateOwned(LGLMeshResult.MeshObjects);
     CSG_Operation(LGLMesh1.MeshObjects[0], LGLMesh2.MeshObjects[0], CSG_Subtraction, LGLMeshResult.MeshObjects[0], '', '');

     (* Was für Werte sind jetzt vorhanden? *)
     for i:= 0 to LGLMeshResult.MeshObjects[0].Vertices.Count-1 do
        Memo1.Lines.Add(Format('%f, %f', [LGLMeshResult.MeshObjects[0].Vertices[i].X, LGLMeshResult.MeshObjects[0].Vertices[i].Y]));

  finally
     LGLMesh1.Free;
     LGLMesh2.Free;
     LGLMeshResult.Free;
  end;
end;
Es scheint die CSG Funktion von GLScene hat ein Problem im 2D Bereich.
Hat jemand eine Idee warum?

Uwe Raabe 4. Apr 2016 16:57

AW: CSG mit GLScene
 
CSG in GLScene ist kein richtiges CSG, da hier lediglich über die OpenGL Z-Puffer etwas ähnlich aussehendes nachgebildet wird. Dies versagt leider unter diversen Bedingungen, wovon sich überlappende Flächen eine ist. OpenGL kennt halt nur Flächen und keine Solids. Daher ist auch kein echtes CSG möglich.

Bambini 4. Apr 2016 17:11

AW: CSG mit GLScene
 
Soweit ich das sehe verwendet GLScene das BSP Verfahren:
https://de.wikipedia.org/wiki/Binary_Space_Partitioning

Jens01 4. Apr 2016 19:56

AW: CSG mit GLScene
 
@Uwe
Was isn für Dich "echtes CSG"?

Das, was da programmiert ist, ist zT doch etwas wirr und unübersichtlich. Und auch nicht vollständig. Ist ja auch kein einfaches Thema.

Uwe Raabe 4. Apr 2016 20:57

AW: CSG mit GLScene
 
Zitat:

Zitat von Jens01 (Beitrag 1334638)
@Uwe
Was isn für Dich "echtes CSG"?

Die GLMeshCSG hatte ich gar nicht mehr auf dem Schirm - obwohl ich mich nun dunkel daran erinnere, daß ich mal einen Fix in GLVectorFilesObjects eingebracht habe, der sich in einem ähnlichen Fehler manifestierte.

Jens01 4. Apr 2016 22:49

AW: CSG mit GLScene
 
Ich hatte irgendwo Deinen Namen da auch gesehen.
Wie gesagt, die Codierung ist etwas unübersichtlich und noch unfertig. Aber auch ein sehr schwieriges und umfangreiches Thema. Die "Verschneidung" von 2 parallel überlappenden Flächen ist ein Sonderfall und in GLScene evtl. nicht implementiert.

Bambini 5. Apr 2016 08:01

AW: CSG mit GLScene
 
Dieser Effekt tritt leider auch auf, wenn zwei Körper verschnitten werden, die sich die Seiten teilen.
Z.B. 2 Würfel mit genau gleicher Kantenlänge, wobei der 2. Würfel etwas höher sitzt.
Verschneidet man den ersten mit dem 2. Würfel, so bleiben die "Seitenwände" des 1. Würfeln erhalten und er ist nur innen ausgeschnitten.

Jens01 5. Apr 2016 11:56

AW: CSG mit GLScene
 
Wird es verschnitten, wenn Du die Objekte ein kleines Stück ineinander schiebst?

Bambini 5. Apr 2016 13:17

AW: CSG mit GLScene
 
Ineinander, wird es nur "ausgehöhlt", der Rand bleibt stehen, versetzt man den Würfen ein kleines Stück oder macht ihn etwas größer,
sieht die Verschneidung gut aus.

Jens01 5. Apr 2016 13:44

AW: CSG mit GLScene
 
Entweder Du machst es mit solchen Tricks oder Du wagst Dich an die Codierung.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz