Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren? (https://www.delphipraxis.net/168000-wie-kann-ich-einen-viereckigen-bereich-auf-glsceneviewer-markieren.html)

Boyington 29. Apr 2012 22:15

Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Hallo alle,
ich bin Delphi-Anfänger und hab nun Probleme mit GLScene.

Folgende Aufgaben sind im Moment zu lösen:
1) *.stl Datei (im ASCII Format) mit OpenDialog laden und dann zeichnen.
2) mit Trackbars das Massstab und die Rotation des 3D-Objekts regeln.
3) mit Mouse-Dragging (onMouseDown, onMouseMove, onMouseUp) innerhalb von GLSceneViewer auf dem gezeichneten 3D-Objekt einen viereckigen Bereich markieren.

Später werde ich eine Funktion verwenden, um die Koordinaten aller Dreiecke von STL-Datei mit kürzestem Abstand (zwichen Kamera und Oberfläsche des 3D-Objekt) innerhalb des markierten Bereiches zu ermitteln (also kurz gesagt „Kantendetektion“). Dann werden die von KUKA-Industrieroboter genutzt zum robotergestützten Entgraten.

1) und 2) habe ich mit Delphi7 + GLScene jetzt schon fertiggemacht, weil GLScene sehr stark ist.

Meine Probleme:
- wie kann ich Teilaufgabe 3) realisieren? Weil den Befehl "GLSceneViewer1.Canvas.Rectangle(x1,y1,x2,y2); " es NICHT gibt.
Die vollständige Hilfe-Doku von GLScene habe ich nicht gefunden und die mitgelieferte Doku von GLScene selbst ist zwar nicht so ausführlich.

Deshalb bitte ich euch um die Hilfe und danke im Voraus!

Gruss
Lee

Boyington 29. Apr 2012 22:21

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Folgende ist der Quelltext:
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, GLScene, GLMisc, GLVectorFileObjects, GLWin32Viewer, GLFileSTL,
  Menus, ComCtrls, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    GLFreeForm1: TGLFreeForm;
    GLLightSource1: TGLLightSource;
    GLCamera1: TGLCamera;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    Laden1: TMenuItem;
    Beenden1: TMenuItem;
    TrackBar1: TTrackBar;
    TrackBar2: TTrackBar;
    TrackBar3: TTrackBar;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    OpenDialog1: TOpenDialog;
    procedure Beenden1Click(Sender: TObject);
    procedure Laden1Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure TrackBar2Change(Sender: TObject);
    procedure TrackBar3Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure GLSceneViewer1MouseDown(Sender: TObject;
      Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
       
  private
    { Private declarations }

  Massstab: Integer;
  Roll: Integer;
  Turn: Integer;
  sx,sy,ex,ey: Integer;
  Markieren:boolean;

  public
    { Public declarations }
  end;

Var
  Form1: TForm1;
 
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Massstab:=TrackBar1.Position;
  Roll:=TrackBar2.Position;
  Turn:=TrackBar3.Position;
end;

procedure TForm1.Beenden1Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Laden1Click(Sender: TObject);
begin
   Form1.OpenDialog1.Title:='Waehlen Sie bitte eine STL-Datei';
   Form1.OpenDialog1.InitialDir:='C:\';
   Form1.OpenDialog1.Filter:='STL Files in ASCII Format(*.stl)|*.stl';
   Form1.OpenDialog1.Execute;

   GLFreeForm1.LoadFromFile(OpenDialog1.FileName);
   GLFreeForm1.Scale.Scale(0.5) ;
   GLFreeForm1.Roll(0);
   GLFreeForm1.Turn(0);
 
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
   Massstab:=TrackBar1.Position;
   GLFreeForm1.Scale.Normalize;
   GLFreeForm1.Scale.Scale(Massstab/10);

end;


procedure TForm1.TrackBar2Change(Sender: TObject);
begin
   Roll:=TrackBar2.Position;
   GLFreeForm1.Rotation.Normalize;
   GLFreeForm1.Roll(Roll);
   GLFreeForm1.Turn(Turn);
end;


procedure TForm1.TrackBar3Change(Sender: TObject);
begin
   Turn:=TrackBar3.Position;
   GLFreeForm1.Rotation.Normalize;
   GLFreeForm1.Roll(Roll);
   GLFreeForm1.Turn(Turn);
end;



procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  //bitte euren Text hier einfügen!!!
end;

procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
   //bitte euren Text hier einfügen!!!
end;

procedure TForm1.GLSceneViewer1MouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
   //bitte euren Text hier einfügen!!!
end;
end.

Boyington 1. Mai 2012 11:19

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
kennen sich hier vielleicht wenig Leute mit GLScene gut aus?
Ich bitte um die Hilfe nochmals, danke!

Bummi 1. Mai 2012 12:03

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Etwas in der Art funktioniert, bringt Dich aber wahrscheinlich nicht weiter, da Du ja Quasi nur ein Guckloch definierst.

Delphi-Quellcode:
type
  TGLSceneViewer = class(GLWin32Viewer.TGLSceneViewer)
        procedure WMPaint(var Message: TWMPaint); message WM_PAINT;

  end;

  TForm1 = class(TForm)
.......
......
procedure TGLSceneViewer.WMPaint(var Message: TWMPaint);
var
 DC:HDC;
begin
   inherited;
   DC := GetDC(handle);
   Windows.FrameRect(DC, Rect(FMdownX, MDownY, FMCurrentX,FMCurrentY),TForm(Owner).Brush.Handle);
   ReleaseDC(Handle,DC);
end;

Uwe Raabe 1. Mai 2012 18:09

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Zitat:

Zitat von Boyington (Beitrag 1164200)
3) mit Mouse-Dragging (onMouseDown, onMouseMove, onMouseUp) innerhalb von GLSceneViewer auf dem gezeichneten 3D-Objekt einen viereckigen Bereich markieren.

