Skip to content

Commit

Permalink
Bug fixed in native BSpline terrain method
Browse files Browse the repository at this point in the history
  • Loading branch information
cvillagrasa committed May 10, 2023
1 parent 64a8bd0 commit 5dfbbef
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 23 deletions.
32 changes: 12 additions & 20 deletions IfcOpenHouse/ios_utils.py
Expand Up @@ -186,7 +186,7 @@ def info(self) -> dict[str, float | dict[str, float | str | None]]:

class TerrainBuildMethod(Enum):
NONE = auto()
NATIVE_BSPLINE = auto() # fancy NURBS surface not supported in the majority of IFC viewers
NATIVE_BSPLINE = auto() # fancy NURBS surface not supported in the some IFC viewers
TESSELATE_OCC_SHAPE = auto() # needs Open Cascade "mamba install -c conda-forge pythonocc-core"


Expand All @@ -199,12 +199,11 @@ def build_native_bspline_terrain(
file.create_entity('IfcCartesianPoint', Coordinates=coord) for coord in row
] for row in terrain_control_points
]
max_i, max_j = len(terrain_control_points[0]) - 1, len(terrain_control_points) - 1
cpoints_curve = {
'west': [coord for i, row in enumerate(terrain_control_point_list) for coord in row if i == 0],
'east': [coord for i, row in enumerate(terrain_control_point_list) for coord in row if i == max_i],
'south': [coord for row in terrain_control_point_list for j, coord in enumerate(row) if j == 0],
'north': [coord for row in terrain_control_point_list for j, coord in enumerate(row) if j == max_j]
'west': terrain_control_point_list[0],
'east': terrain_control_point_list[-1],
'south': [row[0] for row in terrain_control_point_list],
'north': [row[-1] for row in terrain_control_point_list]
}
spline_surface = file.create_entity(
'IfcBSplineSurfaceWithKnots', UDegree=degree, VDegree=degree,
Expand All @@ -221,10 +220,7 @@ def build_native_bspline_terrain(
) for side, curve in cpoints_curve.items()
}
edge_curve_end_indices = {
'south': ([0, 0], [max_i, 0]),
'north': ([0, max_j], [0, max_j]),
'west': ([0, 0], [0, max_j]),
'east': ([max_i, 0], [max_i, max_j])
'south': ([0, 0], [-1, 0]), 'north': ([0, -1], [-1, -1]), 'west': ([0, 0], [0, -1]), 'east': ([-1, 0], [-1, -1])
}
edge_curve_ends = {
side: [
Expand All @@ -240,19 +236,15 @@ def build_native_bspline_terrain(
) for side, edge_curve_geometry in edge_curve_geometries.items()
}
oriented_edges = {
side: file.create_entity('IfcOrientedEdge', EdgeElement=edge_curve, Orientation=True)
side: file.create_entity('IfcOrientedEdge', EdgeElement=edge_curve, Orientation=side in ('west', 'north'))
for side, edge_curve in edge_curves.items()
}
edge_loops = {
side: file.create_entity('IfcEdgeLoop', EdgeList=[oriented_edge])
for side, oriented_edge in oriented_edges.items()
}
bounds = {
side: file.create_entity('IfcFaceOuterBound', Bound=edge_loop, Orientation=True)
for side, edge_loop in edge_loops.items()
}
edge_loop = file.create_entity(
'IfcEdgeLoop', EdgeList=[oriented_edges[side] for side in ('west', 'north', 'east', 'south')]
)
bound = file.create_entity('IfcFaceOuterBound', Bound=edge_loop, Orientation=True)
advanced_face = file.create_entity(
'IfcAdvancedFace', Bounds=list(bounds.values()), FaceSurface=spline_surface, SameSense=True
'IfcAdvancedFace', Bounds=[bound], FaceSurface=spline_surface, SameSense=True
)
closed_shell = file.create_entity('IfcClosedShell', CfsFaces=[advanced_face])
advanced_brep = file.create_entity('IfcAdvancedBrep', Outer=closed_shell)
Expand Down
6 changes: 3 additions & 3 deletions nbs/00_generation.ipynb
Expand Up @@ -477,8 +477,8 @@
"text/plain": [
"{'id': 41,\n",
" 'type': 'IfcWall',\n",
" 'GlobalId': '3$OFqnmlfFy8SUn2Pdp188',\n",
" 'OwnerHistory': #40=IfcOwnerHistory(#19,#16,.READWRITE.,.ADDED.,1683534741,#19,#16,1683534741),\n",
" 'GlobalId': '3RQCBL94n6MP25zS7s5mmU',\n",
" 'OwnerHistory': #40=IfcOwnerHistory(#19,#16,.READWRITE.,.ADDED.,1683711969,#19,#16,1683711969),\n",
" 'Name': 'South wall',\n",
" 'Description': None,\n",
" 'ObjectType': None,\n",
Expand Down Expand Up @@ -950,7 +950,7 @@
"* `TerrainBuildMethod.TESSELATE_OCC_SHAPE`: Construct the shape in Open Cascade and tesselate it with the help of IfcOpenShell 🐚.\n",
"* `TerrainBuildMethod.NONE`: You may also safely skip the terrain part.\n",
"\n",
"The terrain with a fancy NURBS surface may be challenging to be correctly displayed within most IFC viewers. On the other hand, the tesselation method was followed on the original IfcOpenHouse for IFC2x3, but note that it requires the installation of Open Cascade (`pythonocc-core` package 📦).\n",
"The terrain with a fancy NURBS surface may be challenging to be correctly displayed within some IFC viewers. On the other hand, the tesselation method was followed on the original IfcOpenHouse for IFC2x3, but note that it requires the installation of Open Cascade (`pythonocc-core` package 📦).\n",
"\n",
"* **CURIOUS NOTE** 👉 The tesselation method will create an [IfcOpenShell entity](https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcOpenShell.htm) with the IfcOpenShell library! 🐚🐚🐚\n",
"\n",
Expand Down

0 comments on commit 5dfbbef

Please sign in to comment.