Hallo meine Lieben,
ich habe ein 3D Modell eines Hauses und möchte von einem Punkt in einem Zimmer ausgehend zufällige Punkte an allen Oberflächen dieses Zimmers generieren, damit am Ende eine Punktwolke entsteht. Wie könnte ich dies am besten machen? Ich danke euch schon mal für die Hilfe.
Punkt auf Oberfläche generieren
-
- User
- Beiträge: 512
- Registriert: Mittwoch 13. November 2019, 08:38
Du musst du etwas konkreter werden. In welchem Format liegt das 3D-Modell vor? Hast du bereits Koordinaten/Flächen oder sonst was davon mit Python eingelesen?
Grundsätzlich: Ebenengleichung der Oberflächen aufstellen, zufällige Zahlen einsetzen, die entstehenden Punkte verarbeiten.
Grundsätzlich: Ebenengleichung der Oberflächen aufstellen, zufällige Zahlen einsetzen, die entstehenden Punkte verarbeiten.
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Ich habe das 3D Modell als IFC-Datei und als .obj-Datei. Einfach eine Ebenengleichung der Oberflächen aufzustellen ist glaube ich nicht möglich, da in dem Modell ja beispielsweise ja auch Türgriffe und Fensterbänke usw vorhanden sind. Es sind ja nicht nur Wände in dem Sinne.
Wenn das beliebige Objekte sind, musst du eine Bibliothek finden, die das Format schluckt und in entsprechende Geometrie-Objekte wandelt. Und die haben dann üblicherweise ray casting oder ähnliche Operationen um zb aus einem Punkt in der Mitte des Raumes (den du festlegen musst!) zufällige Strahlen mit den umgebenden Objekten zu schneiden.
OpenCascade kann das: https://old.opencascade.com/content/the ... tion-point
FreeCAD setzt AFAIK darauf, und ist ein Python Skriptbar. Das wäre mein erster Ansatzpunkt.
OpenCascade kann das: https://old.opencascade.com/content/the ... tion-point
FreeCAD setzt AFAIK darauf, und ist ein Python Skriptbar. Das wäre mein erster Ansatzpunkt.
-
- User
- Beiträge: 512
- Registriert: Mittwoch 13. November 2019, 08:38
Türgriffe und Fensterbänke sind aber afaik im WaveFront Obj-Format auch als Flächen hinterlegt. Lediglich die Darstellung/Verarbeitung erfolgt rund.Herzdame2608 hat geschrieben: Mittwoch 28. Oktober 2020, 12:33 Einfach eine Ebenengleichung der Oberflächen aufzustellen ist glaube ich nicht möglich, da in dem Modell ja beispielsweise ja auch Türgriffe und Fensterbänke usw vorhanden sind. Es sind ja nicht nur Wände in dem Sinne.
Für Python gibt es PyWavefront. Damit kommst du schon mal an die `vertices` und die daraus zusammengesetzten `faces`. Vermutlich es ist hilfreich sich zunächst mit dem Format vertraut zu machen: https://de.wikipedia.org/wiki/Wavefront_OBJ
ungetestet:
Code: Alles auswählen
import pywavefront
scene = pywavefront.Wavefont(<pfad_zur_obj_datei>, collect_faces=True)
print(scene.vertices) # gibt dir alle Punkte aus
for mesh in scene.mesh_list: # Die Flächen "faces" stecken in den "meshes"
print(mesh.faces)
Wobei der Vorschlag von __deets__ ggf. auch sehr schnell zum Ziel führt. Da kommts natürlich auch etwas drauf an, was du dann damit machen willst bzw. wer der Anwender ist usw. Ich halte beide Vorgehen für gut.
Edit: In dem Zusammenhang vielleicht hilfreich: https://pointclouds.org/.
Noch mal Edit: Wenns nicht ums Programmieren, sondern nur ums "Haben" geht, hilft vllt. auch das: http://cloudcompare.org/.
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Vielen Dank für eure schnellen Antworten.
Ich habe jetzt mal die Datei ausgelesen und eine .txt-Datei mit allen x,y, und z Koordinaten bekommen, wäre es nicht auch möglich damit zu arbeiten?
Hier ist ein kleiner Ausschnitt.
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 21.7873750384417 0
v 13.9845180074552 21.7873750384417 2.6
v 13.9845180074552 21.7873750384417 0
v 13.9845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 9.64739683486211 0
v 13.7845180074552 9.64739683486211 2.6
v 13.7845180074552 9.64739683486211 0
v 13.7845180074552 9.64739683486211 2.6
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 9.64739683486211 2.6
Ich habe jetzt mal die Datei ausgelesen und eine .txt-Datei mit allen x,y, und z Koordinaten bekommen, wäre es nicht auch möglich damit zu arbeiten?
Hier ist ein kleiner Ausschnitt.
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 21.7873750384417 0
v 13.9845180074552 21.7873750384417 2.6
v 13.9845180074552 21.7873750384417 0
v 13.9845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 9.64739683486211 0
v 13.7845180074552 9.64739683486211 2.6
v 13.7845180074552 9.64739683486211 0
v 13.7845180074552 9.64739683486211 2.6
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 9.64739683486211 0
v 13.9845180074552 21.7873750384417 0
v 13.7845180074552 21.7873750384417 0
v 13.7845180074552 9.64739683486211 0
v 13.9845180074552 9.64739683486211 2.6
v 13.9845180074552 21.7873750384417 2.6
v 13.7845180074552 21.7873750384417 2.6
v 13.7845180074552 9.64739683486211 2.6
Jein. Theoretisch ja, aber dann musst du die gesamte Arbeit des einlesens und repräsentieren als Objekte die selbst erarbeiten. Und da kann dir hier auch keiner 10 Zeilen code liefern, die das lösen.
Ich würde mir einer der genannten Technologien vorgehen.
Ich würde mir einer der genannten Technologien vorgehen.
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Das mit Pywavefront hat perfekt geklappt, am Anfang hat er mir für manche Objekte Fehler rausgegeben und diese irgendwie nicht erkannt, das konnte ich in der IFC-Datei dann aber beheben. Wie kann ich nun weiter vorgehen um zufällige Punkte auf der Oberfläche eines Raumes zu generieren?
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Wichtig ist hierbei, dass immer nur die nächste Fläche mit Punkten befüllt wird und die dahinter liegenden Flächen frei bleiben.
-
- User
- Beiträge: 512
- Registriert: Mittwoch 13. November 2019, 08:38
Jetzt suchst du dir anhand der Flächen die entsprechenden Koordinaten der Punkte. Dann ermittelt du die Ebenengleichung in Dreipunkteform. Also: x = p + s * (q - p) + t * (r - p). Wobei x der Vektor des neuen Punktes auf der Ebene ist, p der Stützvektor (Ortsvektor einer der Punkte), q und r die Ortsvektoren der anderen Punkte und t und s die mit Zufallswerten zu befüllenden Variablen. Dabei musst du natürlich etwas auf die Grenzen der Zufallswerte achten, damit die Punkte innerhalb deiner Fläche bleiben. Wenn die Flächen durch mehr als 3 Punkte beschrieben werden oder du keine Lust hast das selbst zu machen, kannst du auch Shapely verwenden: https://gis.stackexchange.com/questions ... -in-python.
Was meinst du mit "nur die nächste Fläche"?
Was meinst du mit "nur die nächste Fläche"?
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Vielen Dank schonmal hierfür.
Mit nächster Fläche meine ich, dass hinter meinem Raum ja ein weiterer Raum ist, diese aber nicht miteinbeziehen werden dürfen. Also wenn hinter einer fläche noch eine liegt muss diese ignoriert werden.
Mit nächster Fläche meine ich, dass hinter meinem Raum ja ein weiterer Raum ist, diese aber nicht miteinbeziehen werden dürfen. Also wenn hinter einer fläche noch eine liegt muss diese ignoriert werden.
Dadurch das du die Schnittpunkte nach Entfernung sortierst, ist der naechstliegende automatisch der einzig erlaubte. Ausser du hast Oeffnungen in andere Raeume, das solltest du aber im 3D-Modell aendern - also zB Tueren einbauen, auch wenn das nur eine simple Flaeche ist.
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Wie meinst du, dass ich mit den Flächen die Koordinaten der Punkte suchen muss?einfachTobi hat geschrieben: Mittwoch 28. Oktober 2020, 18:51 Jetzt suchst du dir anhand der Flächen die entsprechenden Koordinaten der Punkte. Dann ermittelt du die Ebenengleichung in Dreipunkteform. Also: x = p + s * (q - p) + t * (r - p). Wobei x der Vektor des neuen Punktes auf der Ebene ist, p der Stützvektor (Ortsvektor einer der Punkte), q und r die Ortsvektoren der anderen Punkte und t und s die mit Zufallswerten zu befüllenden Variablen. Dabei musst du natürlich etwas auf die Grenzen der Zufallswerte achten, damit die Punkte innerhalb deiner Fläche bleiben. Wenn die Flächen durch mehr als 3 Punkte beschrieben werden oder du keine Lust hast das selbst zu machen, kannst du auch Shapely verwenden: https://gis.stackexchange.com/questions ... -in-python.
Was meinst du mit "nur die nächste Fläche"?
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Ich weiß gerade wirklich nicht, wie ich anfangen soll...
Ich würde wirklich nicht selbst sowas programmieren. Hier ist eine andere Bibliothek & ein Beispiel wie man da Körper mit strahlen schneidet. https://trimsh.org/examples/ray.html
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Ok das ist ja schonmal super.__deets__ hat geschrieben: Mittwoch 28. Oktober 2020, 23:29 Ich würde wirklich nicht selbst sowas programmieren. Hier ist eine andere Bibliothek & ein Beispiel wie man da Körper mit strahlen schneidet. https://trimsh.org/examples/ray.html
Mein Problem ist nun, wenn ich diese Biblitothek anwende, funktioniert das irgendwie nicht mit dem Koordinatensystem meiner .OBJ-Datei...
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Ich hab verschiedene .OBJ-Dateien versucht. Hier eine ganz einfache mit vier Wänden.
https://drive.google.com/file/d/1f4izVx ... sp=sharing
(Wusste nicht, wie ich sonst die Datei hier einfügen sollte.
https://drive.google.com/file/d/1f4izVx ... sp=sharing
(Wusste nicht, wie ich sonst die Datei hier einfügen sollte.
Code: Alles auswählen
import pywavefront
import trimesh
import numpy as np
scene = pywavefront.Wavefront('C:/.../4waende.obj', collect_faces=True)
print(scene.vertices)
for mesh in scene.mesh_list:
print(mesh.faces)
mesh = mesh.faces
ray_origins = np.array([[1, 1, 1])
ray_directions = np.random.rand(10000, 3)
print(mesh.ray.intersects_location.__doc__)
Aber du schneidest doch gar nichts. Und die Zufallsstrahlen sind ja nur in einem der 8 Quadranten.
Du musst den Punkt von dem du ausgehst schon irgendwie angeben, passend zur Objekt-Datei. Der ist ja unmöglich zu raten. Bestenfalls kannst du den Schwerpunkt aller Punkte im Objekt nehmen, aber das ist eine ziemlich maue Heuristik.
Du musst den Punkt von dem du ausgehst schon irgendwie angeben, passend zur Objekt-Datei. Der ist ja unmöglich zu raten. Bestenfalls kannst du den Schwerpunkt aller Punkte im Objekt nehmen, aber das ist eine ziemlich maue Heuristik.
-
- User
- Beiträge: 62
- Registriert: Donnerstag 18. Juni 2020, 12:04
Ich habe den Punkt mehrmals variiert und egal was ich dort eingebe, es kommt immer Syntax Fehler. Auch wenn ich weiß, dass der Punkt mitten im Raum liegt.