Skip to content

Commit

Permalink
use IfcCsgPrimitive3D instead of extrusions
Browse files Browse the repository at this point in the history
  • Loading branch information
c-mellueh committed Sep 26, 2024
1 parent 920d788 commit 104c4ad
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 32 deletions.
108 changes: 78 additions & 30 deletions boreholeCreator/tool/geometry.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import math
from typing import Type

import ifcopenshell
Expand Down Expand Up @@ -53,60 +52,109 @@ def create_rectangle(cls, ifcfile, x, y, name):

@classmethod
def create_triangle(cls, ifcfile, radius, name):
c = 2 * radius * math.sqrt(3.0)
c = 2 * radius * 1.7320508076 # sqrt(3)
coordinates = ((-0.5 * c, radius), (0.5 * c, radius), (0.0, -2 * radius))
point_list = ifcfile.create_entity("IfcCartesianPointList2D", CoordList=coordinates)
curve = ifcfile.create_entity("IfcIndexedPolyCurve", Points=point_list)
return ifcfile.create_entity("IfcArbitraryClosedProfileDef", ProfileType="AREA", ProfileName=name,
OuterCurve=curve)

@classmethod
def create_pyramid(cls):
def create_pyramid(cls, use_primitive: bool = True):
radius = cls.get_radius()
ifcfile = cls.get_file()
context = cls.get_context()
c = 2 * radius * math.sqrt(3.0)
height = 2.
coord = ((0., 0., 0.), (-0.5 * c, radius, height), (0.5 * c, radius, height), (0.0, -2 * radius, height))
point_list = ifcfile.create_entity("IFCCARTESIANPOINTLIST3D", CoordList=coord)

face_indexes = ((3, 2, 4), (1, 3, 4), (1, 2, 3), (1, 4, 2))
faces = [ifcfile.create_entity("IFCINDEXEDPOLYGONALFACE", CoordIndex=point_list) for point_list in face_indexes]

face_set = ifcfile.create_entity("IFCPOLYGONALFACESET", Coordinates=point_list, Closed=True, Faces=faces)
shape = ifcfile.createIfcShapeRepresentation(context, "Body", "Tessellation", [face_set])
representation = ifcfile.create_entity("IFCPRODUCTDEFINITIONSHAPE", Representations=[shape])
return representation
c = 2 * radius * 1.7320508076
if use_primitive:
return cls.create_rectangular_pyramid_shape("Pyramid", -2., c, c)
else:
ifcfile = cls.get_file()
context = cls.get_context()

height = 2.
coord = ((0., 0., 0.), (-0.5 * c, radius, height), (0.5 * c, radius, height), (0.0, -2 * radius, height))
point_list = ifcfile.create_entity("IFCCARTESIANPOINTLIST3D", CoordList=coord)

face_indexes = ((3, 2, 4), (1, 3, 4), (1, 2, 3), (1, 4, 2))
faces = [ifcfile.create_entity("IFCINDEXEDPOLYGONALFACE", CoordIndex=point_list) for point_list in
face_indexes]

face_set = ifcfile.create_entity("IFCPOLYGONALFACESET", Coordinates=point_list, Closed=True, Faces=faces)
shape = ifcfile.createIfcShapeRepresentation(context, "Body", "Tessellation", [face_set])
representation = ifcfile.create_entity("IFCPRODUCTDEFINITIONSHAPE", Representations=[shape])
return representation

@classmethod
def create_cylinder(cls, name, depth: float):
ifcfile = cls.get_file()
def create_cylinder(cls, name, depth: float, use_primitive: bool = True):
radius = cls.get_radius()
circle = cls.create_circle(ifcfile, radius, f"Circle_{name}")
return cls.create_extrusion_shape(circle, name, depth, )

if use_primitive:
cls.create_cylinder_shape(f"Circle_{name}", radius, depth)
else:
# Create Cylinder by extruding Circle
ifcfile = cls.get_file()
circle = cls.create_circle(ifcfile, radius, f"Circle_{name}")
return cls.create_extrusion_shape(circle, name, depth, )

@classmethod
def create_cuboid(cls, name, depth: float):
ifcfile = cls.get_file()
def create_cuboid(cls, name, depth: float, use_primitive: bool = True):
radius = cls.get_radius()
reactangle = cls.create_rectangle(ifcfile, radius * 1.2, radius * 1.2, f"Circle_{name}")
return cls.create_extrusion_shape(reactangle, name, depth)
c = 1.4142135624 * radius # sqrt(2)*radius
if use_primitive:
return cls.create_cuboid_shape(f"Cuboid_{name}", depth, c, c)
else:
ifcfile = cls.get_file()
reactangle = cls.create_rectangle(ifcfile, radius * 1.2, radius * 1.2, f"Cuboid_{name}")
return cls.create_extrusion_shape(reactangle, name, depth)