Leider geht aus dieser Beschreibung nicht hervor, ob der "rechteckige" Bereich auf die Bildschirmebene bezogen ist, oder auf eine Fläche im Raum.

Für die Bildschirmebene empfehle ich ein TGLHUDSprite mit einem passenden AlphaBlend-Wert, damit man hindurchsehen kann. Soll das "Rechteck" im Raum erscheinen und sich mit dem Objekt mitdrehen, dann wäre ein TGLCube mit CubeDepth = 0 die bessere Wahl.

Boyington 2. Mai 2012 08:42

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Danke für eure Hinweise:)
Erhlich gesagt, dass ich mich selber noch nicht entschieden habe, ob der rechteckige Bereich (s.g "Guckloch") auf der Bildschirmebene/GLSceneViewer-Ebene oder auf der Fläche im Raum sein soll, das ist abhängig davon, welche Methode relativ einfacher ist.

-------------------------------------------------------------------
an Uwe Raabe:
1. für Fläche im Raum: mit welchem Parameter kann ich TGLCube transparent machen? Also nur mit vier Kanten.
2. wie mache ich, dass TGLCube(pmLines, also NUR mit vier Kanten) bzw. die Projektion vom TGLCube immer auf der Oberfläche des 3D-Objektes liegt?
--------------------------------------------------------------------
Nochmals vielen Dank!
Gruss
Lee

Uwe Raabe 2. Mai 2012 12:40

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Zitat:

Zitat von Boyington (Beitrag 1164524)
1. für Fläche im Raum: mit welchem Parameter kann ich TGLCube transparent machen? Also nur mit vier Kanten.

Delphi-Quellcode:
Material.FrontProperties.PolygonMode := pmLines;
Zitat:

Zitat von Boyington (Beitrag 1164524)
2. wie mache ich, dass TGLCube(pmLines, also NUR mit vier Kanten) bzw. die Projektion vom TGLCube immer auf der Oberfläche des 3D-Objektes liegt?

Das Problem dabei ist, daß die Projektion nicht notwendigerweise ein einfach tranformiertes Rechteck ist - z.B. wenn die Projektionsfläche eine Kugel ist. Das ist eindeutig der schwierigere Part, nicht in zwei Sätzen zu beantworten und hängt sehr stark von den 3D-Objekten ab.

Boyington 2. Mai 2012 13:52

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1164559)
Zitat:

Zitat von Boyington (Beitrag 1164524)
1. für Fläche im Raum: mit welchem Parameter kann ich TGLCube transparent machen? Also nur mit vier Kanten.

Delphi-Quellcode:
Material.FrontProperties.PolygonMode := pmLines;
Zitat:

Zitat von Boyington (Beitrag 1164524)
2. wie mache ich, dass TGLCube(pmLines, also NUR mit vier Kanten) bzw. die Projektion vom TGLCube immer auf der Oberfläche des 3D-Objektes liegt?

Das Problem dabei ist, daß die Projektion nicht notwendigerweise ein einfach tranformiertes Rechteck ist - z.B. wenn die Projektionsfläche eine Kugel ist. Das ist eindeutig der schwierigere Part, nicht in zwei Sätzen zu beantworten und hängt sehr stark von den 3D-Objekten ab.

1000 Dank!!!

noch eine Frage zu 1): PolygonMode von FrontProperties:=pmLines habe ich in "Object Inspector" gemacht, aber die Kanten von diesem GLCube werden manchmals von 3D-Bauteil verdeckt. Wie mache ich GLCube immer im Vordergrund, damit werden KEINE Kante vom GLCube verdeckt.

l.g
Lee

Uwe Raabe 2. Mai 2012 14:31

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Zitat:

Zitat von Boyington (Beitrag 1164565)
noch eine Frage zu 1): PolygonMode von FrontProperties:=pmLines habe ich in "Object Inspector" gemacht, aber die Kanten von diesem GLCube werden manchmals von 3D-Bauteil verdeckt. Wie mache ich GLCube immer im Vordergrund, damit werden KEINE Kante vom GLCube verdeckt.

Der Cube muss natürlich "näher" an der Kamera liegen, als das 3D-Bauteil. Es kann auch helfen, wenn du den Cube an das Ende der Objektliste der Scene hängst, damit er als letztes gerendert wird.

Boyington 2. Mai 2012 14:55

AW: Wie kann ich einen viereckigen Bereich auf GLSceneViewer markieren?
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1164567)
Zitat:

Zitat von Boyington (Beitrag 1164565)
noch eine Frage zu 1): PolygonMode von FrontProperties:=pmLines habe ich in "Object Inspector" gemacht, aber die Kanten von diesem GLCube werden manchmals von 3D-Bauteil verdeckt. Wie mache ich GLCube immer im Vordergrund, damit werden KEINE Kante vom GLCube verdeckt.

Der Cube muss natürlich "näher" an der Kamera liegen, als das 3D-Bauteil. Es kann auch helfen, wenn du den Cube an das Ende der Objektliste der Scene hängst, damit er als letztes gerendert wird.

Prima:-) Ich hab geschafft mit der Einstellung der Position wie folgende:
GLCamera1 X=0, Y=0, Z=2
GLFreeForm1 X=0, Y=0, Z=0
GLCube1 X=0, Y=0, Z=1

Dann werden keine Kanten vom GLCube verdeckt!

Vielan Dank!
lg
Lee


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr.

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