add 3d extent; check isDisplayable; ignore invalid IFC meshes

This commit is contained in:
KatKatKateryna
2024-10-30 17:35:04 +00:00
parent 396916bb7c
commit 63d2879709
3 changed files with 80 additions and 18 deletions
+4 -2
View File
@@ -144,6 +144,7 @@ class SpeckleProvider(BaseProvider):
self.limit_message = ""
self.extent = [-180,-90,180,90]
self.extent3d = [-180,-90,0,180,90,1000]
self.material_color_proxies = {}
@@ -420,6 +421,7 @@ class SpeckleProvider(BaseProvider):
speckle_data["model_last_version_date"] = datetime.strptime(commit['createdAt'].replace("T", " ").replace("Z","").split(".")[0], '%Y-%m-%d %H:%M:%S')
speckle_data["model_id"] = wrapper.model_id
speckle_data["extent"] = self.extent
speckle_data["extent3d"] = self.extent3d
speckle_data["limit_message"] = self.limit_message
return speckle_data
@@ -437,7 +439,7 @@ class SpeckleProvider(BaseProvider):
)
from pygeoapi.provider.speckle_utils.crs_utils import get_set_crs_settings
from pygeoapi.provider.speckle_utils.feature_utils import create_features
from pygeoapi.provider.speckle_utils.display_utils import set_default_color, get_material_color_proxies
from pygeoapi.provider.speckle_utils.display_utils import isDisplayable, set_default_color, get_material_color_proxies
supported_classes = [GisFeature, GisPolygonElement, Mesh, Brep, Point, Line, Polyline, Curve, Arc, Circle, Ellipse, Polycurve]
supported_types = [y().speckle_type for y in supported_classes]
@@ -472,7 +474,7 @@ class SpeckleProvider(BaseProvider):
and (isinstance(getattr(x, item, None), list) or ("grasshopper" in self.sourceApp.lower() and x.speckle_type == "Base") )
],
)
context_list = [x for x in GraphTraversal([rule]).traverse(commit_obj)]
context_list = [x for x in GraphTraversal([rule]).traverse(commit_obj) if isDisplayable(x.current)]
get_set_crs_settings(self, commit_obj, context_list, data)
@@ -55,7 +55,15 @@ def reproject_bulk(self, all_coords: List[List[List[float]]], all_coord_counts:
if geometry["type"] == "MultiPoint":
poly_part.extend([local_flat_coords[ind] for ind in range_coords_indices])
else:
poly_part.append([local_flat_coords[ind] for ind in range_coords_indices])
new_list = []
for ind in range_coords_indices:
try:
new_list.append(local_flat_coords[ind])
except Exception as e: # corrupted geometry, ignore altogether
new_list = []
break
if len(new_list)>0:
poly_part.append(new_list)
start_index += part_count
@@ -89,7 +97,9 @@ def reproject_2d_coords_list(self, coords_in: List[List[float]]) -> List[List[fl
all_x = [x[0] for x in transformed]
all_y = [x[1] for x in transformed]
all_z = [x[2] for x in transformed]
self.extent = [min(all_x), min(all_y), max(all_x), max(all_y)]
self.extent3d = [min(all_x), min(all_y), min(all_z), max(all_x), max(all_y), max(all_z)]
return transformed
def offset_rotate(self, coords_in: List[list]) -> List[List[float]]:
@@ -54,6 +54,7 @@ def separate_display_vals(displayValue: List) -> List[Tuple["Base"]]:
count = 0
all_count = len(item.faces)
sub_meshes = []
for _ in item.faces:
if count < all_count:
faces = []
@@ -61,33 +62,64 @@ def separate_display_vals(displayValue: List) -> List[Tuple["Base"]]:
colors = []
vert_num = item.faces[count]
if vert_num == 0:
vert_num = 3
elif vert_num == 1:
vert_num = 4
faces.append(vert_num)
faces.extend([ x for x in list(range(vert_num))])
for ind in range(vert_num):
face_vert_index = count+1+ind
vert_index = item.faces[face_vert_index]
try:
for ind in range(vert_num):
face_vert_index = count+1+ind
#print(face_vert_index)
vert_index = item.faces[face_vert_index]
new_vert = item.vertices[3*vert_index : 3*vert_index + 3]
verts.extend(new_vert)
new_vert = item.vertices[3*vert_index : 3*vert_index + 3]
verts.extend(new_vert)
if isinstance(item.colors, List) and len(item.colors) > vert_index:
color = item.colors[vert_index]
colors.append(color)
if isinstance(item.colors, List) and len(item.colors) > vert_index:
color = item.colors[vert_index]
colors.append(color)
count += vert_num+1
if len(colors)>0:
mesh = Mesh.create(faces= faces, vertices=verts, colors=colors)
else:
mesh = Mesh.create(faces= faces, vertices=verts)
sub_meshes.append((mesh, item))
count += vert_num+1
if len(colors)>0:
mesh = Mesh.create(faces= faces, vertices=verts, colors=colors)
else:
mesh = Mesh.create(faces= faces, vertices=verts)
display_objs.append((mesh, item))
except IndexError: # corrupted mesh, drop altogether
sub_meshes = []
break
display_objs.extend(sub_meshes)
elif item is not None:
display_objs.append((item, item))
return display_objs
def isDisplayable(obj: "Base") -> bool:
if is_primitive(obj):
return True
displayValue = None
if hasattr(obj, 'displayValue'):
displayValue = getattr(obj, 'displayValue')
elif hasattr(obj, '@displayValue'):
displayValue = getattr(obj, '@displayValue')
# merge to sigle object, if List
if isinstance(displayValue, List):
return True
return False
def find_display_obj(obj) -> Tuple["Base", "Base"]:
"""Get displayable object."""
@@ -121,11 +153,12 @@ def find_display_obj(obj) -> Tuple["Base", "Base"]:
def is_convertible(obj) -> bool:
"""Check if the object can be converted directly."""
from specklepy.objects.geometry import Base, Point, Line, Arc, Circle, Curve, Polycurve, Mesh, Brep
from specklepy.objects.geometry import Base, Point, Line, Polyline, Arc, Circle, Curve, Polycurve, Mesh, Brep
if ( (isinstance(obj, Base) and obj.speckle_type.endswith("Feature")) or
isinstance(obj, Point) or
isinstance(obj, Line) or
isinstance(obj, Polyline) or
isinstance(obj, Arc) or
isinstance(obj, Circle) or
isinstance(obj, Curve) or
@@ -135,6 +168,23 @@ def is_convertible(obj) -> bool:
return True
return False
def is_primitive(obj) -> bool:
"""Check if the object can be converted directly."""
from specklepy.objects.geometry import Polyline, Point, Line, Arc, Circle, Curve, Polycurve, Mesh, Brep
if (
isinstance(obj, Point) or
isinstance(obj, Line) or
isinstance(obj, Polyline) or
isinstance(obj, Arc) or
isinstance(obj, Circle) or
isinstance(obj, Curve) or
isinstance(obj, Mesh)
):
return True
return False
def get_single_display_object(displayValForColor: List) -> "Base":
"""Get a merged Mesh or a first item from displayValue list."""