Skip to content

Commit

Permalink
Add 3d mesh generation
Browse files Browse the repository at this point in the history
  • Loading branch information
argenos committed Jan 17, 2025
1 parent fb8f818 commit f05d7b1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 22 deletions.
54 changes: 32 additions & 22 deletions src/fpm/generators/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
create_mesh,
create_collection,
)
from fpm.graph import get_floorplan_model_name
from fpm.graph import get_floorplan_model_name, get_3d_structure
from fpm.utils import save_file


Expand All @@ -19,31 +19,41 @@ def generate_3d_mesh(g, output_path, **custom_args):
# clear the blender scene
clear_scene()

spaces = model.spaces
# create wall spaces
for space in spaces:
for i, wall in enumerate(space.walls):
vertices, faces = wall.generate_3d_structure()
create_mesh(building, wall.name, vertices, faces)
print("Getting 3D structures")
elements = get_3d_structure(g, "Wall")
create_element_mesh(building, elements)

for feature in space.floor_features:
vertices, faces = feature.generate_3d_structure()
create_mesh(building, feature.name, vertices, faces)
columns = get_3d_structure(g, "Column")
create_element_mesh(building, columns)

wall_openings = model.wall_openings
# create wall openings
for wall_opening in wall_openings:
dividers = get_3d_structure(g, "Divider")
create_element_mesh(building, dividers)

vertices, faces = wall_opening.generate_3d_structure()
create_mesh(building, wall_opening.name, vertices, faces)
entryways = get_3d_structure(g, "Entryway")
create_element_mesh(building, entryways)
subtract_opening(entryways)

# boolean operation for walls and opening
boolean_operation_difference(wall_opening.wall_a.name, wall_opening.name)
if not wall_opening.wall_b is None:
boolean_operation_difference(wall_opening.wall_b.name, wall_opening.name)

bpy.data.objects[wall_opening.name].select_set(True)
bpy.ops.object.delete()
windows = get_3d_structure(g, "Window")
create_element_mesh(building, windows)
subtract_opening(windows)

file_name = "{name}.{ext}".format(name=model_name, ext=file_format)
save_file(output_path, file_name, None)


def create_element_mesh(building, elements):
for e in elements:
name = e.get("name")
vertices = e.get("vertices")
faces = e.get("faces")
create_mesh(building, name, vertices, faces)


def subtract_opening(openings):
# boolean operation for walls and opening
for opening in openings:
name = opening.get("name")
for wall in opening.get("voids", list()):
boolean_operation_difference(wall, name)
bpy.data.objects[name].select_set(True)
bpy.ops.object.delete()
32 changes: 32 additions & 0 deletions src/fpm/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,38 @@ def get_opening_points(g, element="Entryway"):
return opening_points


def get_3d_structure(g, element="Wall"):
elements = list()
coords_m = get_coordinates_map(g)
for e, _, _ in g.triples((None, RDF.type, FP[element])):
poly = g.value(e, FP["3d-shape"])
vertices_ptr = g.value(poly, POLY["points"])
vertices = get_list_from_ptr(g, vertices_ptr)
positions = list()
for point in vertices:
p = get_point_position(g, point)
x, y = get_waypoint_coord(g, p, coords_m)
positions.append((x, y, p["z"]))

faces_ptr = g.value(poly, POLY["faces"])
faces_nodes = get_list_from_ptr(g, faces_ptr)
faces = list()
for f in faces_nodes:
face_vertices = get_list_from_ptr(g, f)
face = [vertices.index(point) for point in face_vertices]
faces.append(face)

name = prefixed(g, e).split(":")[-1]
d = {"name": name, "vertices": positions, "faces": faces}
if element in ["Entryway", "Window"]:
voids_ptr = g.value(e, FP["voids"])
voids = get_list_from_ptr(g, voids_ptr)
d["voids"] = [prefixed(g, v).split(":")[-1] for v in voids]
elements.append(d)

return elements


def get_point_positions_in_space(g, space):
polygon = g.value(space, FP["shape"])

Expand Down

0 comments on commit f05d7b1

Please sign in to comment.