mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
black .
This commit is contained in:
@@ -446,25 +446,25 @@ def get_horizontal_profile_preview_data(context, relating_type):
|
|||||||
# The first one is for the profile start, based on the current and previous segment of the polyline.
|
# The first one is for the profile start, based on the current and previous segment of the polyline.
|
||||||
# The second is for the profile end, based on the current and the next segment.
|
# The second is for the profile end, based on the current and the next segment.
|
||||||
if i == 0:
|
if i == 0:
|
||||||
d = (polyline_verts[i+1] - polyline_verts[i]).normalized()
|
d = (polyline_verts[i + 1] - polyline_verts[i]).normalized()
|
||||||
clip_start = d
|
clip_start = d
|
||||||
else:
|
else:
|
||||||
d1 = (polyline_verts[i] - polyline_verts[i-1]).normalized()
|
d1 = (polyline_verts[i] - polyline_verts[i - 1]).normalized()
|
||||||
d2 = (polyline_verts[i] - polyline_verts[i+1]).normalized()
|
d2 = (polyline_verts[i] - polyline_verts[i + 1]).normalized()
|
||||||
clip_start = (d1-d2).normalized()
|
clip_start = (d1 - d2).normalized()
|
||||||
|
|
||||||
if i == len(polyline_verts) - 2:
|
if i == len(polyline_verts) - 2:
|
||||||
d = (polyline_verts[i+1] - polyline_verts[i]).normalized()
|
d = (polyline_verts[i + 1] - polyline_verts[i]).normalized()
|
||||||
clip_end = d
|
clip_end = d
|
||||||
else:
|
else:
|
||||||
d1 = (polyline_verts[i+1] - polyline_verts[i]).normalized()
|
d1 = (polyline_verts[i + 1] - polyline_verts[i]).normalized()
|
||||||
d2 = (polyline_verts[i+1] - polyline_verts[i+2]).normalized()
|
d2 = (polyline_verts[i + 1] - polyline_verts[i + 2]).normalized()
|
||||||
clip_end = (d1-d2).normalized()
|
clip_end = (d1 - d2).normalized()
|
||||||
|
|
||||||
# Rotates the profile face to the right direction
|
# Rotates the profile face to the right direction
|
||||||
direction = polyline_verts[i+1] - polyline_verts[i]
|
direction = polyline_verts[i + 1] - polyline_verts[i]
|
||||||
position = polyline_verts[i]
|
position = polyline_verts[i]
|
||||||
rotation_matrix = direction.to_track_quat('Z', 'Y').to_matrix().to_4x4()
|
rotation_matrix = direction.to_track_quat("Z", "Y").to_matrix().to_4x4()
|
||||||
bmesh.ops.transform(bm, verts=bm.verts, matrix=rotation_matrix)
|
bmesh.ops.transform(bm, verts=bm.verts, matrix=rotation_matrix)
|
||||||
bmesh.ops.translate(bm, verts=bm.verts, vec=position)
|
bmesh.ops.translate(bm, verts=bm.verts, vec=position)
|
||||||
bmesh.ops.translate(bm, verts=bm.verts, vec=-direction)
|
bmesh.ops.translate(bm, verts=bm.verts, vec=-direction)
|
||||||
@@ -474,10 +474,22 @@ def get_horizontal_profile_preview_data(context, relating_type):
|
|||||||
new_verts = [e for e in last_face["geom"] if isinstance(e, bmesh.types.BMVert)]
|
new_verts = [e for e in last_face["geom"] if isinstance(e, bmesh.types.BMVert)]
|
||||||
bmesh.ops.translate(bm, verts=new_verts, vec=direction * 3)
|
bmesh.ops.translate(bm, verts=new_verts, vec=direction * 3)
|
||||||
# Apply the cutting planes
|
# Apply the cutting planes
|
||||||
cut = bmesh.ops.bisect_plane(bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:], plane_co=polyline_verts[i], plane_no=clip_start, clear_inner=True)
|
cut = bmesh.ops.bisect_plane(
|
||||||
|
bm,
|
||||||
|
geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
|
||||||
|
plane_co=polyline_verts[i],
|
||||||
|
plane_no=clip_start,
|
||||||
|
clear_inner=True,
|
||||||
|
)
|
||||||
bm.verts.index_update()
|
bm.verts.index_update()
|
||||||
bm.edges.index_update()
|
bm.edges.index_update()
|
||||||
cut = bmesh.ops.bisect_plane(bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:], plane_co=polyline_verts[i+1], plane_no=clip_end, clear_outer=True)
|
cut = bmesh.ops.bisect_plane(
|
||||||
|
bm,
|
||||||
|
geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
|
||||||
|
plane_co=polyline_verts[i + 1],
|
||||||
|
plane_no=clip_end,
|
||||||
|
clear_outer=True,
|
||||||
|
)
|
||||||
|
|
||||||
bm.to_mesh(mesh)
|
bm.to_mesh(mesh)
|
||||||
bm.free()
|
bm.free()
|
||||||
@@ -489,7 +501,7 @@ def get_horizontal_profile_preview_data(context, relating_type):
|
|||||||
mesh = bpy.data.meshes.new("TempMesh2")
|
mesh = bpy.data.meshes.new("TempMesh2")
|
||||||
all_bm.to_mesh(mesh)
|
all_bm.to_mesh(mesh)
|
||||||
all_bm.free()
|
all_bm.free()
|
||||||
obj = bpy.data.objects.new('TempObj', mesh)
|
obj = bpy.data.objects.new("TempObj", mesh)
|
||||||
bm = bmesh.new()
|
bm = bmesh.new()
|
||||||
bm.from_mesh(obj.data)
|
bm.from_mesh(obj.data)
|
||||||
bpy.data.meshes.remove(bpy.data.meshes["TempMesh2"])
|
bpy.data.meshes.remove(bpy.data.meshes["TempMesh2"])
|
||||||
@@ -639,21 +651,21 @@ class PolylineOperator:
|
|||||||
if x:
|
if x:
|
||||||
if event.shift and event.value == "PRESS" and event.type == "X":
|
if event.shift and event.value == "PRESS" and event.type == "X":
|
||||||
self.tool_state.use_default_container = False
|
self.tool_state.use_default_container = False
|
||||||
self.tool_state.plane_method = "YZ" if self.tool_state.plane_method !="YZ" else None
|
self.tool_state.plane_method = "YZ" if self.tool_state.plane_method != "YZ" else None
|
||||||
self.tool_state.axis_method = None
|
self.tool_state.axis_method = None
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
if y:
|
if y:
|
||||||
if event.shift and event.value == "PRESS" and event.type == "Y":
|
if event.shift and event.value == "PRESS" and event.type == "Y":
|
||||||
self.tool_state.use_default_container = False
|
self.tool_state.use_default_container = False
|
||||||
self.tool_state.plane_method = "XZ" if self.tool_state.plane_method !="XZ" else None
|
self.tool_state.plane_method = "XZ" if self.tool_state.plane_method != "XZ" else None
|
||||||
self.tool_state.axis_method = None
|
self.tool_state.axis_method = None
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
if z:
|
if z:
|
||||||
if event.shift and event.value == "PRESS" and event.type == "Z":
|
if event.shift and event.value == "PRESS" and event.type == "Z":
|
||||||
self.tool_state.use_default_container = False
|
self.tool_state.use_default_container = False
|
||||||
self.tool_state.plane_method = "XY" if self.tool_state.plane_method !="XY" else None
|
self.tool_state.plane_method = "XY" if self.tool_state.plane_method != "XY" else None
|
||||||
self.tool_state.axis_method = None
|
self.tool_state.axis_method = None
|
||||||
tool.Blender.update_viewport()
|
tool.Blender.update_viewport()
|
||||||
|
|
||||||
|
|||||||
@@ -112,10 +112,9 @@ class DumbProfileGenerator:
|
|||||||
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
|
matrix_world = Matrix.Rotation(pi / 2, 4, "Z") @ Matrix.Rotation(pi / 2, 4, "X") @ matrix_world
|
||||||
matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world
|
matrix_world = Matrix.Rotation(self.rotation, 4, "Z") @ matrix_world
|
||||||
else:
|
else:
|
||||||
rotation_matrix = self.direction.to_track_quat('Z', 'Y')
|
rotation_matrix = self.direction.to_track_quat("Z", "Y")
|
||||||
matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world
|
matrix_world = rotation_matrix.to_matrix().to_4x4() @ matrix_world
|
||||||
|
|
||||||
|
|
||||||
matrix_world.translation = self.location
|
matrix_world.translation = self.location
|
||||||
if self.insertion_type not in {"POLYLINE"} and self.container_obj:
|
if self.insertion_type not in {"POLYLINE"} and self.container_obj:
|
||||||
matrix_world.translation.z = self.container_obj.location.z
|
matrix_world.translation.z = self.container_obj.location.z
|
||||||
|
|||||||
@@ -523,11 +523,10 @@ class Polyline(bonsai.core.tool.Polyline):
|
|||||||
return "Cannot create two points at the same location"
|
return "Cannot create two points at the same location"
|
||||||
# Avoids creating overlapping edges
|
# Avoids creating overlapping edges
|
||||||
if len(polyline_points) > 1:
|
if len(polyline_points) > 1:
|
||||||
v1 = Vector((x, y, z))
|
v1 = Vector((x, y, z))
|
||||||
v2 = Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z))
|
v2 = Vector((polyline_points[-1].x, polyline_points[-1].y, polyline_points[-1].z))
|
||||||
v3 = Vector((polyline_points[-2].x, polyline_points[-2].y, polyline_points[-2].z))
|
v3 = Vector((polyline_points[-2].x, polyline_points[-2].y, polyline_points[-2].z))
|
||||||
angle = tool.Cad.angle_3_vectors(v1, v2, v3, new_angle=None, degrees=True
|
angle = tool.Cad.angle_3_vectors(v1, v2, v3, new_angle=None, degrees=True)
|
||||||
)
|
|
||||||
if tool.Cad.is_x(angle, 0):
|
if tool.Cad.is_x(angle, 0):
|
||||||
return
|
return
|
||||||
# TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool
|
# TODO move this limitation to be Wall tool specific. Right now it also affects Measure tool
|
||||||
|
|||||||
@@ -227,7 +227,6 @@ class Foo:
|
|||||||
else:
|
else:
|
||||||
ifcopenshell.api.geometry.assign_representation(self.file, product=wall, representation=rep)
|
ifcopenshell.api.geometry.assign_representation(self.file, product=wall, representation=rep)
|
||||||
|
|
||||||
|
|
||||||
def join(self, wall1, wall2, layers1, layers2, connection1, connection2):
|
def join(self, wall1, wall2, layers1, layers2, connection1, connection2):
|
||||||
if connection1 == "NOTDEFINED" or connection2 == "NOTDEFINED":
|
if connection1 == "NOTDEFINED" or connection2 == "NOTDEFINED":
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ def generate_vertices(rep_curve: entity_instance, distance_interval: float = 5.0
|
|||||||
raise ValueError("Alignment representation not found.")
|
raise ValueError("Alignment representation not found.")
|
||||||
|
|
||||||
s = ifcopenshell.geom.settings()
|
s = ifcopenshell.geom.settings()
|
||||||
s.set("piecewise-step-type",0) # 0 = step-size is maximum step size, 1 = step-size is mininimum number of steps
|
s.set("piecewise-step-type", 0) # 0 = step-size is maximum step size, 1 = step-size is mininimum number of steps
|
||||||
s.set("piecewise-step-size", distance_interval)
|
s.set("piecewise-step-size", distance_interval)
|
||||||
shape = ifcopenshell.geom.create_shape(s, rep_curve)
|
shape = ifcopenshell.geom.create_shape(s, rep_curve)
|
||||||
vertices = shape.verts
|
vertices = shape.verts
|
||||||
@@ -193,14 +193,14 @@ class IfcAlignmentHelper:
|
|||||||
expected_type = "IFCALIGNMENTVERTICALSEGMENT"
|
expected_type = "IFCALIGNMENTVERTICALSEGMENT"
|
||||||
if not segment_type == expected_type:
|
if not segment_type == expected_type:
|
||||||
raise TypeError(f"Expected to see type '{expected_type}', instead received '{segment_type}'.")
|
raise TypeError(f"Expected to see type '{expected_type}', instead received '{segment_type}'.")
|
||||||
|
|
||||||
start_distance_along = segment.StartDistAlong
|
start_distance_along = segment.StartDistAlong
|
||||||
horizontal_length = segment.HorizontalLength
|
horizontal_length = segment.HorizontalLength
|
||||||
start_height = segment.StartHeight
|
start_height = segment.StartHeight
|
||||||
start_gradient = segment.StartGradient
|
start_gradient = segment.StartGradient
|
||||||
end_gradient = segment.EndGradient
|
end_gradient = segment.EndGradient
|
||||||
radius_of_curvature = segment.RadiusOfCurvature
|
radius_of_curvature = segment.RadiusOfCurvature
|
||||||
|
|
||||||
if math.isclose(horizontal_length, 0):
|
if math.isclose(horizontal_length, 0):
|
||||||
# set transition value based on whether this is the final zero-length segment
|
# set transition value based on whether this is the final zero-length segment
|
||||||
transition = "DISCONTINUOUS"
|
transition = "DISCONTINUOUS"
|
||||||
@@ -213,23 +213,33 @@ class IfcAlignmentHelper:
|
|||||||
case "CONSTANTGRADIENT":
|
case "CONSTANTGRADIENT":
|
||||||
parent_curve = self._file.create_entity(
|
parent_curve = self._file.create_entity(
|
||||||
type="IfcLine",
|
type="IfcLine",
|
||||||
Pnt=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(0.0,0.0),),
|
Pnt=self._file.create_entity(
|
||||||
Dir=self._file.create_entity(type="IfcVector",
|
type="IfcCartesianPoint",
|
||||||
Orientation=self._file.create_entity(type="IfcDirection",DirectionRatios=(1.0,0.0),),
|
Coordinates=(0.0, 0.0),
|
||||||
Magnitude=1.0,),
|
),
|
||||||
)
|
Dir=self._file.create_entity(
|
||||||
|
type="IfcVector",
|
||||||
|
Orientation=self._file.create_entity(
|
||||||
|
type="IfcDirection",
|
||||||
|
DirectionRatios=(1.0, 0.0),
|
||||||
|
),
|
||||||
|
Magnitude=1.0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
dx = math.cos(math.atan(start_gradient))
|
dx = math.cos(math.atan(start_gradient))
|
||||||
dy = math.sin(math.atan(start_gradient))
|
dy = math.sin(math.atan(start_gradient))
|
||||||
curve_segment_length = horizontal_length/dx
|
curve_segment_length = horizontal_length / dx
|
||||||
|
|
||||||
curve_segment = self._file.create_entity(
|
curve_segment = self._file.create_entity(
|
||||||
type="IfcCurveSegment",
|
type="IfcCurveSegment",
|
||||||
Transition=transition,
|
Transition=transition,
|
||||||
Placement=self._file.create_entity(
|
Placement=self._file.create_entity(
|
||||||
type="IfcAxis2Placement2D",
|
type="IfcAxis2Placement2D",
|
||||||
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)),
|
Location=self._file.create_entity(
|
||||||
RefDirection=self._file.createIfcDirection((dx,dy)),
|
type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
|
||||||
|
),
|
||||||
|
RefDirection=self._file.createIfcDirection((dx, dy)),
|
||||||
),
|
),
|
||||||
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
||||||
SegmentLength=self._file.createIfcLengthMeasure(curve_segment_length),
|
SegmentLength=self._file.createIfcLengthMeasure(curve_segment_length),
|
||||||
@@ -240,30 +250,34 @@ class IfcAlignmentHelper:
|
|||||||
case "PARABOLICARC":
|
case "PARABOLICARC":
|
||||||
A = start_height
|
A = start_height
|
||||||
B = start_gradient
|
B = start_gradient
|
||||||
C = (end_gradient - start_gradient)/(2.0*horizontal_length)
|
C = (end_gradient - start_gradient) / (2.0 * horizontal_length)
|
||||||
|
|
||||||
parent_curve = self._file.create_entity(
|
parent_curve = self._file.create_entity(
|
||||||
type="IfcPolynomialCurve",
|
type="IfcPolynomialCurve",
|
||||||
Position=self._file.create_entity(
|
Position=self._file.create_entity(
|
||||||
type="IfcAxis2Placement2D",
|
type="IfcAxis2Placement2D",
|
||||||
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(0.0,0.0)),
|
Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)),
|
||||||
RefDirection=self._file.createIfcDirection((1.0, 0.0),),
|
RefDirection=self._file.createIfcDirection(
|
||||||
|
(1.0, 0.0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
CoefficientsX=(0.0,1.0),
|
CoefficientsX=(0.0, 1.0),
|
||||||
CoefficientsY=(A,B,C),
|
CoefficientsY=(A, B, C),
|
||||||
)
|
)
|
||||||
|
|
||||||
dx = math.cos(math.atan(start_gradient))
|
dx = math.cos(math.atan(start_gradient))
|
||||||
dy = math.sin(math.atan(start_gradient))
|
dy = math.sin(math.atan(start_gradient))
|
||||||
curve_segment_length = ifcopenshell_wrapper.polynomial_length(A,B,C,horizontal_length)
|
curve_segment_length = ifcopenshell_wrapper.polynomial_length(A, B, C, horizontal_length)
|
||||||
|
|
||||||
curve_segment = self._file.create_entity(
|
curve_segment = self._file.create_entity(
|
||||||
type="IfcCurveSegment",
|
type="IfcCurveSegment",
|
||||||
Transition=transition,
|
Transition=transition,
|
||||||
Placement=self._file.create_entity(
|
Placement=self._file.create_entity(
|
||||||
type="IfcAxis2Placement2D",
|
type="IfcAxis2Placement2D",
|
||||||
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)),
|
Location=self._file.create_entity(
|
||||||
RefDirection=self._file.createIfcDirection((dx,dy)),
|
type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
|
||||||
|
),
|
||||||
|
RefDirection=self._file.createIfcDirection((dx, dy)),
|
||||||
),
|
),
|
||||||
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
||||||
SegmentLength=self._file.createIfcLengthMeasure(curve_segment_length),
|
SegmentLength=self._file.createIfcLengthMeasure(curve_segment_length),
|
||||||
@@ -275,29 +289,34 @@ class IfcAlignmentHelper:
|
|||||||
start_angle = math.atan(start_gradient)
|
start_angle = math.atan(start_gradient)
|
||||||
end_angle = math.atan(end_gradient)
|
end_angle = math.atan(end_gradient)
|
||||||
if start_angle < end_angle:
|
if start_angle < end_angle:
|
||||||
radius = horizontal_length/(math.sin(end_angle) - math.sin(start_angle))
|
radius = horizontal_length / (math.sin(end_angle) - math.sin(start_angle))
|
||||||
else:
|
else:
|
||||||
radius = horizontal_length/(math.sin(start_angle) - math.sin(end_angle))
|
radius = horizontal_length / (math.sin(start_angle) - math.sin(end_angle))
|
||||||
|
|
||||||
parent_curve = self._file.create_entity(
|
parent_curve = self._file.create_entity(
|
||||||
type="IfcCircle",
|
type="IfcCircle",
|
||||||
Position=self._file.create_entity(
|
Position=self._file.create_entity(
|
||||||
type="IfcAxis2Placement2D",
|
type="IfcAxis2Placement2D",
|
||||||
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(0.0,0.0)),
|
Location=self._file.create_entity(type="IfcCartesianPoint", Coordinates=(0.0, 0.0)),
|
||||||
RefDirection=self._file.createIfcDirection((1.0, 0.0),),
|
RefDirection=self._file.createIfcDirection(
|
||||||
|
(1.0, 0.0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
Radius=radius,
|
Radius=radius,
|
||||||
)
|
)
|
||||||
|
|
||||||
segment_curve_length = radius*math.fabs(end_angle - start_angle)
|
segment_curve_length = radius * math.fabs(end_angle - start_angle)
|
||||||
|
|
||||||
curve_segment = self._file.create_entity(
|
curve_segment = self._file.create_entity(
|
||||||
type="IfcCurveSegment",
|
type="IfcCurveSegment",
|
||||||
Transition=transition,
|
Transition=transition,
|
||||||
Placement=self._file.create_entity(
|
Placement=self._file.create_entity(
|
||||||
type="IfcAxis2Placement2D",
|
type="IfcAxis2Placement2D",
|
||||||
Location=self._file.create_entity(type="IfcCartesianPoint",Coordinates=(start_distance_along,start_height)),
|
Location=self._file.create_entity(
|
||||||
RefDirection=self._file.createIfcDirection((1.0,0.0),
|
type="IfcCartesianPoint", Coordinates=(start_distance_along, start_height)
|
||||||
|
),
|
||||||
|
RefDirection=self._file.createIfcDirection(
|
||||||
|
(1.0, 0.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
SegmentStart=self._file.createIfcLengthMeasure(0.0),
|
||||||
@@ -676,7 +695,9 @@ class IfcAlignmentHelper:
|
|||||||
alignment.Representation = product_definition_shape
|
alignment.Representation = product_definition_shape
|
||||||
|
|
||||||
# create referent for start station
|
# create referent for start station
|
||||||
start_station_name = "Start Station ({})".format(ifcopenshell.util.stationing.station_as_string(start_station))
|
start_station_name = "Start Station ({})".format(
|
||||||
|
ifcopenshell.util.stationing.station_as_string(start_station)
|
||||||
|
)
|
||||||
start_referent = self._file.createIfcReferent(
|
start_referent = self._file.createIfcReferent(
|
||||||
GlobalId=ifcopenshell.guid.new(),
|
GlobalId=ifcopenshell.guid.new(),
|
||||||
OwnerHistory=None,
|
OwnerHistory=None,
|
||||||
@@ -698,8 +719,8 @@ class IfcAlignmentHelper:
|
|||||||
Representation=None,
|
Representation=None,
|
||||||
PredefinedType="STATION",
|
PredefinedType="STATION",
|
||||||
)
|
)
|
||||||
pset_stationing = ifcopenshell.api.pset.add_pset(self._file,product=start_referent,name="Pset_Stationing")
|
pset_stationing = ifcopenshell.api.pset.add_pset(self._file, product=start_referent, name="Pset_Stationing")
|
||||||
ifcopenshell.api.pset.edit_pset(self._file,pset=pset_stationing,properties={"Station":start_station})
|
ifcopenshell.api.pset.edit_pset(self._file, pset=pset_stationing, properties={"Station": start_station})
|
||||||
|
|
||||||
# nest the horizontal and the referent under the alignment
|
# nest the horizontal and the referent under the alignment
|
||||||
nesting_of_alignment = self._file.create_entity(
|
nesting_of_alignment = self._file.create_entity(
|
||||||
@@ -739,8 +760,8 @@ class IfcAlignmentHelper:
|
|||||||
@param vclengths: horizontal length of parabolic vertical curves
|
@param vclengths: horizontal length of parabolic vertical curves
|
||||||
@param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic
|
@param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic
|
||||||
"""
|
"""
|
||||||
vertical_segments = list() # business logic
|
vertical_segments = list() # business logic
|
||||||
vertical_curve_segments = list() # geometry
|
vertical_curve_segments = list() # geometry
|
||||||
xPBG, yPBG = vpoints[0]
|
xPBG, yPBG = vpoints[0]
|
||||||
xPVI, yPVI = vpoints[1]
|
xPVI, yPVI = vpoints[1]
|
||||||
i = 1
|
i = 1
|
||||||
@@ -748,20 +769,20 @@ class IfcAlignmentHelper:
|
|||||||
# back gradient
|
# back gradient
|
||||||
dxBG = xPVI - xPBG
|
dxBG = xPVI - xPBG
|
||||||
dyBG = yPVI - yPBG
|
dyBG = yPVI - yPBG
|
||||||
start_slope = math.tan(math.atan2(dyBG,dxBG))
|
start_slope = math.tan(math.atan2(dyBG, dxBG))
|
||||||
|
|
||||||
#forward gradient
|
# forward gradient
|
||||||
i += 1
|
i += 1
|
||||||
xPFG, yPFG = vpoints[i]
|
xPFG, yPFG = vpoints[i]
|
||||||
dxFG = xPFG - xPVI
|
dxFG = xPFG - xPVI
|
||||||
dyFG = yPFG - yPVI
|
dyFG = yPFG - yPVI
|
||||||
end_slope = math.tan(math.atan2(dyFG,dxFG))
|
end_slope = math.tan(math.atan2(dyFG, dxFG))
|
||||||
|
|
||||||
xEVC = xPVI + length/2.0
|
xEVC = xPVI + length / 2.0
|
||||||
yEVC = yPVI + end_slope * length/2.0
|
yEVC = yPVI + end_slope * length / 2.0
|
||||||
|
|
||||||
# create gradient
|
# create gradient
|
||||||
gradient_length = dxBG - length/2.0
|
gradient_length = dxBG - length / 2.0
|
||||||
design_parameters = self._file.create_entity(
|
design_parameters = self._file.create_entity(
|
||||||
type="IfcAlignmentVerticalSegment",
|
type="IfcAlignmentVerticalSegment",
|
||||||
StartTag=None,
|
StartTag=None,
|
||||||
@@ -772,7 +793,7 @@ class IfcAlignmentHelper:
|
|||||||
StartGradient=start_slope,
|
StartGradient=start_slope,
|
||||||
EndGradient=start_slope,
|
EndGradient=start_slope,
|
||||||
RadiusOfCurvature=None,
|
RadiusOfCurvature=None,
|
||||||
PredefinedType="CONSTANTGRADIENT"
|
PredefinedType="CONSTANTGRADIENT",
|
||||||
)
|
)
|
||||||
alignment_segment = self._file.create_entity(
|
alignment_segment = self._file.create_entity(
|
||||||
type="IfcAlignmentSegment",
|
type="IfcAlignmentSegment",
|
||||||
@@ -791,9 +812,9 @@ class IfcAlignmentHelper:
|
|||||||
vertical_curve_segments.append(self._map_alignment_vertical_segment(design_parameters)[0])
|
vertical_curve_segments.append(self._map_alignment_vertical_segment(design_parameters)[0])
|
||||||
|
|
||||||
# create vertical curve
|
# create vertical curve
|
||||||
k = (end_slope - start_slope)/length
|
k = (end_slope - start_slope) / length
|
||||||
xBVC = xPVI - length/2.0
|
xBVC = xPVI - length / 2.0
|
||||||
yBVC = yPVI - start_slope*length/2.0
|
yBVC = yPVI - start_slope * length / 2.0
|
||||||
|
|
||||||
design_parameters = self._file.create_entity(
|
design_parameters = self._file.create_entity(
|
||||||
type="IfcAlignmentVerticalSegment",
|
type="IfcAlignmentVerticalSegment",
|
||||||
@@ -804,8 +825,8 @@ class IfcAlignmentHelper:
|
|||||||
StartHeight=yBVC,
|
StartHeight=yBVC,
|
||||||
StartGradient=start_slope,
|
StartGradient=start_slope,
|
||||||
EndGradient=end_slope,
|
EndGradient=end_slope,
|
||||||
RadiusOfCurvature=1/k,
|
RadiusOfCurvature=1 / k,
|
||||||
PredefinedType="PARABOLICARC"
|
PredefinedType="PARABOLICARC",
|
||||||
)
|
)
|
||||||
alignment_segment = self._file.create_entity(
|
alignment_segment = self._file.create_entity(
|
||||||
type="IfcAlignmentSegment",
|
type="IfcAlignmentSegment",
|
||||||
@@ -821,7 +842,7 @@ class IfcAlignmentHelper:
|
|||||||
vertical_segments.append(alignment_segment)
|
vertical_segments.append(alignment_segment)
|
||||||
|
|
||||||
if include_geometry:
|
if include_geometry:
|
||||||
vertical_curve_segments.append(self._map_alignment_vertical_segment(design_parameters)[0])
|
vertical_curve_segments.append(self._map_alignment_vertical_segment(design_parameters)[0])
|
||||||
|
|
||||||
# start of next curve is end of this curve
|
# start of next curve is end of this curve
|
||||||
xPBG = xEVC
|
xPBG = xEVC
|
||||||
@@ -829,11 +850,10 @@ class IfcAlignmentHelper:
|
|||||||
xPVI = xPFG
|
xPVI = xPFG
|
||||||
yPVI = yPFG
|
yPVI = yPFG
|
||||||
|
|
||||||
|
|
||||||
# create last gradient run
|
# create last gradient run
|
||||||
dx = xPVI - xPBG
|
dx = xPVI - xPBG
|
||||||
dy = yPVI - yPBG
|
dy = yPVI - yPBG
|
||||||
slope = math.tan(math.atan2(dy,dx))
|
slope = math.tan(math.atan2(dy, dx))
|
||||||
gradient_length = dx
|
gradient_length = dx
|
||||||
|
|
||||||
design_parameters = self._file.create_entity(
|
design_parameters = self._file.create_entity(
|
||||||
@@ -846,7 +866,7 @@ class IfcAlignmentHelper:
|
|||||||
StartGradient=slope,
|
StartGradient=slope,
|
||||||
EndGradient=slope,
|
EndGradient=slope,
|
||||||
RadiusOfCurvature=None,
|
RadiusOfCurvature=None,
|
||||||
PredefinedType="CONSTANTGRADIENT"
|
PredefinedType="CONSTANTGRADIENT",
|
||||||
)
|
)
|
||||||
alignment_segment = self._file.create_entity(
|
alignment_segment = self._file.create_entity(
|
||||||
type="IfcAlignmentSegment",
|
type="IfcAlignmentSegment",
|
||||||
@@ -875,7 +895,7 @@ class IfcAlignmentHelper:
|
|||||||
StartGradient=slope,
|
StartGradient=slope,
|
||||||
EndGradient=slope,
|
EndGradient=slope,
|
||||||
RadiusOfCurvature=None,
|
RadiusOfCurvature=None,
|
||||||
PredefinedType="CONSTANTGRADIENT"
|
PredefinedType="CONSTANTGRADIENT",
|
||||||
)
|
)
|
||||||
alignment_segment = self._file.create_entity(
|
alignment_segment = self._file.create_entity(
|
||||||
type="IfcAlignmentSegment",
|
type="IfcAlignmentSegment",
|
||||||
@@ -899,10 +919,10 @@ class IfcAlignmentHelper:
|
|||||||
Segments=vertical_curve_segments,
|
Segments=vertical_curve_segments,
|
||||||
SelfIntersect=False,
|
SelfIntersect=False,
|
||||||
BaseCurve=composite_curve,
|
BaseCurve=composite_curve,
|
||||||
EndPoint=None
|
EndPoint=None,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
gradient_curve = None
|
gradient_curve = None
|
||||||
|
|
||||||
return vertical_segments, vertical_curve_segments, gradient_curve
|
return vertical_segments, vertical_curve_segments, gradient_curve
|
||||||
|
|
||||||
@@ -915,7 +935,7 @@ class IfcAlignmentHelper:
|
|||||||
lengths: Sequence[float],
|
lengths: Sequence[float],
|
||||||
alignment_description: str = None,
|
alignment_description: str = None,
|
||||||
start_station: float = 1000.0,
|
start_station: float = 1000.0,
|
||||||
include_geometry: bool = True
|
include_geometry: bool = True,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Create an alignment using the PI layout method for both horizontal and vertical alignments.
|
Create an alignment using the PI layout method for both horizontal and vertical alignments.
|
||||||
@@ -930,11 +950,15 @@ class IfcAlignmentHelper:
|
|||||||
@param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic
|
@param include_geometry: optionally create the alignment geometric representation as well as the semantic business logic
|
||||||
"""
|
"""
|
||||||
|
|
||||||
horizontal_segments, horizontal_curve_segments, composite_curve = self._create_horizontal_alignment(alignment_name,alignment_description,points,radii,include_geometry)
|
horizontal_segments, horizontal_curve_segments, composite_curve = self._create_horizontal_alignment(
|
||||||
vertical_segments, vertical_curve_segments, gradient_curve = self._create_vertical_alignment(composite_curve,vpoints,lengths)
|
alignment_name, alignment_description, points, radii, include_geometry
|
||||||
|
)
|
||||||
|
vertical_segments, vertical_curve_segments, gradient_curve = self._create_vertical_alignment(
|
||||||
|
composite_curve, vpoints, lengths
|
||||||
|
)
|
||||||
|
|
||||||
name_segments(prefix="H",segments=horizontal_segments)
|
name_segments(prefix="H", segments=horizontal_segments)
|
||||||
name_segments(prefix="V",segments=vertical_segments)
|
name_segments(prefix="V", segments=vertical_segments)
|
||||||
|
|
||||||
# Create the horizontal alignment (IfcAlignmentHorizontal) and nest alignment segments
|
# Create the horizontal alignment (IfcAlignmentHorizontal) and nest alignment segments
|
||||||
horizontal_alignment = self._file.create_entity(
|
horizontal_alignment = self._file.create_entity(
|
||||||
@@ -1021,8 +1045,8 @@ class IfcAlignmentHelper:
|
|||||||
Representation=None,
|
Representation=None,
|
||||||
PredefinedType="STATION",
|
PredefinedType="STATION",
|
||||||
)
|
)
|
||||||
pset_stationing = ifcopenshell.api.pset.add_pset(self._file,product=start_referent,name="Pset_Stationing")
|
pset_stationing = ifcopenshell.api.pset.add_pset(self._file, product=start_referent, name="Pset_Stationing")
|
||||||
ifcopenshell.api.pset.edit_pset(self._file,pset=pset_stationing,properties={"Station":start_station})
|
ifcopenshell.api.pset.edit_pset(self._file, pset=pset_stationing, properties={"Station": start_station})
|
||||||
|
|
||||||
# nest the horizontal, vertical and the referent under the alignment
|
# nest the horizontal, vertical and the referent under the alignment
|
||||||
nesting_of_alignment = self._file.create_entity(
|
nesting_of_alignment = self._file.create_entity(
|
||||||
@@ -1069,7 +1093,10 @@ class IfcAlignmentHelper:
|
|||||||
type="IfcProductDefinitionShape",
|
type="IfcProductDefinitionShape",
|
||||||
Name="Alignment Product Definition Shape",
|
Name="Alignment Product Definition Shape",
|
||||||
Description=None,
|
Description=None,
|
||||||
Representations=(footprint_shape_representation,axis3d_shape_representation,),
|
Representations=(
|
||||||
|
footprint_shape_representation,
|
||||||
|
axis3d_shape_representation,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# create representations for each segment
|
# create representations for each segment
|
||||||
@@ -1078,9 +1105,8 @@ class IfcAlignmentHelper:
|
|||||||
|
|
||||||
# add the representation to the alignment
|
# add the representation to the alignment
|
||||||
alignment.Representation = product_definition_shape
|
alignment.Representation = product_definition_shape
|
||||||
|
|
||||||
return alignment
|
|
||||||
|
|
||||||
|
return alignment
|
||||||
|
|
||||||
def create_horizontal_alignment_by_pi_method(
|
def create_horizontal_alignment_by_pi_method(
|
||||||
self,
|
self,
|
||||||
@@ -1112,18 +1138,16 @@ if __name__ == "__main__":
|
|||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
|
|
||||||
f = ifcopenshell.file(schema="IFC4X3_ADD2")
|
f = ifcopenshell.file(schema="IFC4X3_ADD2")
|
||||||
project = f.create_entity(type="IfcProject",GlobalId=ifcopenshell.guid.new())
|
project = f.create_entity(type="IfcProject", GlobalId=ifcopenshell.guid.new())
|
||||||
context = f.create_entity(type="IfcGeometricRepresentationContext")
|
context = f.create_entity(type="IfcGeometricRepresentationContext")
|
||||||
|
|
||||||
points=[(0.,0.),(100.,0.),(200.,150.)]
|
points = [(0.0, 0.0), (100.0, 0.0), (200.0, 150.0)]
|
||||||
radii=[(50.)]
|
radii = [50.0]
|
||||||
|
|
||||||
helper = IfcAlignmentHelper(f)
|
helper = IfcAlignmentHelper(f)
|
||||||
helper.create_horizontal_alignment_by_pi_method(
|
helper.create_horizontal_alignment_by_pi_method(name="MyAlignment", hpoints=points, radii=radii)
|
||||||
name="MyAlignment",hpoints = points,radii = radii
|
|
||||||
)
|
|
||||||
|
|
||||||
#f = ifcopenshell.open(sys.argv[1])
|
# f = ifcopenshell.open(sys.argv[1])
|
||||||
print_structure(f.by_type("IfcAlignment")[0])
|
print_structure(f.by_type("IfcAlignment")[0])
|
||||||
|
|
||||||
al_hor_rep = f.by_type("IfcCompositeCurve")[0]
|
al_hor_rep = f.by_type("IfcCompositeCurve")[0]
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
def station_as_string(station:float,plus_seperator=3,accuracy=3):
|
|
||||||
|
def station_as_string(station: float, plus_seperator=3, accuracy=3):
|
||||||
"""
|
"""
|
||||||
Returns a stringized version of a station. Example 100.0 is 1+00.00 as a stationing string
|
Returns a stringized version of a station. Example 100.0 is 1+00.00 as a stationing string
|
||||||
@param station: the station to be stringized
|
@param station: the station to be stringized
|
||||||
@@ -27,25 +28,23 @@ def station_as_string(station:float,plus_seperator=3,accuracy=3):
|
|||||||
"""
|
"""
|
||||||
value = math.fabs(station)
|
value = math.fabs(station)
|
||||||
|
|
||||||
shifter = math.pow(10.0,plus_seperator)
|
shifter = math.pow(10.0, plus_seperator)
|
||||||
v1 = math.floor(value/shifter)
|
v1 = math.floor(value / shifter)
|
||||||
v2 = value - v1*shifter
|
v2 = value - v1 * shifter
|
||||||
|
|
||||||
# Check to make sure that v2 is not basically the same as shifter
|
# Check to make sure that v2 is not basically the same as shifter
|
||||||
# If station = 69500.00000, we sometimes get 694+100.00 instead of 695+00.00
|
# If station = 69500.00000, we sometimes get 694+100.00 instead of 695+00.00
|
||||||
if math.isclose(v2-shifter,5.0*math.pow(10.0,-(accuracy+1))):
|
if math.isclose(v2 - shifter, 5.0 * math.pow(10.0, -(accuracy + 1))):
|
||||||
v2 = 0.0
|
v2 = 0.0
|
||||||
v1 += 1
|
v1 += 1
|
||||||
|
|
||||||
v1 = -1*v1 if station < 0 else v1
|
v1 = -1 * v1 if station < 0 else v1
|
||||||
|
|
||||||
station_string = "{:d}+{:0{}.{}f}".format(v1,v2,plus_seperator+accuracy+1,accuracy)
|
station_string = "{:d}+{:0{}.{}f}".format(v1, v2, plus_seperator + accuracy + 1, accuracy)
|
||||||
|
|
||||||
# special case when v1 is 0 and station is negative, the string above doesn't get the leading
|
# special case when v1 is 0 and station is negative, the string above doesn't get the leading
|
||||||
# negative sign. this snippet fixes that
|
# negative sign. this snippet fixes that
|
||||||
if v1 == 0 and station < 0:
|
if v1 == 0 and station < 0:
|
||||||
station_string = "-" + station_string
|
station_string = "-" + station_string
|
||||||
|
|
||||||
return station_string
|
return station_string
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ ENDSEC;
|
|||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_original_edges():
|
def test_original_edges():
|
||||||
ifc_file = ifcopenshell.file.from_string(contents)
|
ifc_file = ifcopenshell.file.from_string(contents)
|
||||||
element = ifc_file.by_id(95)
|
element = ifc_file.by_id(95)
|
||||||
@@ -92,6 +93,6 @@ def test_original_edges():
|
|||||||
assert (len(shape.edges) // 2) == 20
|
assert (len(shape.edges) // 2) == 20
|
||||||
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
|
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
|
||||||
assert (len(shape.edges) // 2) == 16
|
assert (len(shape.edges) // 2) == 16
|
||||||
settings.set('cgal-original-edges', True)
|
settings.set("cgal-original-edges", True)
|
||||||
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
|
shape = ifcopenshell.geom.create_shape(settings, element, geometry_library="cgal")
|
||||||
assert (len(shape.edges) // 2) == 20
|
assert (len(shape.edges) // 2) == 20
|
||||||
|
|||||||
@@ -18,28 +18,29 @@
|
|||||||
|
|
||||||
import ifcopenshell.util.stationing as sta
|
import ifcopenshell.util.stationing as sta
|
||||||
|
|
||||||
|
|
||||||
def test_station_as_string():
|
def test_station_as_string():
|
||||||
# test with a bunch of "random" station values
|
# test with a bunch of "random" station values
|
||||||
s = sta.station_as_string(0.0)
|
s = sta.station_as_string(0.0)
|
||||||
assert(s == "0+000.000")
|
assert s == "0+000.000"
|
||||||
|
|
||||||
s = sta.station_as_string(0.0,2,2)
|
s = sta.station_as_string(0.0, 2, 2)
|
||||||
assert(s == "0+00.00")
|
assert s == "0+00.00"
|
||||||
|
|
||||||
s = sta.station_as_string(0.0,2)
|
s = sta.station_as_string(0.0, 2)
|
||||||
assert(s == "0+00.000")
|
assert s == "0+00.000"
|
||||||
|
|
||||||
s = sta.station_as_string(100.00)
|
s = sta.station_as_string(100.00)
|
||||||
assert(s == "0+100.000")
|
assert s == "0+100.000"
|
||||||
|
|
||||||
s = sta.station_as_string(-100.00)
|
s = sta.station_as_string(-100.00)
|
||||||
assert(s == "-0+100.000")
|
assert s == "-0+100.000"
|
||||||
|
|
||||||
s = sta.station_as_string(123456.789,2,2)
|
s = sta.station_as_string(123456.789, 2, 2)
|
||||||
assert(s == "1234+56.79")
|
assert s == "1234+56.79"
|
||||||
|
|
||||||
s = sta.station_as_string(-123456.789,2,2)
|
s = sta.station_as_string(-123456.789, 2, 2)
|
||||||
assert(s == "-1234+56.79")
|
assert s == "-1234+56.79"
|
||||||
|
|
||||||
s = sta.station_as_string(123456.789,3,4)
|
s = sta.station_as_string(123456.789, 3, 4)
|
||||||
assert(s == "123+456.7890")
|
assert s == "123+456.7890"
|
||||||
|
|||||||
Reference in New Issue
Block a user