@classmethod
def create_prism(cls, name, depth: float, ):
ifcfile = cls.get_file()
radius = cls.get_radius()
triangle = cls.create_triangle(ifcfile, radius, f"Circle_{name}")
triangle = cls.create_triangle(ifcfile, radius, f"Prism_{name}")
return cls.create_extrusion_shape(triangle, name, depth)

@classmethod
def create_extrusion_shape(cls, profile, name, depth: float, ):
dir = (0., 0., 1.) if depth <= 0. else (0., 0., -1.)
def create_extrusion_shape(cls, profile, name: str, depth: float, ):
direction = (0., 0., 1.) if depth <= 0. else (0., 0., -1.)
context = cls.get_context()
ifcfile = cls.get_file()
extrusion_placement = tool.Location.create_ifcaxis2placement(ifcfile, [0.0, 0.0, 0.0], dir,
(1.0, 0.0, 0.0)) # Axis down
extrusion_placement = tool.Location.create_ifcaxis2placement3D(ifcfile, [0.0, 0.0, 0.0], direction,
(1.0, 0.0, 0.0)) # Axis down
solid = cls.create_ifcextrudedareasolid(ifcfile, profile, extrusion_placement, Z, abs(depth))
body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "SweptSolid", [solid])
product_shape = ifcfile.createIfcProductDefinitionShape(f"{name}", None, [body_representation])
return product_shape

@classmethod
def create_cylinder_shape(cls, name: str, radius: float, height: float):
context = cls.get_context()
ifcfile = cls.get_file()
direction = (0., 0., 1.) if height <= 0. else (0., 0., -1.)
placement = tool.Location.create_ifcaxis2placement3D(ifcfile, dir1=direction) # Axis down
cylinder = ifcfile.createIfcRightCircularCylinder(placement, height, radius)
body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "CSG", [cylinder])
product_shape = ifcfile.createIfcProductDefinitionShape(f"{name}", None, [body_representation])
return product_shape

@classmethod
def create_cuboid_shape(cls, name: str, height: float, width: float, length: float):
height = -height
context = cls.get_context()
ifcfile = cls.get_file()
direction = (0., 0., 1.) if height >= 0. else (0., 0., -1.)
pos = (-width / 2, -length / 2, 0.) if height >= 0. else (-width / 2, length / 2, 0.)
placement = tool.Location.create_ifcaxis2placement3D(ifcfile, pos, dir1=direction) # Axis down
box = ifcfile.createIfcBlock(placement, width, length, abs(height))
body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "CSG", [box])
return ifcfile.createIfcProductDefinitionShape(f"{name}", None, [body_representation])

@classmethod
def create_rectangular_pyramid_shape(cls, name: str, height: float, width: float, legth: float):
direction = (0., 0., 1.) if height >= 0. else (0., 0., -1.)
ifcfile = cls.get_file()
context = cls.get_context()

pos = (-width / 2, -legth / 2, 0.) if height >= 0. else (-width / 2, legth / 2, -height)
placement = tool.Location.create_ifcaxis2placement3D(ifcfile, pos, dir1=direction) # Axis down
pyramid = ifcfile.createIfcRectangularPyramid(placement, width, legth, abs(height))
body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "CSG", [pyramid])
return ifcfile.createIfcProductDefinitionShape(f"{name}", None, [body_representation])
4 changes: 2 additions & 2 deletions boreholeCreator/tool/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def get_properties(cls) -> LocationProperties:
return boreholeCreator.LocationProperties

@classmethod
def create_ifcaxis2placement(cls,ifcfile, point=O, dir1=Z, dir2=X):
def create_ifcaxis2placement3D(cls, ifcfile, point=O, dir1=Z, dir2=X):
point = ifcfile.createIfcCartesianPoint(point)
dir1 = ifcfile.createIfcDirection(dir1)
dir2 = ifcfile.createIfcDirection(dir2)
Expand All @@ -37,7 +37,7 @@ def create_ifcaxis2placement(cls,ifcfile, point=O, dir1=Z, dir2=X):

@classmethod
def create_ifclocalplacement(cls,ifcfile, point=O, dir1=Z, dir2=X, relative_to=None):
axis2placement = cls.create_ifcaxis2placement(ifcfile, point, dir1, dir2)
axis2placement = cls.create_ifcaxis2placement3D(ifcfile, point, dir1, dir2)
ifclocalplacement2 = ifcfile.createIfcLocalPlacement(relative_to, axis2placement)
return ifclocalplacement2

Expand Down

0 comments on commit 104c4ad

Please sign in to comment.