mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 01:47:55 +00:00
Support 2D axis representations, and curves from either mesh or curves
This commit is contained in:
@@ -1878,33 +1878,64 @@ class IfcExporter():
|
|||||||
def create_representation(self, representation):
|
def create_representation(self, representation):
|
||||||
self.ifc_vertices = []
|
self.ifc_vertices = []
|
||||||
self.ifc_edges = []
|
self.ifc_edges = []
|
||||||
if representation['is_generated'] \
|
if representation['context'] == 'Model':
|
||||||
and representation['subcontext'] == 'Box':
|
return self.create_model_representation(representation)
|
||||||
|
elif representation['context'] == 'Plan':
|
||||||
|
return self.create_plan_representation(representation)
|
||||||
|
elif representation['context'] == 'NotDefined':
|
||||||
|
return self.create_variable_representation(representation)
|
||||||
|
|
||||||
|
def create_model_representation(self, representation):
|
||||||
|
if representation['subcontext'] == 'Annotation':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'Axis':
|
||||||
|
return self.file.createIfcRepresentationMap(
|
||||||
|
self.origin, self.create_curve3d_axis_representation(representation))
|
||||||
|
elif representation['subcontext'] == 'Body':
|
||||||
|
return self.create_variable_representation(representation)
|
||||||
|
elif representation['subcontext'] == 'Box':
|
||||||
return self.file.createIfcRepresentationMap(self.origin,
|
return self.file.createIfcRepresentationMap(self.origin,
|
||||||
self.create_box_representation(representation))
|
self.create_box_representation(representation))
|
||||||
|
elif representation['subcontext'] == 'Clearance':
|
||||||
|
return self.create_variable_representation(representation)
|
||||||
elif representation['subcontext'] == 'CoG':
|
elif representation['subcontext'] == 'CoG':
|
||||||
return self.file.createIfcRepresentationMap(self.origin,
|
return self.file.createIfcRepresentationMap(self.origin,
|
||||||
self.create_cog_representation(representation))
|
self.create_cog_representation(representation))
|
||||||
elif representation['is_curve'] \
|
elif representation['subcontext'] == 'FootPrint':
|
||||||
and representation['context'] == 'Model' \
|
return self.create_variable_representation(representation)
|
||||||
and representation['subcontext'] == 'Axis' \
|
elif representation['subcontext'] == 'Reference':
|
||||||
and representation['target_view'] == 'GRAPH_VIEW':
|
if representation['target_view'] == 'GRAPH_VIEW':
|
||||||
return self.file.createIfcRepresentationMap(
|
return self.file.createIfcRepresentationMap(
|
||||||
self.origin, self.create_curve_axis_representation(representation))
|
self.origin, self.create_structural_reference_representation(representation))
|
||||||
elif representation['is_structural'] \
|
|
||||||
and representation['context'] == 'Model' \
|
|
||||||
and representation['subcontext'] == 'Reference' \
|
|
||||||
and representation['target_view'] == 'GRAPH_VIEW':
|
|
||||||
return self.file.createIfcRepresentationMap(
|
|
||||||
self.origin, self.create_structural_reference_representation(representation))
|
|
||||||
elif representation['context'] == 'Plan' \
|
|
||||||
or representation['subcontext'] == 'Axis' \
|
|
||||||
or representation['is_wireframe']:
|
|
||||||
return self.file.createIfcRepresentationMap(self.origin,
|
|
||||||
self.create_wireframe_representation(representation))
|
|
||||||
elif representation['subcontext'] == 'SurveyPoints':
|
elif representation['subcontext'] == 'SurveyPoints':
|
||||||
return self.file.createIfcRepresentationMap(self.origin,
|
return self.file.createIfcRepresentationMap(self.origin,
|
||||||
self.create_geometric_curve_set_representation(representation))
|
self.create_geometric_curve_set_representation(representation))
|
||||||
|
|
||||||
|
def create_plan_representation(self, representation):
|
||||||
|
if representation['subcontext'] == 'Annotation':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'Axis':
|
||||||
|
return self.file.createIfcRepresentationMap(
|
||||||
|
self.origin, self.create_curve2d_axis_representation(representation))
|
||||||
|
elif representation['subcontext'] == 'Body':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'Box':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'Clearance':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'CoG':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'FootPrint':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'Reference':
|
||||||
|
pass
|
||||||
|
elif representation['subcontext'] == 'SurveyPoints':
|
||||||
|
pass
|
||||||
|
|
||||||
|
def create_variable_representation(self, representation):
|
||||||
|
if representation['is_wireframe']:
|
||||||
|
return self.file.createIfcRepresentationMap(self.origin,
|
||||||
|
self.create_wireframe_representation(representation))
|
||||||
elif representation['is_curve']:
|
elif representation['is_curve']:
|
||||||
return self.file.createIfcRepresentationMap(self.origin,
|
return self.file.createIfcRepresentationMap(self.origin,
|
||||||
self.create_curve_representation(representation))
|
self.create_curve_representation(representation))
|
||||||
@@ -1946,35 +1977,15 @@ class IfcExporter():
|
|||||||
[cog])
|
[cog])
|
||||||
|
|
||||||
def create_wireframe_representation(self, representation):
|
def create_wireframe_representation(self, representation):
|
||||||
mesh = representation['raw']
|
|
||||||
self.create_vertices(mesh.vertices)
|
|
||||||
for edge in mesh.edges:
|
|
||||||
self.ifc_edges.append(self.file.createIfcPolyline([
|
|
||||||
self.ifc_vertices[v] for v in edge.vertices]))
|
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
representation['subcontext'],
|
representation['subcontext'],
|
||||||
'Curve',
|
'Curve',
|
||||||
self.ifc_edges)
|
self.create_curves(representation['raw']))
|
||||||
|
|
||||||
def create_geometric_curve_set_representation(self, representation):
|
def create_geometric_curve_set_representation(self, representation):
|
||||||
mesh = representation['raw']
|
geometric_curve_set = self.file.createIfcGeometricCurveSet(self.create_curves(representation['raw']))
|
||||||
self.create_vertices(mesh.vertices)
|
|
||||||
edges = list(mesh.edges)
|
|
||||||
loop_vertices = []
|
|
||||||
loops = []
|
|
||||||
# Not a fast algorithm, but easy
|
|
||||||
while edges:
|
|
||||||
for i, edge in enumerate(edges):
|
|
||||||
if edge.vertices[0] in loop_vertices \
|
|
||||||
and edge.vertices[1] in loop_vertices:
|
|
||||||
del edges[i]
|
|
||||||
loop_vertex_indices = self.get_loop_from_edges(edges)
|
|
||||||
loop_vertices.extend(loop_vertex_indices)
|
|
||||||
loops.append(self.file.createIfcPolyline([
|
|
||||||
self.ifc_vertices[i] for i in loop_vertex_indices]))
|
|
||||||
geometric_curve_set = self.file.createIfcGeometricCurveSet(loops)
|
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
@@ -1998,12 +2009,19 @@ class IfcExporter():
|
|||||||
# Find tangent and return.
|
# Find tangent and return.
|
||||||
return (pt1 - pt0) * usq3 + (pt2 - pt1) * ut6 + (pt3 - pt2) * tsq3
|
return (pt1 - pt0) * usq3 + (pt2 - pt1) * ut6 + (pt3 - pt2) * tsq3
|
||||||
|
|
||||||
def create_curve_axis_representation(self, representation):
|
def create_curve3d_axis_representation(self, representation):
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
representation['subcontext'], 'Curve3D',
|
representation['subcontext'], 'Curve3D',
|
||||||
[self.create_curve(representation['raw'])])
|
self.create_curves(representation['raw']))
|
||||||
|
|
||||||
|
def create_curve2d_axis_representation(self, representation):
|
||||||
|
return self.file.createIfcShapeRepresentation(
|
||||||
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
|
representation['target_view']]['ifc'],
|
||||||
|
representation['subcontext'], 'Curve2D',
|
||||||
|
self.create_curves(representation['raw'], is_2d=True))
|
||||||
|
|
||||||
def create_structural_reference_representation(self, representation):
|
def create_structural_reference_representation(self, representation):
|
||||||
if representation['raw_object'].type == 'EMPTY':
|
if representation['raw_object'].type == 'EMPTY':
|
||||||
@@ -2021,7 +2039,7 @@ class IfcExporter():
|
|||||||
def create_curve_representation(self, representation):
|
def create_curve_representation(self, representation):
|
||||||
# TODO: support unclosed surfaces
|
# TODO: support unclosed surfaces
|
||||||
swept_area = self.file.createIfcArbitraryClosedProfileDef('AREA', None,
|
swept_area = self.file.createIfcArbitraryClosedProfileDef('AREA', None,
|
||||||
self.create_curve(representation['raw'].bevel_object.data))
|
self.create_curves(representation['raw'].bevel_object.data)[0])
|
||||||
swept_area_solids = []
|
swept_area_solids = []
|
||||||
for spline in representation['raw'].splines:
|
for spline in representation['raw'].splines:
|
||||||
points = self.get_spline_points(spline)
|
points = self.get_spline_points(spline)
|
||||||
@@ -2052,7 +2070,7 @@ class IfcExporter():
|
|||||||
self.convert_si_to_unit(direction.length)))
|
self.convert_si_to_unit(direction.length)))
|
||||||
# TODO: support other types of swept areas
|
# TODO: support other types of swept areas
|
||||||
# swept_area_solid = self.file.createIfcFixedReferenceSweptAreaSolid(
|
# swept_area_solid = self.file.createIfcFixedReferenceSweptAreaSolid(
|
||||||
# swept_area, self.origin, self.create_curve(representation['raw']),
|
# swept_area, self.origin, # self.create_curves(representation['raw'])[0],
|
||||||
# 0., 1., self.file.createIfcDirection((0.0, -1.0, 0.0)))
|
# 0., 1., self.file.createIfcDirection((0.0, -1.0, 0.0)))
|
||||||
return self.file.createIfcShapeRepresentation(
|
return self.file.createIfcShapeRepresentation(
|
||||||
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
self.ifc_rep_context[representation['context']][representation['subcontext']][
|
||||||
@@ -2075,18 +2093,52 @@ class IfcExporter():
|
|||||||
self.create_vertex_point(points[0].co),
|
self.create_vertex_point(points[0].co),
|
||||||
self.create_vertex_point(points[1].co))
|
self.create_vertex_point(points[1].co))
|
||||||
|
|
||||||
def create_curve(self, curve):
|
def create_curves(self, curve, is_2d=False):
|
||||||
# TODO: support interpolated curves, not just polylines
|
if isinstance(curve, bpy.types.Mesh):
|
||||||
points = []
|
return self.create_curves_from_mesh(curve, is_2d=is_2d)
|
||||||
for point in curve.splines[0].bezier_points:
|
elif isinstance(curve, bpy.types.Curve):
|
||||||
points.append(self.create_cartesian_point(
|
return self.create_curves_from_curve(curve, is_2d=is_2d)
|
||||||
point.co.x, point.co.y, point.co.z))
|
|
||||||
for point in curve.splines[0].points:
|
def create_curves_from_mesh(self, mesh, is_2d=False):
|
||||||
points.append(self.create_cartesian_point(
|
self.create_vertices(mesh.vertices, is_2d=is_2d)
|
||||||
point.co.x, point.co.y, point.co.z))
|
edges = list(mesh.edges)
|
||||||
if curve.splines[0].use_cyclic_u:
|
loop_vertices = []
|
||||||
points.append(points[0])
|
loops = []
|
||||||
return self.file.createIfcPolyline(points)
|
# Not a fast algorithm, but easy
|
||||||
|
while edges:
|
||||||
|
for i, edge in enumerate(edges):
|
||||||
|
if edge.vertices[0] in loop_vertices \
|
||||||
|
and edge.vertices[1] in loop_vertices:
|
||||||
|
del edges[i]
|
||||||
|
loop_vertex_indices = self.get_loop_from_edges(edges)
|
||||||
|
loop_vertices.extend(loop_vertex_indices)
|
||||||
|
loops.append(self.file.createIfcPolyline([
|
||||||
|
self.ifc_vertices[i] for i in loop_vertex_indices]))
|
||||||
|
return loops
|
||||||
|
|
||||||
|
def create_curves_from_curve(self, curve, is_2d=False):
|
||||||
|
results = []
|
||||||
|
for spline in curve.splines:
|
||||||
|
# TODO: support interpolated curves, not just polylines
|
||||||
|
points = []
|
||||||
|
for point in spline.bezier_points:
|
||||||
|
if is_2d:
|
||||||
|
points.append(self.create_cartesian_point(
|
||||||
|
point.co.x, point.co.y))
|
||||||
|
else:
|
||||||
|
points.append(self.create_cartesian_point(
|
||||||
|
point.co.x, point.co.y, point.co.z))
|
||||||
|
for point in spline.points:
|
||||||
|
if is_2d:
|
||||||
|
points.append(self.create_cartesian_point(
|
||||||
|
point.co.x, point.co.y))
|
||||||
|
else:
|
||||||
|
points.append(self.create_cartesian_point(
|
||||||
|
point.co.x, point.co.y, point.co.z))
|
||||||
|
if spline.use_cyclic_u:
|
||||||
|
points.append(points[0])
|
||||||
|
results.append(self.file.createIfcPolyline(points))
|
||||||
|
return results
|
||||||
|
|
||||||
def create_swept_solid_representation(self, representation):
|
def create_swept_solid_representation(self, representation):
|
||||||
obj = representation['raw_object']
|
obj = representation['raw_object']
|
||||||
@@ -2246,10 +2298,15 @@ class IfcExporter():
|
|||||||
representation['target_view']]['ifc'],
|
representation['target_view']]['ifc'],
|
||||||
representation['subcontext'], 'Brep', items)
|
representation['subcontext'], 'Brep', items)
|
||||||
|
|
||||||
def create_vertices(self, vertices):
|
def create_vertices(self, vertices, is_2d=False):
|
||||||
self.ifc_vertices.extend(
|
if is_2d:
|
||||||
[self.file.createIfcCartesianPoint(self.convert_si_to_unit(v.co)) for v in vertices]
|
for v in vertices:
|
||||||
)
|
co = self.convert_si_to_unit(v.co)
|
||||||
|
self.ifc_vertices.append(self.file.createIfcCartesianPoint((co[0], co[1])))
|
||||||
|
else:
|
||||||
|
self.ifc_vertices.extend(
|
||||||
|
[self.file.createIfcCartesianPoint(self.convert_si_to_unit(v.co)) for v in vertices]
|
||||||
|
)
|
||||||
|
|
||||||
def create_cartesian_point(self, x, y, z=None):
|
def create_cartesian_point(self, x, y, z=None):
|
||||||
x = self.convert_si_to_unit(x)
|
x = self.convert_si_to_unit(x)
|
||||||
@@ -2441,7 +2498,7 @@ class IfcExportSettings:
|
|||||||
self.has_representations = True
|
self.has_representations = True
|
||||||
self.has_quantities = True
|
self.has_quantities = True
|
||||||
self.contexts = ['Model', 'Plan']
|
self.contexts = ['Model', 'Plan']
|
||||||
self.subcontexts = ['Axis', 'FootPrint', 'Reference', 'Body', 'Clearance', 'CoG', 'SurveyPoints']
|
self.subcontexts = ['Annotation', 'Axis', 'Box', 'FootPrint', 'Reference', 'Body', 'Clearance', 'CoG', 'SurveyPoints']
|
||||||
self.generated_subcontexts = ['Box']
|
self.generated_subcontexts = ['Box']
|
||||||
self.target_views = ['GRAPH_VIEW', 'SKETCH_VIEW', 'MODEL_VIEW', 'PLAN_VIEW', 'REFLECTED_PLAN_VIEW',
|
self.target_views = ['GRAPH_VIEW', 'SKETCH_VIEW', 'MODEL_VIEW', 'PLAN_VIEW', 'REFLECTED_PLAN_VIEW',
|
||||||
'SECTION_VIEW', 'ELEVATION_VIEW', 'USERDEFINED', 'NOTDEFINED']
|
'SECTION_VIEW', 'ELEVATION_VIEW', 'USERDEFINED', 'NOTDEFINED']
|
||||||
|
|||||||
@@ -375,7 +375,6 @@ class BIM_PT_mesh(Panel):
|
|||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'is_parametric')
|
row.prop(props, 'is_parametric')
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'is_wireframe')
|
row.prop(props, 'is_wireframe')
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|||||||
Reference in New Issue
Block a user