Punkt auf Oberfläche generieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Herzdame2608
User
Beiträge: 62
Registriert: Donnerstag 18. Juni 2020, 12:04

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.
einfachTobi
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.
Herzdame2608
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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

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.
Türgriffe und Fensterbänke sind aber afaik im WaveFront Obj-Format auch als Flächen hinterlegt. Lediglich die Darstellung/Verarbeitung erfolgt rund.
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)
Der Rest bis zur Punktwolke ist Mathematik - das bekommt man auch noch hingebastelt.
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/.
Herzdame2608
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
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Herzdame2608
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?
Herzdame2608
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.
einfachTobi
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"?
Herzdame2608
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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Herzdame2608
User
Beiträge: 62
Registriert: Donnerstag 18. Juni 2020, 12:04

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"?
Wie meinst du, dass ich mit den Flächen die Koordinaten der Punkte suchen muss?
Herzdame2608
User
Beiträge: 62
Registriert: Donnerstag 18. Juni 2020, 12:04

Ich weiß gerade wirklich nicht, wie ich anfangen soll...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14: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
Herzdame2608
User
Beiträge: 62
Registriert: Donnerstag 18. Juni 2020, 12:04

__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
Ok das ist ja schonmal super.
Mein Problem ist nun, wenn ich diese Biblitothek anwende, funktioniert das irgendwie nicht mit dem Koordinatensystem meiner .OBJ-Datei...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

🤷‍♂️ Ohne konkreten Code und Obj Dateien und so kann man dazu nix sagen.
Herzdame2608
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.

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__)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Herzdame2608
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.
Antworten