mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
See #2999. Reimplement basic creation of structural items.
This commit is contained in:
@@ -286,6 +286,16 @@ def guess_type(items: Sequence[ifcopenshell.entity_instance]) -> Union[str, None
|
||||
return "SectionedSpine"
|
||||
elif all([True if i.is_a("IfcLightSource") else False for i in items]):
|
||||
return "LightSource"
|
||||
elif all([True if i.is_a("IfcVertex") else False for i in items]):
|
||||
return "Vertex"
|
||||
elif all([True if i.is_a("IfcEdge") else False for i in items]):
|
||||
return "Edge"
|
||||
elif all([True if i.is_a("IfcPath") else False for i in items]):
|
||||
return "Path"
|
||||
elif all([True if i.is_a("IfcFace") else False for i in items]):
|
||||
return "Face"
|
||||
elif all([True if i.is_a("IfcOpenShell") else False for i in items]):
|
||||
return "Shell"
|
||||
|
||||
|
||||
def resolve_representation(representation: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
|
||||
@@ -785,6 +785,41 @@ class ShapeBuilder:
|
||||
RefDirection=ref_direction,
|
||||
)
|
||||
|
||||
def vertex(self, position: VectorType = (0.0, 0.0, 0.0)) -> ifcopenshell.entity_instance:
|
||||
"""Create a topological vertex
|
||||
|
||||
Commonly used in structural point elements.
|
||||
|
||||
:param position: The 3D coordinate of the vertex
|
||||
:return: IfcVertexPoint
|
||||
"""
|
||||
return self.file.create_entity(
|
||||
"IfcVertexPoint", self.file.create_entity("IfcCartesianPoint", ifc_safe_vector_type(position))
|
||||
)
|
||||
|
||||
def edge(
|
||||
self, start: VectorType = (0.0, 0.0, 0.0), end: VectorType = (1.0, 0.0, 0.0)
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Create a topological edge
|
||||
|
||||
:param start: The start coordinates of the vertex.
|
||||
:param end: The end coordinates of the vertex.
|
||||
:return: IfcEdge
|
||||
"""
|
||||
return self.file.create_entity("IfcEdge", self.vertex(start), self.vertex(end))
|
||||
|
||||
def face(self, points: SequenceOfVectors) -> ifcopenshell.entity_instance:
|
||||
"""Create a single topological face
|
||||
|
||||
There are many types of faces, but for now we only support planar
|
||||
polyloop defined faces with an outer boundary.
|
||||
|
||||
:param points: ordered list of 3d coordinates representing the outer boundary
|
||||
:return: IfcFace
|
||||
"""
|
||||
verts = [self.file.createIfcCartesianPoint(p) for p in ifc_safe_vector_type(points)]
|
||||
return self.file.createIfcFace([self.file.createIfcFaceOuterBound(self.file.createIfcPolyLoop(verts), True)])
|
||||
|
||||
def mirror(
|
||||
self,
|
||||
curve_or_item: Union[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]],
|
||||
@@ -1025,13 +1060,17 @@ class ShapeBuilder:
|
||||
if not representation_type:
|
||||
representation_type = ifcopenshell.util.representation.guess_type(items)
|
||||
|
||||
representation = self.file.createIfcShapeRepresentation(
|
||||
return self.file.create_entity(
|
||||
(
|
||||
"IfcTopologyRepresentation"
|
||||
if representation_type in ("Vertex", "Edge", "Path", "Face", "Shell")
|
||||
else "IfcShapeRepresentation"
|
||||
),
|
||||
ContextOfItems=context,
|
||||
RepresentationIdentifier=context.ContextIdentifier,
|
||||
RepresentationType=representation_type,
|
||||
Items=items,
|
||||
)
|
||||
return representation
|
||||
|
||||
def deep_copy(self, element: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
return ifcopenshell.util.element.copy_deep(self.file, element)
|
||||
|
||||
@@ -203,6 +203,31 @@ class TestMirror(test.bootstrap.IFC4):
|
||||
assert np.allclose(rectangle.Points.CoordList, ((0.0, 0.0), (-100.0, 0.0), (-100.0, 100.0), (0.0, 100.0)))
|
||||
|
||||
|
||||
class TestVertex(test.bootstrap.IFC4):
|
||||
def test_run(self):
|
||||
builder = ShapeBuilder(self.file)
|
||||
vertex = builder.vertex((1, 2, 3))
|
||||
assert np.allclose(vertex.VertexGeometry.Coordinates, (1, 2, 3))
|
||||
|
||||
|
||||
class TestEdge(test.bootstrap.IFC4):
|
||||
def test_run(self):
|
||||
builder = ShapeBuilder(self.file)
|
||||
edge = builder.edge((1, 0, 0), (1, 2, 3))
|
||||
assert np.allclose(edge.EdgeStart.VertexGeometry.Coordinates, (1, 0, 0))
|
||||
assert np.allclose(edge.EdgeEnd.VertexGeometry.Coordinates, (1, 2, 3))
|
||||
|
||||
|
||||
class TestFace(test.bootstrap.IFC4):
|
||||
def test_run(self):
|
||||
builder = ShapeBuilder(self.file)
|
||||
face = builder.face(((0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)))
|
||||
assert np.allclose(face.Bounds[0].Bound.Polygon[0], (0, 0, 0))
|
||||
assert np.allclose(face.Bounds[0].Bound.Polygon[1], (1, 0, 0))
|
||||
assert np.allclose(face.Bounds[0].Bound.Polygon[2], (1, 1, 0))
|
||||
assert np.allclose(face.Bounds[0].Bound.Polygon[3], (0, 1, 0))
|
||||
|
||||
|
||||
class TestCalculateTransitions(test.bootstrap.IFC4):
|
||||
def calculate_and_test(self, params: dict[str, Any], length: Union[float, None]):
|
||||
np_X, np_Y = 0, 1
|
||||
|
||||
Reference in New Issue
Block a user