black ifc2ca

This commit is contained in:
htlcnn
2020-11-01 19:23:03 +07:00
committed by Dion Moult
parent c14f5eeca0
commit d6881e833d
4 changed files with 1104 additions and 912 deletions
+297 -141
View File
@@ -2,6 +2,7 @@ import json
import ifcopenshell
import os
class CA2IFC:
def __init__(self, inputFilename, outputFilename):
self.inputFilename = inputFilename
@@ -30,7 +31,7 @@ class CA2IFC:
localPlacement = self.f.createIfcLocalPlacement(None, globalAxes)
# TODO: create units
lengthUnit = self.f.createIfcSIUnit(None, 'LENGTHUNIT', None, 'METRE')
lengthUnit = self.f.createIfcSIUnit(None, "LENGTHUNIT", None, "METRE")
unitAssignment = self.f.createIfcUnitAssignment((lengthUnit,))
# create owner history
@@ -40,132 +41,246 @@ class CA2IFC:
self.reps = self.create_reference_subrep(globalAxes)
# create project and model
project = self.f.createIfcProject(self.guid(), ownerHistory, 'A Project', None, None, None, None, (self.reps['model'],), unitAssignment)
model = self.f.createIfcStructuralAnalysisModel(self.guid(), ownerHistory, self.data['name'], None, None, 'NOTDEFINED', globalAxes, None, None, localPlacement)
project = self.f.createIfcProject(
self.guid(), ownerHistory, "A Project", None, None, None, None, (self.reps["model"],), unitAssignment
)
model = self.f.createIfcStructuralAnalysisModel(
self.guid(),
ownerHistory,
self.data["name"],
None,
None,
"NOTDEFINED",
globalAxes,
None,
None,
localPlacement,
)
self.f.createIfcRelDeclares(self.guid(), ownerHistory, None, None, project, (model,))
# create materials
ifcMaterials = [None for _ in range(len(self.data['db']['materials']))]
for i,material in enumerate(self.data['db']['materials']):
ifcMaterials = [None for _ in range(len(self.data["db"]["materials"]))]
for i, material in enumerate(self.data["db"]["materials"]):
ifcMaterials[i] = self.create_material(material)
# create profiles
ifcProfiles = [None for _ in range(len(self.data['db']['profiles']))]
for i,profile in enumerate(self.data['db']['profiles']):
ifcProfiles = [None for _ in range(len(self.data["db"]["profiles"]))]
for i, profile in enumerate(self.data["db"]["profiles"]):
ifcProfiles[i] = self.create_profile(profile)
# create material-profile sets
mpSets = list(set([el['material'] + '-' + el['profile'] for el in self.data['elements'] if el['geometryType'] == 'line']))
mpSets = list(
set([el["material"] + "-" + el["profile"] for el in self.data["elements"] if el["geometryType"] == "line"])
)
ifcMaterialProfileSets = [None for _ in range(len(mpSets))]
for i,mpSet in enumerate(mpSets):
materialIndex = [mat['ifcName'] for mat in self.data['db']['materials']].index(mpSet.split('-')[0])
profileIndex = [prof['ifcName'] for prof in self.data['db']['profiles']].index(mpSet.split('-')[1])
for i, mpSet in enumerate(mpSets):
materialIndex = [mat["ifcName"] for mat in self.data["db"]["materials"]].index(mpSet.split("-")[0])
profileIndex = [prof["ifcName"] for prof in self.data["db"]["profiles"]].index(mpSet.split("-")[1])
material = ifcMaterials[materialIndex]
profile = ifcProfiles[profileIndex]
matProf = self.f.createIfcMaterialProfile(self.data['db']['materials'][materialIndex]['name'] + ' | ' + self.data['db']['profiles'][profileIndex]['profileName'], None, material, profile)
matProf = self.f.createIfcMaterialProfile(
self.data["db"]["materials"][materialIndex]["name"]
+ " | "
+ self.data["db"]["profiles"][profileIndex]["profileName"],
None,
material,
profile,
)
ifcMaterialProfileSets[i] = self.f.createIfcMaterialProfileSet(None, None, (matProf,))
# create structural elements
ifcElements = [None for _ in range(len(self.data['elements']))]
for i,el in enumerate(self.data['elements']):
ifcElements = [None for _ in range(len(self.data["elements"]))]
for i, el in enumerate(self.data["elements"]):
# geometry - product definition shape
prodDefShape = self.create_geometry(el)
if el['geometryType'] == 'line':
if el["geometryType"] == "line":
# z axis TODO: group by elements
localZAxis = self.f.createIfcDirection(tuple(el['orientation'][2]))
localZAxis = self.f.createIfcDirection(tuple(el["orientation"][2]))
# element
ifcElements[i] = self.f.createIfcStructuralCurveMember(self.guid(), ownerHistory, el['name'], None, None, localPlacement, prodDefShape, el['predefinedType'], localZAxis)
ifcElements[i] = self.f.createIfcStructuralCurveMember(
self.guid(),
ownerHistory,
el["name"],
None,
None,
localPlacement,
prodDefShape,
el["predefinedType"],
localZAxis,
)
if el['geometryType'] == 'surface':
ifcElements[i] = self.f.createIfcStructuralSurfaceMember(self.guid(), ownerHistory, el['name'], None, None, localPlacement, prodDefShape, el['predefinedType'], el['thickness'])
if el["geometryType"] == "surface":
ifcElements[i] = self.f.createIfcStructuralSurfaceMember(
self.guid(),
ownerHistory,
el["name"],
None,
None,
localPlacement,
prodDefShape,
el["predefinedType"],
el["thickness"],
)
# create structural point connections
ifcConnections = [None for _ in range(len(self.data['connections']))]
for i,conn in enumerate(self.data['connections']):
ifcConnections = [None for _ in range(len(self.data["connections"]))]
for i, conn in enumerate(self.data["connections"]):
# geometry - product definition shape
prodDefShape = self.create_geometry(conn)
# boundary conditions
if conn['appliedCondition']:
bc = self.create_applied_conditions(conn['appliedCondition'], conn['geometryType'])
if conn['geometryType'] == 'point':
appliedCondition = self.f.createIfcBoundaryNodeCondition(None, bc['dx'], bc['dy'], bc['dz'], bc['drx'], bc['dry'], bc['drz'])
if conn['geometryType'] == 'line':
appliedCondition = self.f.createIfcBoundaryEdgeCondition(None, bc['dx'], bc['dy'], bc['dz'], bc['drx'], bc['dry'], bc['drz'])
if conn['geometryType'] == 'surface':
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc['dx'], bc['dy'], bc['dz'])
if conn["appliedCondition"]:
bc = self.create_applied_conditions(conn["appliedCondition"], conn["geometryType"])
if conn["geometryType"] == "point":
appliedCondition = self.f.createIfcBoundaryNodeCondition(
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
)
if conn["geometryType"] == "line":
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
)
if conn["geometryType"] == "surface":
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
else:
appliedCondition = None
if conn['geometryType'] == 'point':
if conn["geometryType"] == "point":
# local axes
localAxes = self.create_orientation(conn['orientation'])
localAxes = self.create_orientation(conn["orientation"])
# connection
ifcConnections[i] = self.f.createIfcStructuralPointConnection(self.guid(), ownerHistory, conn['name'], None, None, localPlacement, prodDefShape, appliedCondition, localAxes)
ifcConnections[i] = self.f.createIfcStructuralPointConnection(
self.guid(),
ownerHistory,
conn["name"],
None,
None,
localPlacement,
prodDefShape,
appliedCondition,
localAxes,
)
if conn['geometryType'] == 'line':
if conn["geometryType"] == "line":
# z axis TODO: group by elements
localZAxis = self.f.createIfcDirection(tuple(conn['orientation'][2]))
localZAxis = self.f.createIfcDirection(tuple(conn["orientation"][2]))
# connection
ifcConnections[i] = self.f.createIfcStructuralCurveConnection(self.guid(), ownerHistory, conn['name'], None, None, localPlacement, prodDefShape, appliedCondition, localZAxis)
ifcConnections[i] = self.f.createIfcStructuralCurveConnection(
self.guid(),
ownerHistory,
conn["name"],
None,
None,
localPlacement,
prodDefShape,
appliedCondition,
localZAxis,
)
if conn['geometryType'] == 'surface':
ifcConnections[i] = self.f.createIfcStructuralSurfaceConnection(self.guid(), ownerHistory, conn['name'], None, None, localPlacement, prodDefShape, appliedCondition)
if conn["geometryType"] == "surface":
ifcConnections[i] = self.f.createIfcStructuralSurfaceConnection(
self.guid(), ownerHistory, conn["name"], None, None, localPlacement, prodDefShape, appliedCondition
)
# assign material-profile-sets
for i,mpSet in enumerate(mpSets):
for i, mpSet in enumerate(mpSets):
groupOfElements = []
for j,el in enumerate(self.data['elements']):
if el['geometryType'] == 'line' and el['material'] + '-' + el['profile'] == mpSet:
for j, el in enumerate(self.data["elements"]):
if el["geometryType"] == "line" and el["material"] + "-" + el["profile"] == mpSet:
groupOfElements.append(ifcElements[j])
if groupOfElements:
self.f.createIfcRelAssociatesMaterial(self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterialProfileSets[i])
self.f.createIfcRelAssociatesMaterial(
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterialProfileSets[i]
)
# assign materials
for i,mat in enumerate(self.data['db']['materials']):
for i, mat in enumerate(self.data["db"]["materials"]):
groupOfElements = []
for j,el in enumerate(self.data['elements']):
if el['geometryType'] == 'surface' and el['material'] == mat['ifcName']:
for j, el in enumerate(self.data["elements"]):
if el["geometryType"] == "surface" and el["material"] == mat["ifcName"]:
groupOfElements.append(ifcElements[j])
if groupOfElements:
self.f.createIfcRelAssociatesMaterial(self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterials[i])
self.f.createIfcRelAssociatesMaterial(
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterials[i]
)
# create connections with elements
for i,el in enumerate(self.data['elements']):
for conn in el['connections']:
j = [c['ifcName'] for c in self.data['connections']].index(conn['relatedConnection'])
geometryType = self.data['connections'][j]['geometryType']
for i, el in enumerate(self.data["elements"]):
for conn in el["connections"]:
j = [c["ifcName"] for c in self.data["connections"]].index(conn["relatedConnection"])
geometryType = self.data["connections"][j]["geometryType"]
if conn['appliedCondition']:
bc = self.create_applied_conditions(conn['appliedCondition'], geometryType)
if geometryType == 'point':
appliedCondition = self.f.createIfcBoundaryNodeCondition(None, bc['dx'], bc['dy'], bc['dz'], bc['drx'], bc['dry'], bc['drz'])
if geometryType == 'line':
appliedCondition = self.f.createIfcBoundaryEdgeCondition(None, bc['dx'], bc['dy'], bc['dz'], bc['drx'], bc['dry'], bc['drz'])
if geometryType == 'surface':
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc['dx'], bc['dy'], bc['dz'])
if conn["appliedCondition"]:
bc = self.create_applied_conditions(conn["appliedCondition"], geometryType)
if geometryType == "point":
appliedCondition = self.f.createIfcBoundaryNodeCondition(
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
)
if geometryType == "line":
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
)
if geometryType == "surface":
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
else:
appliedCondition = None
# local axes
localAxes = self.create_orientation(conn['orientation'])
localAxes = self.create_orientation(conn["orientation"])
if geometryType == 'point':
if not conn['eccentricity']:
self.f.createIfcRelConnectsStructuralMember(self.guid(), ownerHistory, None, None, ifcElements[i], ifcConnections[j], appliedCondition, None, None, localAxes)
if geometryType == "point":
if not conn["eccentricity"]:
self.f.createIfcRelConnectsStructuralMember(
self.guid(),
ownerHistory,
None,
None,
ifcElements[i],
ifcConnections[j],
appliedCondition,
None,
None,
localAxes,
)
else:
pointOnElement = self.f.createIfcCartesianPoint(tuple(conn['eccentricity']['pointOnElement']))
vector = conn['eccentricity']['vector']
connPointEcc = self.f.createIfcConnectionPointEccentricity(pointOnElement, None, vector[0], vector[1], vector[2])
self.f.createIfcRelConnectsWithEccentricity(self.guid(), ownerHistory, None, None, ifcElements[i], ifcConnections[j], appliedCondition, None, None, localAxes, connPointEcc)
pointOnElement = self.f.createIfcCartesianPoint(tuple(conn["eccentricity"]["pointOnElement"]))
vector = conn["eccentricity"]["vector"]
connPointEcc = self.f.createIfcConnectionPointEccentricity(
pointOnElement, None, vector[0], vector[1], vector[2]
)
self.f.createIfcRelConnectsWithEccentricity(
self.guid(),
ownerHistory,
None,
None,
ifcElements[i],
ifcConnections[j],
appliedCondition,
None,
None,
localAxes,
connPointEcc,
)
if geometryType in ['line', 'surface']:
self.f.createIfcRelConnectsStructuralMember(self.guid(), ownerHistory, None, None, ifcElements[i], ifcConnections[j], appliedCondition, None, None, localAxes)
if geometryType in ["line", "surface"]:
self.f.createIfcRelConnectsStructuralMember(
self.guid(),
ownerHistory,
None,
None,
ifcElements[i],
ifcConnections[j],
appliedCondition,
None,
None,
localAxes,
)
# assign elements and connections to group
self.f.createIfcRelAssignsToGroup(self.guid(), ownerHistory, None, None, tuple(ifcElements + ifcConnections), None, model)
self.f.createIfcRelAssignsToGroup(
self.guid(), ownerHistory, None, None, tuple(ifcElements + ifcConnections), None, model
)
# finalize ifc file
self.f.write(self.outputFilename)
@@ -177,10 +292,10 @@ class CA2IFC:
self.f.wrapped_data.header.file_name.name = os.path.basename(self.outputFilename)
def create_global_axes(self):
self.xAxis = self.f.createIfcDirection((1., 0., 0.))
self.yAxis = self.f.createIfcDirection((0., 1., 0.))
self.zAxis = self.f.createIfcDirection((0., 0., 1.))
self.origin = self.f.createIfcCartesianPoint((0., 0., 0.))
self.xAxis = self.f.createIfcDirection((1.0, 0.0, 0.0))
self.yAxis = self.f.createIfcDirection((0.0, 1.0, 0.0))
self.zAxis = self.f.createIfcDirection((0.0, 0.0, 1.0))
self.origin = self.f.createIfcCartesianPoint((0.0, 0.0, 0.0))
axes = self.f.createIfcAxis2Placement3D(self.origin, self.zAxis, self.xAxis)
return axes
@@ -193,156 +308,197 @@ class CA2IFC:
return axes
def create_owner_history(self):
actor = self.f.createIfcActorRole('ENGINEER', None, None)
person = self.f.createIfcPerson('Christovasilis', None, 'Ioannis', None, None, None, (actor,))
organization = self.f.createIfcOrganization(None, 'IfcOpenShell', 'IfcOpenShell, an open source (LGPL) software library that helps users and software developers to work with the IFC file format.')
actor = self.f.createIfcActorRole("ENGINEER", None, None)
person = self.f.createIfcPerson("Christovasilis", None, "Ioannis", None, None, None, (actor,))
organization = self.f.createIfcOrganization(
None,
"IfcOpenShell",
"IfcOpenShell, an open source (LGPL) software library that helps users and software developers to work with the IFC file format.",
)
p_o = self.f.createIfcPersonAndOrganization(person, organization)
application = self.f.createIfcApplication(organization, 'v0.0.x', 'IFC2CA', 'IFC2CA')
ownerHistory = self.f.createIfcOwnerHistory(p_o, application, 'READWRITE', None, None, p_o, application)
application = self.f.createIfcApplication(organization, "v0.0.x", "IFC2CA", "IFC2CA")
ownerHistory = self.f.createIfcOwnerHistory(p_o, application, "READWRITE", None, None, p_o, application)
return ownerHistory
def create_reference_subrep(self, globalAxes):
modelRep = self.f.createIfcGeometricRepresentationContext(None, 'Model', 3, 1.E-05, globalAxes, None)
bodySubRep = self.f.createIfcGeometricRepresentationSubContext('Body', 'Model', None, None, None , None, modelRep, None, 'MODEL_VIEW', None)
refSubRep = self.f.createIfcGeometricRepresentationSubContext('Reference', 'Model', None, None, None , None, modelRep, None, 'GRAPH_VIEW', None)
modelRep = self.f.createIfcGeometricRepresentationContext(None, "Model", 3, 1.0e-05, globalAxes, None)
bodySubRep = self.f.createIfcGeometricRepresentationSubContext(
"Body", "Model", None, None, None, None, modelRep, None, "MODEL_VIEW", None
)
refSubRep = self.f.createIfcGeometricRepresentationSubContext(
"Reference", "Model", None, None, None, None, modelRep, None, "GRAPH_VIEW", None
)
return {
'model': modelRep,
'body': bodySubRep,
'reference': refSubRep
}
return {"model": modelRep, "body": bodySubRep, "reference": refSubRep}
def create_material(self, material):
ifcMaterial = self.f.createIfcMaterial(material['name'], None, material['category'])
ifcMaterial = self.f.createIfcMaterial(material["name"], None, material["category"])
mechProps = []
if 'youngModulus' in material['mechProps']:
youngModulus = self.f.createIfcPropertySingleValue('YoungModulus', None, self.f.createIfcModulusOfElasticityMeasure(material['mechProps']['youngModulus']))
if "youngModulus" in material["mechProps"]:
youngModulus = self.f.createIfcPropertySingleValue(
"YoungModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["youngModulus"])
)
mechProps.append(youngModulus)
if 'shearModulus' in material['mechProps']:
shearModulus = self.f.createIfcPropertySingleValue('ShearModulus', None, self.f.createIfcModulusOfElasticityMeasure(material['mechProps']['shearModulus']))
if "shearModulus" in material["mechProps"]:
shearModulus = self.f.createIfcPropertySingleValue(
"ShearModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["shearModulus"])
)
mechProps.append(shearModulus)
if 'poissonRatio' in material['mechProps']:
poissonRatio = self.f.createIfcPropertySingleValue('PoissonRatio', None, self.f.createIfcPositiveRatioMeasure(material['mechProps']['poissonRatio']))
if "poissonRatio" in material["mechProps"]:
poissonRatio = self.f.createIfcPropertySingleValue(
"PoissonRatio", None, self.f.createIfcPositiveRatioMeasure(material["mechProps"]["poissonRatio"])
)
mechProps.append(poissonRatio)
if mechProps:
self.f.createIfcMaterialProperties('Pset_MaterialMechanical', material['name'], tuple(mechProps), ifcMaterial)
self.f.createIfcMaterialProperties(
"Pset_MaterialMechanical", material["name"], tuple(mechProps), ifcMaterial
)
commonProps = []
if 'massDensity' in material['commonProps']:
massDensity = self.f.createIfcPropertySingleValue('MassDensity', None, self.f.createIfcMassDensityMeasure(material['commonProps']['massDensity']))
if "massDensity" in material["commonProps"]:
massDensity = self.f.createIfcPropertySingleValue(
"MassDensity", None, self.f.createIfcMassDensityMeasure(material["commonProps"]["massDensity"])
)
commonProps.append(massDensity)
if commonProps:
self.f.createIfcMaterialProperties('Pset_MaterialCommon', material['name'], tuple(commonProps), ifcMaterial)
self.f.createIfcMaterialProperties("Pset_MaterialCommon", material["name"], tuple(commonProps), ifcMaterial)
return ifcMaterial
def create_profile(self, profile):
if profile['profileShape'] == 'rectangular':
ifcProfile = self.f.createIfcRectangleProfileDef(profile['profileType'], profile['profileName'], None, profile['xDim'], profile['yDim'])
if profile["profileShape"] == "rectangular":
ifcProfile = self.f.createIfcRectangleProfileDef(
profile["profileType"], profile["profileName"], None, profile["xDim"], profile["yDim"]
)
if profile['profileShape'] == 'iSymmetrical':
if profile["profileShape"] == "iSymmetrical":
ifcProfile = self.f.createIfcIShapeProfileDef(
profile['profileType'], profile['profileName'], None,
profile['commonProps']['overallWidth'],
profile['commonProps']['overallDepth'],
profile['commonProps']['webThickness'],
profile['commonProps']['flangeThickness'],
profile['commonProps']['filletRadius']
profile["profileType"],
profile["profileName"],
None,
profile["commonProps"]["overallWidth"],
profile["commonProps"]["overallDepth"],
profile["commonProps"]["webThickness"],
profile["commonProps"]["flangeThickness"],
profile["commonProps"]["filletRadius"],
)
mechProps = []
if 'massPerLength' in profile['mechProps']:
massPerLength = self.f.createIfcPropertySingleValue('MassPerLength', None, self.f.createIfcMassPerLengthMeasure(profile['mechProps']['massPerLength']))
if "massPerLength" in profile["mechProps"]:
massPerLength = self.f.createIfcPropertySingleValue(
"MassPerLength", None, self.f.createIfcMassPerLengthMeasure(profile["mechProps"]["massPerLength"])
)
mechProps.append(massPerLength)
if 'crossSectionArea' in profile['mechProps']:
crossSectionArea = self.f.createIfcPropertySingleValue('CrossSectionArea', None, self.f.createIfcAreaMeasure(profile['mechProps']['crossSectionArea']))
if "crossSectionArea" in profile["mechProps"]:
crossSectionArea = self.f.createIfcPropertySingleValue(
"CrossSectionArea", None, self.f.createIfcAreaMeasure(profile["mechProps"]["crossSectionArea"])
)
mechProps.append(crossSectionArea)
if 'momentOfInertiaY' in profile['mechProps']:
momentOfInertiaY = self.f.createIfcPropertySingleValue('MomentOfInertiaY', None, self.f.createIfcMomentOfInertiaMeasure(profile['mechProps']['momentOfInertiaY']))
if "momentOfInertiaY" in profile["mechProps"]:
momentOfInertiaY = self.f.createIfcPropertySingleValue(
"MomentOfInertiaY",
None,
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaY"]),
)
mechProps.append(momentOfInertiaY)
if 'momentOfInertiaZ' in profile['mechProps']:
momentOfInertiaZ = self.f.createIfcPropertySingleValue('MomentOfInertiaZ', None, self.f.createIfcMomentOfInertiaMeasure(profile['mechProps']['momentOfInertiaZ']))
if "momentOfInertiaZ" in profile["mechProps"]:
momentOfInertiaZ = self.f.createIfcPropertySingleValue(
"MomentOfInertiaZ",
None,
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaZ"]),
)
mechProps.append(momentOfInertiaZ)
if 'torsionalConstantX' in profile['mechProps']:
torsionalConstantX = self.f.createIfcPropertySingleValue('TorsionalConstantX', None, self.f.createIfcMomentOfInertiaMeasure(profile['mechProps']['torsionalConstantX']))
if "torsionalConstantX" in profile["mechProps"]:
torsionalConstantX = self.f.createIfcPropertySingleValue(
"TorsionalConstantX",
None,
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["torsionalConstantX"]),
)
mechProps.append(torsionalConstantX)
if mechProps:
self.f.createIfcProfileProperties('Pset_ProfileMechanical', profile['profileName'], tuple(mechProps), ifcProfile)
self.f.createIfcProfileProperties(
"Pset_ProfileMechanical", profile["profileName"], tuple(mechProps), ifcProfile
)
return ifcProfile
def create_geometry(self, object):
if object['geometryType'] == 'point':
point = self.f.createIfcCartesianPoint(tuple(object['geometry']))
if object["geometryType"] == "point":
point = self.f.createIfcCartesianPoint(tuple(object["geometry"]))
vertex = self.f.createIfcVertexPoint(point)
vertexTopologyRep = self.f.createIfcTopologyRepresentation(self.reps['reference'], 'Reference', 'Vertex', (vertex,))
vertexTopologyRep = self.f.createIfcTopologyRepresentation(
self.reps["reference"], "Reference", "Vertex", (vertex,)
)
vertexProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (vertexTopologyRep,))
return vertexProdDefShape
if object['geometryType'] == 'line':
startPoint = self.f.createIfcCartesianPoint(tuple(object['geometry'][0]))
if object["geometryType"] == "line":
startPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][0]))
startVertex = self.f.createIfcVertexPoint(startPoint)
endPoint = self.f.createIfcCartesianPoint(tuple(object['geometry'][1]))
endPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][1]))
endVertex = self.f.createIfcVertexPoint(endPoint)
edge = self.f.createIfcEdge(startVertex, endVertex)
edgeTopologyRep = self.f.createIfcTopologyRepresentation(self.reps['reference'], 'Reference', 'Edge', (edge,))
edgeTopologyRep = self.f.createIfcTopologyRepresentation(
self.reps["reference"], "Reference", "Edge", (edge,)
)
edgeProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (edgeTopologyRep,))
return edgeProdDefShape
if object['geometryType'] == 'surface':
verts = [None for _ in range(len(object['geometry']))]
for i,p in enumerate(object['geometry']):
if object["geometryType"] == "surface":
verts = [None for _ in range(len(object["geometry"]))]
for i, p in enumerate(object["geometry"]):
point = self.f.createIfcCartesianPoint(tuple(p))
verts[i] = self.f.createIfcVertexPoint(point)
orientedEdges = [None for _ in range(len(object['geometry']))]
for i,v in enumerate(verts):
orientedEdges = [None for _ in range(len(object["geometry"]))]
for i, v in enumerate(verts):
v2Index = (i + 1) if i < len(verts) - 1 else 0
edge = self.f.createIfcEdge(v, verts[v2Index])
orientedEdges[i] = self.f.createIfcOrientedEdge(None, None, edge, True)
edgeLoop = self.f.createIfcEdgeLoop(tuple(orientedEdges))
localAxes = self.create_orientation(object['orientation'])
localAxes = self.create_orientation(object["orientation"])
plane = self.f.createIfcPlane(localAxes)
faceBound = self.f.createIfcFaceBound(edgeLoop, True)
face = self.f.createIfcFaceSurface((faceBound,), plane, True)
faceTopologyRep = self.f.createIfcTopologyRepresentation(self.reps['reference'], 'Reference', 'Face', (face,))
faceTopologyRep = self.f.createIfcTopologyRepresentation(
self.reps["reference"], "Reference", "Face", (face,)
)
faceProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (faceTopologyRep,))
return faceProdDefShape
def create_applied_conditions(self, bc, geometryType):
for dof in ['dx', 'dy', 'dz']:
for dof in ["dx", "dy", "dz"]:
if isinstance(bc[dof], bool):
bc[dof] = self.f.createIfcBoolean(bc[dof])
else:
if geometryType == 'point':
if geometryType == "point":
bc[dof] = self.f.createIfcLinearStiffnessMeasure(bc[dof])
if geometryType == 'line':
if geometryType == "line":
bc[dof] = self.f.createIfcModulusOfLinearSubgradeReactionMeasure(bc[dof])
if geometryType == 'surface':
if geometryType == "surface":
bc[dof] = self.f.createIfcModulusOfSubgradeReactionMeasure(bc[dof])
for dof in ['drx', 'dry', 'drz']:
for dof in ["drx", "dry", "drz"]:
if isinstance(bc[dof], bool):
bc[dof] = self.f.createIfcBoolean(bc[dof])
else:
if geometryType == 'point':
if geometryType == "point":
bc[dof] = self.f.createIfcRotationalStiffnessMeasure(bc[dof])
if geometryType == 'line':
if geometryType == "line":
bc[dof] = self.f.createIfcModulusOfRotationalSubgradeReactionMeasure(bc[dof])
return bc
if __name__ == '__main__':
inputFilename = 'structure_01.json'
outputFilename = 'structure_01.ifc'
if __name__ == "__main__":
inputFilename = "structure_01.json"
outputFilename = "structure_01.ifc"
ca2ifc = CA2IFC(inputFilename, outputFilename)
ca2ifc.convert()
+245 -216
View File
@@ -4,59 +4,59 @@ import json
import ifcopenshell
import numpy as np
class IFC2CA:
def __init__(self, filename):
self.filename = filename
self.file = None
self.result = {}
self.warnings = []
self.tol = 1E-06
self.tol = 1e-06
def convert(self):
self.file = ifcopenshell.open(self.filename)
for model in self.file.by_type('IfcStructuralAnalysisModel'):
elements = self.get_structural_items(model, item_type='IfcStructuralMember')
connections = self.get_structural_items(model, item_type='IfcStructuralConnection')
for model in self.file.by_type("IfcStructuralAnalysisModel"):
elements = self.get_structural_items(model, item_type="IfcStructuralMember")
connections = self.get_structural_items(model, item_type="IfcStructuralConnection")
materialdb = []
materials = list(dict.fromkeys([e['material'] for e in elements]))
materials = list(dict.fromkeys([e["material"] for e in elements]))
for mat in [mat for mat in materials if mat]:
id = int(mat.split('|')[1])
id = int(mat.split("|")[1])
material = self.get_material_properties(self.file.by_id(id))
material['relatedElements'] = [e['ifcName'] for e in elements if 'material' in e and e['material'] == mat]
material["relatedElements"] = [
e["ifcName"] for e in elements if "material" in e and e["material"] == mat
]
materialdb.append(material)
profiledb = []
profiles = list(dict.fromkeys([e['profile'] for e in elements if 'profile' in e]))
profiles = list(dict.fromkeys([e["profile"] for e in elements if "profile" in e]))
for prof in [prof for prof in profiles if prof]:
id = int(prof.split('|')[1])
id = int(prof.split("|")[1])
profile = self.get_profile_properties(self.file.by_id(id))
profile['relatedElements'] = [e['ifcName'] for e in elements if 'profile' in e and e['profile'] == prof]
profile["relatedElements"] = [e["ifcName"] for e in elements if "profile" in e and e["profile"] == prof]
profiledb.append(profile)
self.result = {
'ifcName': model.is_a() + '|' + str(model.id()),
'name': model.Name,
'id': model.GlobalId,
'elements': elements,
'connections': connections,
'db': {
'materials': materialdb,
'profiles': profiledb
},
'warnings': self.warnings
"ifcName": model.is_a() + "|" + str(model.id()),
"name": model.Name,
"id": model.GlobalId,
"elements": elements,
"connections": connections,
"db": {"materials": materialdb, "profiles": profiledb},
"warnings": self.warnings,
}
print('Model "%s" converted' % model.Name)
print('Number of elements: ', len(elements))
print('Number of connections: ', len(connections))
print('Number of materials: ', len(materialdb))
print('Number of profiles: ', len(profiledb))
print('')
print("Number of elements: ", len(elements))
print("Number of connections: ", len(connections))
print("Number of materials: ", len(materialdb))
print("Number of profiles: ", len(profiledb))
print("")
break
def get_structural_items(self, model, item_type='IfcStructuralItem'):
def get_structural_items(self, model, item_type="IfcStructuralItem"):
items = []
for group in model.IsGroupedBy:
for item in group.RelatedObjects:
@@ -70,100 +70,112 @@ class IFC2CA:
def get_item_data(self, item):
transformation = self.get_transformation(item.ObjectPlacement)
if item.is_a('IfcStructuralCurveMember'):
representation = self.get_representation(item, 'Edge')
if item.is_a("IfcStructuralCurveMember"):
representation = self.get_representation(item, "Edge")
material_profile = self.get_material_profile(item)
if not representation:
self.warnings.append('No representation defined for %s. Member excluded' % (item.is_a() + '|' + str(item.id())))
self.warnings.append(
"No representation defined for %s. Member excluded" % (item.is_a() + "|" + str(item.id()))
)
return
if not material_profile:
self.warnings.append('No material defined for in %s' % (item.is_a() + '|' + str(item.id())))
self.warnings.append('No profile defined for in %s' % (item.is_a() + '|' + str(item.id())))
self.warnings.append("No material defined for in %s" % (item.is_a() + "|" + str(item.id())))
self.warnings.append("No profile defined for in %s" % (item.is_a() + "|" + str(item.id())))
materialId = None
profileId = None
else:
material = material_profile.Material
materialId = material.is_a() + '|' + str(material.id())
materialId = material.is_a() + "|" + str(material.id())
profile = material_profile.Profile
profileId = profile.is_a() + '|' + str(profile.id())
profileId = profile.is_a() + "|" + str(profile.id())
geometry = self.get_geometry(representation)
orientation = self.get_1D_orientation(geometry, item.Axis)
connections = self.get_connection_data(item.ConnectedBy)
for conn in connections:
if not conn['orientation']:
conn['orientation'] = orientation
if not conn["orientation"]:
conn["orientation"] = orientation
# --> Correct pointOnElement for eccentricity connection for ETABS files
length = np.linalg.norm(np.array(geometry[1]) - np.array(geometry[0]))
for c in connections:
if c['eccentricity']:
if np.linalg.norm(np.array(c['eccentricity']['pointOnElement'])) > length + self.tol:
print(np.linalg.norm(np.array(c['eccentricity']['pointOnElement'])), '>', length)
self.warnings.append('Eccentricity in %s corrected' % (item.is_a() + '|' + str(item.id())))
c['eccentricity']['pointOnElement'][0] = length
if c["eccentricity"]:
if np.linalg.norm(np.array(c["eccentricity"]["pointOnElement"])) > length + self.tol:
print(np.linalg.norm(np.array(c["eccentricity"]["pointOnElement"])), ">", length)
self.warnings.append("Eccentricity in %s corrected" % (item.is_a() + "|" + str(item.id())))
c["eccentricity"]["pointOnElement"][0] = length
# End <--
if transformation:
geometry = self.transform_vectors(geometry, transformation)
orientation = self.transform_vectors(orientation, transformation, include_translation=False)
for c in connections:
c['orientation'] = self.transform_vectors(c['orientation'], transformation, include_translation=False)
if c['eccentricity']:
c['eccentricity']['vector'] = self.transform_vectors(c['eccentricity']['vector'], transformation, include_translation=False)
c["orientation"] = self.transform_vectors(
c["orientation"], transformation, include_translation=False
)
if c["eccentricity"]:
c["eccentricity"]["vector"] = self.transform_vectors(
c["eccentricity"]["vector"], transformation, include_translation=False
)
return {
'ifcName': item.is_a() + '|' + str(item.id()),
'name': item.Name,
'id': item.GlobalId,
'geometryType': 'line',
'predefinedType': item.PredefinedType,
'geometry': geometry,
'orientation': orientation,
'material': materialId,
'profile': profileId,
'connections': connections
"ifcName": item.is_a() + "|" + str(item.id()),
"name": item.Name,
"id": item.GlobalId,
"geometryType": "line",
"predefinedType": item.PredefinedType,
"geometry": geometry,
"orientation": orientation,
"material": materialId,
"profile": profileId,
"connections": connections,
}
elif item.is_a('IfcStructuralSurfaceMember'):
representation = self.get_representation(item, 'Face')
elif item.is_a("IfcStructuralSurfaceMember"):
representation = self.get_representation(item, "Face")
material = self.get_material_profile(item)
if not representation:
self.warnings.append('No representation defined for %s. Member excluded' % (item.is_a() + '|' + str(item.id())))
self.warnings.append(
"No representation defined for %s. Member excluded" % (item.is_a() + "|" + str(item.id()))
)
return
if not material:
self.warnings.append('No material defined for in %s' % (item.is_a() + '|' + str(item.id())))
self.warnings.append("No material defined for in %s" % (item.is_a() + "|" + str(item.id())))
materialId = None
else:
materialId = material.is_a() + '|' + str(material.id())
materialId = material.is_a() + "|" + str(material.id())
geometry = self.get_geometry(representation)
orientation = self.get_2D_orientation(representation)
connections = self.get_connection_data(item.ConnectedBy)
for conn in connections:
if not conn['orientation']:
conn['orientation'] = orientation
if not conn["orientation"]:
conn["orientation"] = orientation
if transformation:
geometry = self.transform_vectors(geometry, transformation)
orientation = self.transform_vectors(orientation, transformation, include_translation=False)
for c in connections:
c['orientation'] = self.transform_vectors(c['orientation'], transformation, include_translation=False)
c["orientation"] = self.transform_vectors(
c["orientation"], transformation, include_translation=False
)
return {
'ifcName': item.is_a() + '|' + str(item.id()),
'name': item.Name,
'id': item.GlobalId,
'geometryType': 'surface',
'predefinedType': item.PredefinedType,
'thickness': item.Thickness,
'geometry': geometry,
'orientation': orientation,
'material': materialId,
'connections': connections
"ifcName": item.is_a() + "|" + str(item.id()),
"name": item.Name,
"id": item.GlobalId,
"geometryType": "surface",
"predefinedType": item.PredefinedType,
"thickness": item.Thickness,
"geometry": geometry,
"orientation": orientation,
"material": materialId,
"connections": connections,
}
elif item.is_a('IfcStructuralPointConnection'):
representation = self.get_representation(item, 'Vertex')
elif item.is_a("IfcStructuralPointConnection"):
representation = self.get_representation(item, "Vertex")
if not representation:
self.warnings.append('No representation defined for %s. Connection excluded' % (item.is_a() + '|' + str(item.id())))
self.warnings.append(
"No representation defined for %s. Connection excluded" % (item.is_a() + "|" + str(item.id()))
)
return
geometry = self.get_geometry(representation)
@@ -175,20 +187,22 @@ class IFC2CA:
orientation = self.transform_vectors(orientation, transformation, include_translation=False)
return {
'ifcName': item.is_a() + '|' + str(item.id()),
'name': item.Name,
'id': item.GlobalId,
'geometryType': 'point',
'geometry': geometry,
'orientation': orientation,
'appliedCondition': self.get_connection_input(item, 'point'),
'relatedElements': [con.is_a() + '|' + str(con.id()) for con in item.ConnectsStructuralMembers]
"ifcName": item.is_a() + "|" + str(item.id()),
"name": item.Name,
"id": item.GlobalId,
"geometryType": "point",
"geometry": geometry,
"orientation": orientation,
"appliedCondition": self.get_connection_input(item, "point"),
"relatedElements": [con.is_a() + "|" + str(con.id()) for con in item.ConnectsStructuralMembers],
}
elif item.is_a('IfcStructuralCurveConnection'):
representation = self.get_representation(item, 'Edge')
elif item.is_a("IfcStructuralCurveConnection"):
representation = self.get_representation(item, "Edge")
if not representation:
self.warnings.append('No representation defined for %s. Connection excluded' % (item.is_a() + '|' + str(item.id())))
self.warnings.append(
"No representation defined for %s. Connection excluded" % (item.is_a() + "|" + str(item.id()))
)
return
geometry = self.get_geometry(representation)
@@ -200,26 +214,26 @@ class IFC2CA:
orientation = self.transform_vectors(orientation, transformation, include_translation=False)
return {
'ifcName': item.is_a() + '|' + str(item.id()),
'name': item.Name,
'id': item.GlobalId,
'geometryType': 'line',
'geometry': geometry,
'orientation': orientation,
'appliedCondition': self.get_connection_input(item, 'line'),
'relatedElements': [con.is_a() + '|' + str(con.id()) for con in item.ConnectsStructuralMembers]
"ifcName": item.is_a() + "|" + str(item.id()),
"name": item.Name,
"id": item.GlobalId,
"geometryType": "line",
"geometry": geometry,
"orientation": orientation,
"appliedCondition": self.get_connection_input(item, "line"),
"relatedElements": [con.is_a() + "|" + str(con.id()) for con in item.ConnectsStructuralMembers],
}
def get_transformation(self, placement):
if not placement:
return None
if placement.is_a('IfcLocalPlacement'):
if placement.is_a("IfcLocalPlacement"):
if placement.PlacementRelTo:
print('Warning! Object Placement with PlacementRelTo attribute is not supported and will be neglected')
print("Warning! Object Placement with PlacementRelTo attribute is not supported and will be neglected")
axes = placement.RelativePlacement
location = np.array(self.get_coordinate(axes.Location))
if axes.Axis and axes.RefDirection:
xAxis = np.array(axes.RefDirection.DirectionRatios) # this can be not accurate (in the xz plane)
xAxis = np.array(axes.RefDirection.DirectionRatios) # this can be not accurate (in the xz plane)
zAxis = np.array(axes.Axis.DirectionRatios)
zAxis /= np.linalg.norm(zAxis)
yAxis = np.cross(zAxis, xAxis)
@@ -227,29 +241,30 @@ class IFC2CA:
xAxis = np.cross(yAxis, zAxis)
xAxis /= np.linalg.norm(xAxis)
else:
if np.allclose(location, np.array([0., 0., 0.])):
if np.allclose(location, np.array([0.0, 0.0, 0.0])):
return None
xAxis = np.array([1., 0., 0.])
yAxis = np.array([0., 1., 0.])
zAxis = np.array([0., 0., 1.])
if (np.allclose(location, np.array([0., 0., 0.])) and
np.allclose(xAxis, np.array([1., 0., 0.])) and
np.allclose(yAxis, np.array([0., 1., 0.])) and
np.allclose(zAxis, np.array([0., 0., 1.]))):
xAxis = np.array([1.0, 0.0, 0.0])
yAxis = np.array([0.0, 1.0, 0.0])
zAxis = np.array([0.0, 0.0, 1.0])
if (
np.allclose(location, np.array([0.0, 0.0, 0.0]))
and np.allclose(xAxis, np.array([1.0, 0.0, 0.0]))
and np.allclose(yAxis, np.array([0.0, 1.0, 0.0]))
and np.allclose(zAxis, np.array([0.0, 0.0, 1.0]))
):
return None
return {
'location': location,
'rotationMatrix': np.array([xAxis, yAxis, zAxis]).transpose()
}
return {"location": location, "rotationMatrix": np.array([xAxis, yAxis, zAxis]).transpose()}
else:
print('Warning! Object Placement is of type %s, which is not supported. Default considered' % placement.is_a())
print(
"Warning! Object Placement is of type %s, which is not supported. Default considered" % placement.is_a()
)
return None
def get_representation(self, element, rep_type):
if not element.Representation:
return None
for representation in element.Representation.Representations:
rep = self.get_specific_representation(representation, 'Reference', rep_type)
rep = self.get_specific_representation(representation, "Reference", rep_type)
if rep:
return rep
else:
@@ -260,42 +275,45 @@ class IFC2CA:
return rep
def get_specific_representation(self, representation, rep_id, rep_type):
if (representation.RepresentationIdentifier == rep_id or rep_id is None) \
and representation.RepresentationType == rep_type:
if (
representation.RepresentationIdentifier == rep_id or rep_id is None
) and representation.RepresentationType == rep_type:
return representation
if representation.RepresentationType == 'MappedRepresentation':
if representation.RepresentationType == "MappedRepresentation":
return self.get_specific_representation(
representation.Items[0].MappingSource.MappedRepresentation,
rep_id, rep_type)
representation.Items[0].MappingSource.MappedRepresentation, rep_id, rep_type
)
def get_geometry(self, representation):
# Maybe IfcOpenShell can use create_shape here to simplify this, but
# supposedly structural models are very simple anyway, so perhaps we
# can do without it.
item = representation.Items[0]
if item.is_a('IfcEdge'):
if item.is_a("IfcEdge"):
return [
self.get_coordinate(item.EdgeStart.VertexGeometry),
self.get_coordinate(item.EdgeEnd.VertexGeometry)
self.get_coordinate(item.EdgeEnd.VertexGeometry),
]
elif item.is_a('IfcFaceSurface'):
elif item.is_a("IfcFaceSurface"):
edges = item.Bounds[0].Bound.EdgeList
coords = []
for edge in edges:
coords.append(self.get_coordinate(edge.EdgeElement.EdgeStart.VertexGeometry))
return coords
elif item.is_a('IfcVertexPoint'):
elif item.is_a("IfcVertexPoint"):
return self.get_coordinate(item.VertexGeometry)
def get_coordinate(self, point):
if point.is_a('IfcCartesianPoint'):
if point.is_a("IfcCartesianPoint"):
return list(point.Coordinates)
def get_0D_orientation(self, axes):
if axes and axes.Axis and axes.RefDirection:
xAxis = np.array(axes.RefDirection.DirectionRatios) # this can be not strictly perpendicular (in the xz plane)
xAxis = np.array(
axes.RefDirection.DirectionRatios
) # this can be not strictly perpendicular (in the xz plane)
zAxis = np.array(axes.Axis.DirectionRatios)
zAxis /= np.linalg.norm(zAxis)
yAxis = np.cross(zAxis, xAxis)
@@ -304,13 +322,13 @@ class IFC2CA:
xAxis /= np.linalg.norm(xAxis)
return [xAxis.tolist(), yAxis.tolist(), zAxis.tolist()]
else: # return None and copy the elements orientation
else: # return None and copy the elements orientation
return None
def get_1D_orientation(self, geometry, zAxis):
xAxis = np.array(geometry[1]) - np.array(geometry[0])
xAxis /= np.linalg.norm(xAxis)
zAxis = np.array(zAxis.DirectionRatios) # this can be not strictly perpendicular (in the xz plane)
zAxis = np.array(zAxis.DirectionRatios) # this can be not strictly perpendicular (in the xz plane)
yAxis = np.cross(zAxis, xAxis)
yAxis /= np.linalg.norm(yAxis)
zAxis = np.cross(xAxis, yAxis)
@@ -320,7 +338,7 @@ class IFC2CA:
def get_2D_orientation(self, representation):
item = representation.Items[0]
if item.is_a('IfcFaceSurface'):
if item.is_a("IfcFaceSurface"):
item.SameSense
axes = item.FaceSurface.Position
orientation = self.get_0D_orientation(axes)
@@ -329,17 +347,17 @@ class IFC2CA:
return orientation
def transform_vectors(self, geometry, trsf, include_translation=True):
if not any(isinstance(el, list) for el in geometry): # single point which contains no list
if not any(isinstance(el, list) for el in geometry): # single point which contains no list
geometry = [geometry]
globalGeometry = []
for p in geometry:
gp = trsf['rotationMatrix'].dot(np.array(p))
gp = trsf["rotationMatrix"].dot(np.array(p))
if include_translation:
gp += trsf['location']
gp += trsf["location"]
globalGeometry.append(gp.tolist())
if len(globalGeometry) == 1: # single point
if len(globalGeometry) == 1: # single point
globalGeometry = globalGeometry[0]
return globalGeometry
@@ -348,36 +366,36 @@ class IFC2CA:
if not element.HasAssociations:
return None
for association in element.HasAssociations:
if not association.is_a('IfcRelAssociatesMaterial'):
if not association.is_a("IfcRelAssociatesMaterial"):
continue
material = association.RelatingMaterial
if material.is_a('IfcMaterialProfileSet'):
if material.is_a("IfcMaterialProfileSet"):
# For now, we only deal with a single profile
return material.MaterialProfiles[0]
if material.is_a('IfcMaterialProfileSetUsage'):
if material.is_a("IfcMaterialProfileSetUsage"):
return material.ForProfileSet.MaterialProfiles[0]
if material.is_a('IfcMaterial'):
if material.is_a("IfcMaterial"):
return material
def get_material_properties(self, material):
psets = material.HasProperties
if self.get_pset_properties(psets, 'Pset_MaterialMechanical'):
mechProps = self.get_pset_properties(psets, 'Pset_MaterialMechanical')
if self.get_pset_properties(psets, "Pset_MaterialMechanical"):
mechProps = self.get_pset_properties(psets, "Pset_MaterialMechanical")
else:
mechProps = self.get_pset_properties(psets, None)
if self.get_pset_properties(psets, 'Pset_MaterialCommon'):
commonProps = self.get_pset_properties(psets, 'Pset_MaterialCommon')
if self.get_pset_properties(psets, "Pset_MaterialCommon"):
commonProps = self.get_pset_properties(psets, "Pset_MaterialCommon")
else:
commonProps = self.get_pset_properties(psets, None)
return {
'ifcName': material.is_a() + '|' + str(material.id()),
'name': material.Name,
'category': material.Category,
'mechProps': mechProps,
'commonProps':commonProps
"ifcName": material.is_a() + "|" + str(material.id()),
"name": material.Name,
"category": material.Category,
"mechProps": mechProps,
"commonProps": commonProps,
}
def get_pset_property(self, psets, pset_name, prop_name):
@@ -397,98 +415,113 @@ class IFC2CA:
return d
def get_profile_properties(self, profile):
if profile.is_a('IfcRectangleProfileDef'):
if profile.is_a("IfcRectangleProfileDef"):
return {
'ifcName': profile.is_a() + '|' + str(profile.id()),
'profileName': profile.ProfileName,
'profileType': profile.ProfileType,
'profileShape': 'rectangular',
'xDim': profile.XDim,
'yDim': profile.YDim
"ifcName": profile.is_a() + "|" + str(profile.id()),
"profileName": profile.ProfileName,
"profileType": profile.ProfileType,
"profileShape": "rectangular",
"xDim": profile.XDim,
"yDim": profile.YDim,
}
if profile.is_a('IfcIShapeProfileDef'):
if profile.is_a("IfcIShapeProfileDef"):
psets = profile.HasProperties
if self.get_pset_properties(psets, 'Pset_ProfileMechanical'):
mechProps = self.get_pset_properties(psets, 'Pset_ProfileMechanical')
if self.get_pset_properties(psets, "Pset_ProfileMechanical"):
mechProps = self.get_pset_properties(psets, "Pset_ProfileMechanical")
else:
mechProps = self.get_i_section_properties(profile, 'iSymmetrical')
mechProps = self.get_i_section_properties(profile, "iSymmetrical")
return {
'ifcName': profile.is_a() + '|' + str(profile.id()),
'profileName': profile.ProfileName,
'profileType': profile.ProfileType,
'profileShape': 'iSymmetrical',
'mechProps': mechProps,
'commonProps': {
'flangeThickness': profile.FlangeThickness,
'webThickness': profile.WebThickness,
'overallDepth': profile.OverallDepth,
'overallWidth': profile.OverallWidth,
'filletRadius': profile.FilletRadius,
}
"ifcName": profile.is_a() + "|" + str(profile.id()),
"profileName": profile.ProfileName,
"profileType": profile.ProfileType,
"profileShape": "iSymmetrical",
"mechProps": mechProps,
"commonProps": {
"flangeThickness": profile.FlangeThickness,
"webThickness": profile.WebThickness,
"overallDepth": profile.OverallDepth,
"overallWidth": profile.OverallWidth,
"filletRadius": profile.FilletRadius,
},
}
def get_connection_data(self, itemList):
return [{
'ifcName': rel.is_a() + '|' + str(rel.id()),
'id': rel.GlobalId,
'relatingElement': rel.RelatingStructuralMember.is_a() + '|' + str(rel.RelatingStructuralMember.id()),
'relatedConnection': rel.RelatedStructuralConnection.is_a() + '|' + str(rel.RelatedStructuralConnection.id()),
'orientation': self.get_0D_orientation(rel.ConditionCoordinateSystem),
'appliedCondition': self.get_connection_input(rel, self.get_geometry_type_from_connection(rel.RelatedStructuralConnection)),
'eccentricity': None if not rel.is_a('IfcRelConnectsWithEccentricity') else {
'vector': [
0.0 if not rel.ConnectionConstraint.EccentricityInX else rel.ConnectionConstraint.EccentricityInX,
0.0 if not rel.ConnectionConstraint.EccentricityInY else rel.ConnectionConstraint.EccentricityInY,
0.0 if not rel.ConnectionConstraint.EccentricityInZ else rel.ConnectionConstraint.EccentricityInZ
return [
{
"ifcName": rel.is_a() + "|" + str(rel.id()),
"id": rel.GlobalId,
"relatingElement": rel.RelatingStructuralMember.is_a() + "|" + str(rel.RelatingStructuralMember.id()),
"relatedConnection": rel.RelatedStructuralConnection.is_a()
+ "|"
+ str(rel.RelatedStructuralConnection.id()),
"orientation": self.get_0D_orientation(rel.ConditionCoordinateSystem),
"appliedCondition": self.get_connection_input(
rel, self.get_geometry_type_from_connection(rel.RelatedStructuralConnection)
),
"eccentricity": None
if not rel.is_a("IfcRelConnectsWithEccentricity")
else {
"vector": [
0.0
if not rel.ConnectionConstraint.EccentricityInX
else rel.ConnectionConstraint.EccentricityInX,
0.0
if not rel.ConnectionConstraint.EccentricityInY
else rel.ConnectionConstraint.EccentricityInY,
0.0
if not rel.ConnectionConstraint.EccentricityInZ
else rel.ConnectionConstraint.EccentricityInZ,
],
'pointOnElement': self.get_coordinate(rel.ConnectionConstraint.PointOnRelatingElement)
}
} for rel in itemList]
"pointOnElement": self.get_coordinate(rel.ConnectionConstraint.PointOnRelatingElement),
},
}
for rel in itemList
]
def get_geometry_type_from_connection(self, connection):
if connection.is_a('IfcStructuralPointConnection'):
return 'point'
if connection.is_a('IfcStructuralCurveConnection'):
return 'line'
if connection.is_a('IfcStructuralSurfaceConnection'):
return 'surface'
if connection.is_a("IfcStructuralPointConnection"):
return "point"
if connection.is_a("IfcStructuralCurveConnection"):
return "line"
if connection.is_a("IfcStructuralSurfaceConnection"):
return "surface"
def get_connection_input(self, connection, geometryType):
if connection.AppliedCondition:
if geometryType == 'point':
if geometryType == "point":
return {
'dx': connection.AppliedCondition.TranslationalStiffnessX.wrappedValue,
'dy': connection.AppliedCondition.TranslationalStiffnessY.wrappedValue,
'dz': connection.AppliedCondition.TranslationalStiffnessZ.wrappedValue,
'drx': connection.AppliedCondition.RotationalStiffnessX.wrappedValue,
'dry': connection.AppliedCondition.RotationalStiffnessY.wrappedValue,
'drz': connection.AppliedCondition.RotationalStiffnessZ.wrappedValue
"dx": connection.AppliedCondition.TranslationalStiffnessX.wrappedValue,
"dy": connection.AppliedCondition.TranslationalStiffnessY.wrappedValue,
"dz": connection.AppliedCondition.TranslationalStiffnessZ.wrappedValue,
"drx": connection.AppliedCondition.RotationalStiffnessX.wrappedValue,
"dry": connection.AppliedCondition.RotationalStiffnessY.wrappedValue,
"drz": connection.AppliedCondition.RotationalStiffnessZ.wrappedValue,
}
if geometryType == 'line':
if geometryType == "line":
return {
'dx': connection.AppliedCondition.TranslationalStiffnessByLengthX.wrappedValue,
'dy': connection.AppliedCondition.TranslationalStiffnessByLengthY.wrappedValue,
'dz': connection.AppliedCondition.TranslationalStiffnessByLengthZ.wrappedValue,
'drx': connection.AppliedCondition.RotationalStiffnessByLengthX.wrappedValue,
'dry': connection.AppliedCondition.RotationalStiffnessByLengthY.wrappedValue,
'drz': connection.AppliedCondition.RotationalStiffnessByLengthZ.wrappedValue
"dx": connection.AppliedCondition.TranslationalStiffnessByLengthX.wrappedValue,
"dy": connection.AppliedCondition.TranslationalStiffnessByLengthY.wrappedValue,
"dz": connection.AppliedCondition.TranslationalStiffnessByLengthZ.wrappedValue,
"drx": connection.AppliedCondition.RotationalStiffnessByLengthX.wrappedValue,
"dry": connection.AppliedCondition.RotationalStiffnessByLengthY.wrappedValue,
"drz": connection.AppliedCondition.RotationalStiffnessByLengthZ.wrappedValue,
}
if geometryType == 'surface':
if geometryType == "surface":
return {
'dx': connection.AppliedCondition.TranslationalStiffnessByAreaX.wrappedValue,
'dy': connection.AppliedCondition.TranslationalStiffnessByAreaY.wrappedValue,
'dz': connection.AppliedCondition.TranslationalStiffnessByAreaZ.wrappedValue
"dx": connection.AppliedCondition.TranslationalStiffnessByAreaX.wrappedValue,
"dy": connection.AppliedCondition.TranslationalStiffnessByAreaY.wrappedValue,
"dz": connection.AppliedCondition.TranslationalStiffnessByAreaZ.wrappedValue,
}
return connection.AppliedCondition
def get_i_section_properties(self, profile, profileShape):
if profileShape == 'iSymmetrical':
if profileShape == "iSymmetrical":
tf = profile.FlangeThickness
tw = profile.WebThickness
h = profile.OverallDepth
@@ -499,20 +532,16 @@ class IFC2CA:
Iz = (2 * tf) * (b ** 3) / 12 + (h - 2 * tf) * (tw ** 3) / 12
Jx = 1 / 3 * ((h - tf) * (tw ** 3) + 2 * b * (tf ** 3))
return {
'crossSectionArea': A,
'momentOfInertiaY': Iy,
'momentOfInertiaZ': Iz,
'torsionalConstantX': Jx
}
return {"crossSectionArea": A, "momentOfInertiaY": Iy, "momentOfInertiaZ": Iz, "torsionalConstantX": Jx}
if __name__ == '__main__':
fileNames = ['cantilever_01', 'portal_01', 'grid_of_beams', 'slab_01', 'structure_01']
if __name__ == "__main__":
fileNames = ["cantilever_01", "portal_01", "grid_of_beams", "slab_01", "structure_01"]
files = fileNames
for fileName in files:
BASE_PATH = '/home/jesusbill/Dev-Projects/github.com/IfcOpenShell/analysis-models/ifcFiles/'
ifc2ca = IFC2CA(BASE_PATH + fileName + '.ifc')
BASE_PATH = "/home/jesusbill/Dev-Projects/github.com/IfcOpenShell/analysis-models/ifcFiles/"
ifc2ca = IFC2CA(BASE_PATH + fileName + ".ifc")
ifc2ca.convert()
with open(BASE_PATH + fileName + '.json', 'w') as f:
f.write(json.dumps(ifc2ca.result, indent = 4))
with open(BASE_PATH + fileName + ".json", "w") as f:
f.write(json.dumps(ifc2ca.result, indent=4))
File diff suppressed because it is too large Load Diff
+222 -167
View File
@@ -11,6 +11,7 @@ import itertools
flatten = itertools.chain.from_iterable
class MODEL:
def __init__(self, dataFilename, medFilename, meshSize):
self.dataFilename = dataFilename
@@ -22,20 +23,20 @@ class MODEL:
self.create()
def getGroupName(self, name):
info = name.split('|')
sortName = ''.join(c for c in info[0] if c.isupper())
return str(sortName + '_' + info[1])
info = name.split("|")
sortName = "".join(c for c in info[0] if c.isupper())
return str(sortName + "_" + info[1])
def makePoint(self, pl):
'''Function to define a Point from
a polyline (list of 1 point)'''
"""Function to define a Point from
a polyline (list of 1 point)"""
(x, y, z) = pl
return self.geompy.MakeVertex(x, y, z)
def makeLine(self, pl):
'''Function to define a Line from
a polyline (list of 2 points)'''
"""Function to define a Line from
a polyline (list of 2 points)"""
(x, y, z) = pl[0]
P1 = self.geompy.MakeVertex(x, y, z)
@@ -45,8 +46,8 @@ class MODEL:
return self.geompy.MakeLineTwoPnt(P1, P2)
def makeFace(self, pl):
'''Function to define a Face from
a polyline (list of points)'''
"""Function to define a Face from
a polyline (list of points)"""
pointList = [None for _ in range(len(pl))]
for ip, (x, y, z) in enumerate(pl):
@@ -60,53 +61,53 @@ class MODEL:
return self.geompy.MakeFaceWires(LineList, 1)
def makeObject(self, geometry, geometryType):
if geometryType == 'point':
if geometryType == "point":
return self.makePoint(geometry)
if geometryType == 'line':
if geometryType == "line":
return self.makeLine(geometry)
if geometryType == 'surface':
if geometryType == "surface":
return self.makeFace(geometry)
def makePartition(self, objects, geometryType):
if geometryType == 'point':
shapeType = 'VERTEX'
if geometryType == 'line':
shapeType = 'EDGE'
if geometryType == 'surface':
shapeType = 'FACE'
if geometryType == "point":
shapeType = "VERTEX"
if geometryType == "line":
shapeType = "EDGE"
if geometryType == "surface":
shapeType = "FACE"
return self.geompy.MakePartition(objects, [], [], [], self.geompy.ShapeType[shapeType], 0, [], 1)
def getLinkGeometry(self, ecc, orientation, finalPoint):
vector = np.array(orientation).transpose().dot(ecc['vector'])
vector = np.array(orientation).transpose().dot(ecc["vector"])
initialPoint = (np.array(finalPoint) - vector).tolist()
return [initialPoint, finalPoint]
def length(self, geometry):
return ((
(geometry[1][0] - geometry[0][0]) ** 2 + \
(geometry[1][1] - geometry[0][1]) ** 2 + \
(geometry[1][2] - geometry[0][2]) ** 2 \
) ** 0.5)
return (
(geometry[1][0] - geometry[0][0]) ** 2
+ (geometry[1][1] - geometry[0][1]) ** 2
+ (geometry[1][2] - geometry[0][2]) ** 2
) ** 0.5
def create(self):
# Read data from input file
with open(self.dataFilename) as dataFile:
data = json.load(dataFile)
elements = data['elements']
connections = data['connections']
elements = data["elements"]
connections = data["connections"]
# --> Delete this reference data and repopulate it with the objects
# while going through elements
for conn in connections:
conn['relatedElements'] = []
conn["relatedElements"] = []
# End <--
meshSize = self.meshSize
dec = 7 # 4 decimals for length in mm
tol = 10**(-dec-3+1)
tol = 10 ** (-dec - 3 + 1)
self.tolLoc = tol*10*2
self.tolLoc = tol * 10 * 2
tolLoc = self.tolLoc
NEW_SALOME = int(salome_version.getVersion()[0]) >= 9
@@ -122,7 +123,7 @@ class MODEL:
import math
import SALOMEDS
gg = salome.ImportComponentGUI('GEOM')
gg = salome.ImportComponentGUI("GEOM")
if NEW_SALOME:
geompy = geomBuilder.New()
else:
@@ -133,81 +134,91 @@ class MODEL:
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
geompy.addToStudy( O, 'O' )
geompy.addToStudy( OX, 'OX' )
geompy.addToStudy( OY, 'OY' )
geompy.addToStudy( OZ, 'OZ' )
geompy.addToStudy(O, "O")
geompy.addToStudy(OX, "OX")
geompy.addToStudy(OY, "OY")
geompy.addToStudy(OZ, "OZ")
if len([e for e in elements if e['geometryType'] == 'line']) > 0:
buildingShapeType = 'EDGE'
if len([e for e in elements if e['geometryType'] == 'surface']) > 0:
buildingShapeType = 'FACE'
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
buildingShapeType = "EDGE"
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
buildingShapeType = "FACE"
### Define entities ###
start_time = time.time()
print('Defining Object Geometry')
print("Defining Object Geometry")
init_time = start_time
# Loop 1
for el in elements:
el['elemObj'] = self.makeObject(el['geometry'], el['geometryType'])
el["elemObj"] = self.makeObject(el["geometry"], el["geometryType"])
el['connObjs'] = [None for _ in el['connections']]
el['linkObjs'] = [None for _ in el['connections']]
el['linkPointObjs'] = [[None, None] for _ in el['connections']]
for j,rel in enumerate(el['connections']):
conn = [c for c in connections if c['ifcName'] == rel['relatedConnection']][0]
if rel['eccentricity']:
rel['index'] = len(conn['relatedElements']) + 1
conn['relatedElements'].append(rel)
el["connObjs"] = [None for _ in el["connections"]]
el["linkObjs"] = [None for _ in el["connections"]]
el["linkPointObjs"] = [[None, None] for _ in el["connections"]]
for j, rel in enumerate(el["connections"]):
conn = [c for c in connections if c["ifcName"] == rel["relatedConnection"]][0]
if rel["eccentricity"]:
rel["index"] = len(conn["relatedElements"]) + 1
conn["relatedElements"].append(rel)
if not rel['eccentricity']:
el['connObjs'][j] = self.makeObject(conn['geometry'], conn['geometryType'])
if not rel["eccentricity"]:
el["connObjs"][j] = self.makeObject(conn["geometry"], conn["geometryType"])
else:
if conn['geometryType'] == 'point':
geometry = self.getLinkGeometry(rel['eccentricity'], el['orientation'], conn['geometry'])
el['connObjs'][j] = self.makeObject(geometry[0], conn['geometryType'])
if conn["geometryType"] == "point":
geometry = self.getLinkGeometry(rel["eccentricity"], el["orientation"], conn["geometry"])
el["connObjs"][j] = self.makeObject(geometry[0], conn["geometryType"])
el['linkPointObjs'][j][0] = self.geompy.MakeVertex(geometry[0][0], geometry[0][1], geometry[0][2])
el['linkPointObjs'][j][1] = self.geompy.MakeVertex(geometry[1][0], geometry[1][1], geometry[1][2])
el['linkObjs'][j] = self.geompy.MakeLineTwoPnt(el['linkPointObjs'][j][0], el['linkPointObjs'][j][1])
el["linkPointObjs"][j][0] = self.geompy.MakeVertex(
geometry[0][0], geometry[0][1], geometry[0][2]
)
el["linkPointObjs"][j][1] = self.geompy.MakeVertex(
geometry[1][0], geometry[1][1], geometry[1][2]
)
el["linkObjs"][j] = self.geompy.MakeLineTwoPnt(
el["linkPointObjs"][j][0], el["linkPointObjs"][j][1]
)
else:
print('Eccentricity defined for a %s geometryType' %conn['geometryType'])
print("Eccentricity defined for a %s geometryType" % conn["geometryType"])
el['partObj'] = self.makePartition([el['elemObj']] + el['connObjs'], el['geometryType'])
el["partObj"] = self.makePartition([el["elemObj"]] + el["connObjs"], el["geometryType"])
el['elemObj'] = geompy.GetInPlace(el['partObj'], el['elemObj'])
for j,rel in enumerate(el['connections']):
el['connObjs'][j] = geompy.GetInPlace(el['partObj'], el['connObjs'][j])
el["elemObj"] = geompy.GetInPlace(el["partObj"], el["elemObj"])
for j, rel in enumerate(el["connections"]):
el["connObjs"][j] = geompy.GetInPlace(el["partObj"], el["connObjs"][j])
for conn in connections:
conn['connObj'] = self.makeObject(conn['geometry'], conn['geometryType'])
conn["connObj"] = self.makeObject(conn["geometry"], conn["geometryType"])
# Make assemble of Building Object
bldObjs = []
bldObjs.extend([el['partObj'] for el in elements])
bldObjs.extend(flatten([[link for link in el['linkObjs'] if link] for el in elements]))
bldObjs.extend([conn['connObj'] for conn in connections])
bldObjs.extend([el["partObj"] for el in elements])
bldObjs.extend(flatten([[link for link in el["linkObjs"] if link] for el in elements]))
bldObjs.extend([conn["connObj"] for conn in connections])
bldComp = geompy.MakeCompound(bldObjs)
# bldComp = geompy.MakePartition(bldObjs, [], [], [], self.geompy.ShapeType[buildingShapeType], 0, [], 1)
geompy.addToStudy(bldComp, 'bldComp')
geompy.addToStudy(bldComp, "bldComp")
# Loop 2
for el in elements:
# geompy.addToStudy(el['partObj'], self.getGroupName(el['ifcName']))
geompy.addToStudyInFather(el['partObj'], el['elemObj'], self.getGroupName(el['ifcName']))
for j,rel in enumerate(el['connections']):
conn = [c for c in connections if c['ifcName'] == rel['relatedConnection']][0]
rel['conn_string'] = None
if conn['geometryType'] == 'point':
rel['conn_string'] = '_0DC_'
if conn['geometryType'] == 'line':
rel['conn_string'] = '_1DC_'
if conn['geometryType'] == 'surface':
rel['conn_string'] = '_2DC_'
geompy.addToStudyInFather(el['partObj'], el['connObjs'][j], self.getGroupName(el['ifcName']) + rel['conn_string'] + self.getGroupName(rel['relatedConnection']))
if rel['eccentricity']:
geompy.addToStudyInFather(el["partObj"], el["elemObj"], self.getGroupName(el["ifcName"]))
for j, rel in enumerate(el["connections"]):
conn = [c for c in connections if c["ifcName"] == rel["relatedConnection"]][0]
rel["conn_string"] = None
if conn["geometryType"] == "point":
rel["conn_string"] = "_0DC_"
if conn["geometryType"] == "line":
rel["conn_string"] = "_1DC_"
if conn["geometryType"] == "surface":
rel["conn_string"] = "_2DC_"
geompy.addToStudyInFather(
el["partObj"],
el["connObjs"][j],
self.getGroupName(el["ifcName"]) + rel["conn_string"] + self.getGroupName(rel["relatedConnection"]),
)
if rel["eccentricity"]:
pass
# geompy.addToStudy(el['linkObjs'][j], self.getGroupName(el['ifcName']) + '_1DR_' + self.getGroupName(rel['relatedConnection']))
# geompy.addToStudyInFather(el['linkObjs'][j], el['linkPointObjs'][j][0], self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(el['ifcName']))
@@ -215,51 +226,67 @@ class MODEL:
for conn in connections:
# geompy.addToStudy(conn['connObj'], self.getGroupName(conn['ifcName']))
geompy.addToStudyInFather(conn['connObj'], conn['connObj'], self.getGroupName(conn['ifcName']))
geompy.addToStudyInFather(conn["connObj"], conn["connObj"], self.getGroupName(conn["ifcName"]))
elapsed_time = time.time() - init_time
init_time += elapsed_time
print('Building Geometry Defined in %g sec' % (elapsed_time))
print("Building Geometry Defined in %g sec" % (elapsed_time))
if len([e for e in elements if e['geometryType'] == 'line']) > 0:
buildingShapeType = 'EDGE'
if len([e for e in elements if e['geometryType'] == 'surface']) > 0:
buildingShapeType = 'FACE'
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
buildingShapeType = "EDGE"
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
buildingShapeType = "FACE"
# Define and add groups for all curve and surface members
if len([e for e in elements if e['geometryType'] == 'line']) > 0:
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
# Make compound of requested group
compoundTemp = geompy.MakeCompound([e['elemObj'] for e in elements if e['geometryType'] == 'line'])
compoundTemp = geompy.MakeCompound([e["elemObj"] for e in elements if e["geometryType"] == "line"])
# Define group object and add to study
curveCompound = geompy.GetInPlace(bldComp, compoundTemp)
geompy.addToStudyInFather(bldComp, curveCompound, 'CurveMembers')
geompy.addToStudyInFather(bldComp, curveCompound, "CurveMembers")
if len([e for e in elements if e['geometryType'] == 'surface']) > 0:
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
# Make compound of requested group
compoundTemp = geompy.MakeCompound([e['elemObj'] for e in elements if e['geometryType'] == 'surface'])
compoundTemp = geompy.MakeCompound([e["elemObj"] for e in elements if e["geometryType"] == "surface"])
# Define group object and add to study
surfaceCompound = geompy.GetInPlace(bldComp, compoundTemp)
geompy.addToStudyInFather(bldComp, surfaceCompound, 'SurfaceMembers')
geompy.addToStudyInFather(bldComp, surfaceCompound, "SurfaceMembers")
# Loop 3
for el in elements:
# el['partObj'] = geompy.RestoreGivenSubShapes(bldComp, [el['partObj']], GEOM.FSM_GetInPlace, False, False)[0]
geompy.addToStudyInFather(bldComp, el['elemObj'], self.getGroupName(el['ifcName']))
geompy.addToStudyInFather(bldComp, el["elemObj"], self.getGroupName(el["ifcName"]))
for j,rel in enumerate(el['connections']):
geompy.addToStudyInFather(bldComp, el['connObjs'][j], self.getGroupName(el['ifcName']) + rel['conn_string'] + self.getGroupName(rel['relatedConnection']))
if rel['eccentricity']: # point geometry
geompy.addToStudyInFather(bldComp, el['linkObjs'][j], self.getGroupName(el['ifcName']) + '_1DR_' + self.getGroupName(rel['relatedConnection']))
geompy.addToStudyInFather(bldComp, el['linkPointObjs'][j][0], self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(el['ifcName']))
geompy.addToStudyInFather(bldComp, el['linkPointObjs'][j][1], self.getGroupName(rel['relatedConnection']) + '_0DC_%g' % rel['index'])
for j, rel in enumerate(el["connections"]):
geompy.addToStudyInFather(
bldComp,
el["connObjs"][j],
self.getGroupName(el["ifcName"]) + rel["conn_string"] + self.getGroupName(rel["relatedConnection"]),
)
if rel["eccentricity"]: # point geometry
geompy.addToStudyInFather(
bldComp,
el["linkObjs"][j],
self.getGroupName(el["ifcName"]) + "_1DR_" + self.getGroupName(rel["relatedConnection"]),
)
geompy.addToStudyInFather(
bldComp,
el["linkPointObjs"][j][0],
self.getGroupName(rel["relatedConnection"]) + "_0DC_" + self.getGroupName(el["ifcName"]),
)
geompy.addToStudyInFather(
bldComp,
el["linkPointObjs"][j][1],
self.getGroupName(rel["relatedConnection"]) + "_0DC_%g" % rel["index"],
)
for conn in connections:
# conn['connObj'] = geompy.RestoreGivenSubShapes(bldComp, [conn['connObj']], GEOM.FSM_GetInPlace, False, False)[0]
geompy.addToStudyInFather(bldComp, conn['connObj'], self.getGroupName(conn['ifcName']))
geompy.addToStudyInFather(bldComp, conn["connObj"], self.getGroupName(conn["ifcName"]))
elapsed_time = time.time() - init_time
init_time += elapsed_time
print('Building Geometry Groups Defined in %g sec' % (elapsed_time))
print("Building Geometry Groups Defined in %g sec" % (elapsed_time))
###
### SMESH component
@@ -268,7 +295,7 @@ class MODEL:
import SMESH
from salome.smesh import smeshBuilder
print('Defining Mesh Components')
print("Defining Mesh Components")
if NEW_SALOME:
smesh = smeshBuilder.New()
@@ -278,13 +305,13 @@ class MODEL:
Regular_1D = bldMesh.Segment()
Local_Length_1 = Regular_1D.LocalLength(meshSize, None, tolLoc)
if buildingShapeType == 'FACE':
if buildingShapeType == "FACE":
NETGEN2D_ONLY = bldMesh.Triangle(algo=smeshBuilder.NETGEN_2D)
NETGEN2D_Pars = NETGEN2D_ONLY.Parameters()
NETGEN2D_Pars.SetMaxSize(meshSize)
NETGEN2D_Pars.SetOptimize(1)
NETGEN2D_Pars.SetFineness(2)
NETGEN2D_Pars.SetMinSize(meshSize/5.0)
NETGEN2D_Pars.SetMinSize(meshSize / 5.0)
NETGEN2D_Pars.SetUseSurfaceCurvature(1)
NETGEN2D_Pars.SetQuadAllowed(1)
NETGEN2D_Pars.SetSecondOrder(0)
@@ -293,102 +320,129 @@ class MODEL:
isDone = bldMesh.Compute()
## Set names of Mesh objects
smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
smesh.SetName(Local_Length_1, 'Local_Length_1')
smesh.SetName(Regular_1D.GetAlgorithm(), "Regular_1D")
smesh.SetName(Local_Length_1, "Local_Length_1")
if buildingShapeType == 'FACE':
smesh.SetName(NETGEN2D_ONLY.GetAlgorithm(), 'NETGEN2D_ONLY')
smesh.SetName(NETGEN2D_Pars, 'NETGEN2D_Pars')
if buildingShapeType == "FACE":
smesh.SetName(NETGEN2D_ONLY.GetAlgorithm(), "NETGEN2D_ONLY")
smesh.SetName(NETGEN2D_Pars, "NETGEN2D_Pars")
smesh.SetName(bldMesh.GetMesh(), 'bldMesh')
smesh.SetName(bldMesh.GetMesh(), "bldMesh")
elapsed_time = time.time() - init_time
init_time += elapsed_time
print('Meshing Operations Completed in %g sec' % (elapsed_time))
print("Meshing Operations Completed in %g sec" % (elapsed_time))
# Define and add groups for all curve and surface members
if len([e for e in elements if e['geometryType'] == 'line']) > 0:
tempgroup = bldMesh.GroupOnGeom(curveCompound, 'CurveMembers', SMESH.EDGE)
smesh.SetName(tempgroup, 'CurveMembers')
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
tempgroup = bldMesh.GroupOnGeom(curveCompound, "CurveMembers", SMESH.EDGE)
smesh.SetName(tempgroup, "CurveMembers")
if len([e for e in elements if e['geometryType'] == 'surface']) > 0:
tempgroup = bldMesh.GroupOnGeom(surfaceCompound, 'SurfaceMembers', SMESH.FACE)
smesh.SetName(tempgroup, 'SurfaceMembers')
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
tempgroup = bldMesh.GroupOnGeom(surfaceCompound, "SurfaceMembers", SMESH.FACE)
smesh.SetName(tempgroup, "SurfaceMembers")
# Define groups in Mesh
for el in elements:
if el['geometryType'] == 'line':
if el["geometryType"] == "line":
shapeType = SMESH.EDGE
if el['geometryType'] == 'surface':
if el["geometryType"] == "surface":
shapeType = SMESH.FACE
tempgroup = bldMesh.GroupOnGeom(el['elemObj'], self.getGroupName(el['ifcName']), shapeType)
smesh.SetName(tempgroup, self.getGroupName(el['ifcName']))
tempgroup = bldMesh.GroupOnGeom(el["elemObj"], self.getGroupName(el["ifcName"]), shapeType)
smesh.SetName(tempgroup, self.getGroupName(el["ifcName"]))
for j,rel in enumerate(el['connections']):
tempgroup = bldMesh.GroupOnGeom(el['connObjs'][j], self.getGroupName(el['ifcName']) + rel['conn_string'] + self.getGroupName(rel['relatedConnection']), SMESH.NODE)
smesh.SetName(tempgroup, self.getGroupName(el['ifcName']) + rel['conn_string'] + self.getGroupName(rel['relatedConnection']))
rel['node'] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
if rel['eccentricity']:
tempgroup = bldMesh.GroupOnGeom(el['linkObjs'][j], self.getGroupName(el['ifcName']) + '_1DR_' + self.getGroupName(rel['relatedConnection']), SMESH.EDGE)
smesh.SetName(tempgroup, self.getGroupName(el['ifcName']) + '_1DR_' + self.getGroupName(rel['relatedConnection']))
for j, rel in enumerate(el["connections"]):
tempgroup = bldMesh.GroupOnGeom(
el["connObjs"][j],
self.getGroupName(el["ifcName"]) + rel["conn_string"] + self.getGroupName(rel["relatedConnection"]),
SMESH.NODE,
)
smesh.SetName(
tempgroup,
self.getGroupName(el["ifcName"]) + rel["conn_string"] + self.getGroupName(rel["relatedConnection"]),
)
rel["node"] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
if rel["eccentricity"]:
tempgroup = bldMesh.GroupOnGeom(
el["linkObjs"][j],
self.getGroupName(el["ifcName"]) + "_1DR_" + self.getGroupName(rel["relatedConnection"]),
SMESH.EDGE,
)
smesh.SetName(
tempgroup,
self.getGroupName(el["ifcName"]) + "_1DR_" + self.getGroupName(rel["relatedConnection"]),
)
tempgroup = bldMesh.GroupOnGeom(el['linkPointObjs'][j][0], self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(el['ifcName']), SMESH.NODE)
smesh.SetName(tempgroup, self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(el['ifcName']))
rel['eccNode'] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
tempgroup = bldMesh.GroupOnGeom(el['linkPointObjs'][j][1], self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(rel['relatedConnection']), SMESH.NODE)
smesh.SetName(tempgroup, self.getGroupName(rel['relatedConnection']) + '_0DC_%g' % rel['index'])
tempgroup = bldMesh.GroupOnGeom(
el["linkPointObjs"][j][0],
self.getGroupName(rel["relatedConnection"]) + "_0DC_" + self.getGroupName(el["ifcName"]),
SMESH.NODE,
)
smesh.SetName(
tempgroup,
self.getGroupName(rel["relatedConnection"]) + "_0DC_" + self.getGroupName(el["ifcName"]),
)
rel["eccNode"] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
tempgroup = bldMesh.GroupOnGeom(
el["linkPointObjs"][j][1],
self.getGroupName(rel["relatedConnection"])
+ "_0DC_"
+ self.getGroupName(rel["relatedConnection"]),
SMESH.NODE,
)
smesh.SetName(tempgroup, self.getGroupName(rel["relatedConnection"]) + "_0DC_%g" % rel["index"])
for conn in connections:
tempgroup = bldMesh.GroupOnGeom(conn['connObj'], self.getGroupName(conn['ifcName']), SMESH.NODE)
smesh.SetName(tempgroup, self.getGroupName(conn['ifcName']))
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ifcName"]), SMESH.NODE)
smesh.SetName(tempgroup, self.getGroupName(conn["ifcName"]))
nodesId = bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)
tempgroup = bldMesh.Add0DElementsToAllNodes(nodesId, self.getGroupName(conn['ifcName']))
smesh.SetName(tempgroup, self.getGroupName(conn['ifcName'] + '_0D'))
if conn['geometryType'] == 'point':
conn['node'] = nodesId.GetIDs()[0]
if conn['geometryType'] == 'line':
tempgroup = bldMesh.GroupOnGeom(conn['connObj'], self.getGroupName(conn['ifcName']), SMESH.EDGE)
smesh.SetName(tempgroup, self.getGroupName(conn['ifcName']))
if conn['geometryType'] == 'surface':
tempgroup = bldMesh.GroupOnGeom(conn['connObj'], self.getGroupName(conn['ifcName']), SMESH.FACE)
smesh.SetName(tempgroup, self.getGroupName(conn['ifcName']))
tempgroup = bldMesh.Add0DElementsToAllNodes(nodesId, self.getGroupName(conn["ifcName"]))
smesh.SetName(tempgroup, self.getGroupName(conn["ifcName"] + "_0D"))
if conn["geometryType"] == "point":
conn["node"] = nodesId.GetIDs()[0]
if conn["geometryType"] == "line":
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ifcName"]), SMESH.EDGE)
smesh.SetName(tempgroup, self.getGroupName(conn["ifcName"]))
if conn["geometryType"] == "surface":
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ifcName"]), SMESH.FACE)
smesh.SetName(tempgroup, self.getGroupName(conn["ifcName"]))
# create 1D SEG2 spring elements
for el in elements:
for j,rel in enumerate(el['connections']):
conn = [c for c in connections if c['ifcName'] == rel['relatedConnection']][0]
if conn['geometryType'] == 'point':
grpName = bldMesh.CreateEmptyGroup(SMESH.EDGE, self.getGroupName(el['ifcName']) + '_1DS_' + self.getGroupName(rel['relatedConnection']))
smesh.SetName(grpName, self.getGroupName(el['ifcName']) + '_1DS_' + self.getGroupName(rel['relatedConnection']))
if not rel['eccentricity']:
conn = [conn for conn in connections if conn['ifcName'] == rel['relatedConnection']][0]
grpName.Add([bldMesh.AddEdge([conn['node'], rel['node']])])
for j, rel in enumerate(el["connections"]):
conn = [c for c in connections if c["ifcName"] == rel["relatedConnection"]][0]
if conn["geometryType"] == "point":
grpName = bldMesh.CreateEmptyGroup(
SMESH.EDGE,
self.getGroupName(el["ifcName"]) + "_1DS_" + self.getGroupName(rel["relatedConnection"]),
)
smesh.SetName(
grpName,
self.getGroupName(el["ifcName"]) + "_1DS_" + self.getGroupName(rel["relatedConnection"]),
)
if not rel["eccentricity"]:
conn = [conn for conn in connections if conn["ifcName"] == rel["relatedConnection"]][0]
grpName.Add([bldMesh.AddEdge([conn["node"], rel["node"]])])
else:
grpName.Add([bldMesh.AddEdge([rel['eccNode'], rel['node']])])
grpName.Add([bldMesh.AddEdge([rel["eccNode"], rel["node"]])])
self.mesh = bldMesh
self.meshNodes = bldMesh.GetNodesId()
elapsed_time = time.time() - init_time
init_time += elapsed_time
print('Mesh Groups Defined in %g sec' % (elapsed_time))
print("Mesh Groups Defined in %g sec" % (elapsed_time))
try:
if NEW_SALOME:
bldMesh.ExportMED(
self.medFilename,
auto_groups = 0,
minor = 40,
overwrite = 1,
meshPart = None,
autoDimension = 0
self.medFilename, auto_groups=0, minor=40, overwrite=1, meshPart=None, autoDimension=0
)
else:
bldMesh.ExportMED(self.medFilename, 0, SMESH.MED_V2_2, 1, None, 0)
except:
print('ExportMED() failed. Invalid file name?')
print("ExportMED() failed. Invalid file name?")
if salome.sg.hasDesktop():
if NEW_SALOME:
@@ -397,16 +451,17 @@ class MODEL:
salome.sg.updateObjBrowser(1)
elapsed_time = init_time - start_time
print('ALL Operations Completed in %g sec' % (elapsed_time))
print("ALL Operations Completed in %g sec" % (elapsed_time))
if __name__ == '__main__':
fileNames = ['structure_01']
if __name__ == "__main__":
fileNames = ["structure_01"]
files = fileNames
meshSize = 0.1
for fileName in files:
BASE_PATH = '/home/jesusbill/Dev-Projects/github.com/IfcOpenShell/analysis-models/models/'
DATAFILENAME = BASE_PATH + fileName + '/' + fileName + '.json'
MEDFILENAME = BASE_PATH + fileName + '/' + fileName + '.med'
BASE_PATH = "/home/jesusbill/Dev-Projects/github.com/IfcOpenShell/analysis-models/models/"
DATAFILENAME = BASE_PATH + fileName + "/" + fileName + ".json"
MEDFILENAME = BASE_PATH + fileName + "/" + fileName + ".med"
model = MODEL(DATAFILENAME, MEDFILENAME, meshSize)