From d1f1f81fffba91c795583db2d895835a02e1cc4b Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Sat, 10 Aug 2019 13:03:13 +0200 Subject: [PATCH] Arch: IFC import, move recycler class around --- src/Mod/Arch/importIFC.py | 383 +++++++++++++++++++------------------- 1 file changed, 192 insertions(+), 191 deletions(-) diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index c51a7c8520..bdd8965fe0 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -1298,197 +1298,6 @@ def getIfcProperties(ifcfile, pid, psets, d): return d -class recycler: - - "the compression engine - a mechanism to reuse ifc entities if needed" - - # this object has some methods identical to corresponding ifcopenshell methods, - # but it checks if a similar entity already exists before creating a new one - # to compress a new type, just add the necessary method here - - def __init__(self,ifcfile): - - self.ifcfile = ifcfile - self.compress = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("ifcCompress",True) - self.cartesianpoints = {(0,0,0):self.ifcfile[8]} # from template - self.directions = {(1,0,0):self.ifcfile[6],(0,0,1):self.ifcfile[7],(0,1,0):self.ifcfile[10]} # from template - self.polylines = {} - self.polyloops = {} - self.propertysinglevalues = {} - self.axis2placement3ds = {'(0.0, 0.0, 0.0)(0.0, 0.0, 1.0)(1.0, 0.0, 0.0)':self.ifcfile[9]} # from template - self.axis2placement2ds = {} - self.localplacements = {} - self.rgbs = {} - self.ssrenderings = {} - self.sstyles = {} - self.transformationoperators = {} - self.psas = {} - self.spared = 0 - - def createIfcCartesianPoint(self,points): - if self.compress and points in self.cartesianpoints: - self.spared += 1 - return self.cartesianpoints[points] - else: - c = self.ifcfile.createIfcCartesianPoint(points) - if self.compress: - self.cartesianpoints[points] = c - return c - - def createIfcDirection(self,points): - if self.compress and points in self.directions: - self.spared += 1 - return self.directions[points] - else: - c = self.ifcfile.createIfcDirection(points) - if self.compress: - self.directions[points] = c - return c - - def createIfcPolyline(self,points): - key = "".join([str(p.Coordinates) for p in points]) - if self.compress and key in self.polylines: - self.spared += 1 - return self.polylines[key] - else: - c = self.ifcfile.createIfcPolyline(points) - if self.compress: - self.polylines[key] = c - return c - - def createIfcPolyLoop(self,points): - key = "".join([str(p.Coordinates) for p in points]) - if self.compress and key in self.polyloops: - self.spared += 1 - return self.polyloops[key] - else: - c = self.ifcfile.createIfcPolyLoop(points) - if self.compress: - self.polyloops[key] = c - return c - - def createIfcPropertySingleValue(self,name,ptype,pvalue): - key = str(name) + str(ptype) + str(pvalue) - if self.compress and key in self.propertysinglevalues: - self.spared += 1 - return self.propertysinglevalues[key] - else: - if isinstance(pvalue,float) and pvalue < 0.000000001: # remove the exp notation that some bim apps hate - pvalue = 0 - c = self.ifcfile.createIfcPropertySingleValue(name,None,ifcfile.create_entity(ptype,pvalue),None) - if self.compress: - self.propertysinglevalues[key] = c - return c - - def createIfcAxis2Placement3D(self,p1,p2,p3): - if p2: - tp2 = str(p2.DirectionRatios) - else: - tp2 = "None" - if p3: - tp3 = str(p3.DirectionRatios) - else: - tp3 = "None" - key = str(p1.Coordinates) + tp2 + tp3 - if self.compress and key in self.axis2placement3ds: - self.spared += 1 - return self.axis2placement3ds[key] - else: - c = self.ifcfile.createIfcAxis2Placement3D(p1,p2,p3) - if self.compress: - self.axis2placement3ds[key] = c - return c - - def createIfcAxis2Placement2D(self,p1,p2): - key = str(p1.Coordinates) + str(p2.DirectionRatios) - if self.compress and key in self.axis2placement2ds: - self.spared += 1 - return self.axis2placement2ds[key] - else: - c = self.ifcfile.createIfcAxis2Placement2D(p1,p2) - if self.compress: - self.axis2placement2ds[key] = c - return c - - def createIfcLocalPlacement(self,gpl): - key = str(gpl.Location.Coordinates) + str(gpl.Axis.DirectionRatios) + str(gpl.RefDirection.DirectionRatios) - if self.compress and key in self.localplacements: - self.spared += 1 - return self.localplacements[key] - else: - c = self.ifcfile.createIfcLocalPlacement(None,gpl) - if self.compress: - self.localplacements[key] = c - return c - - def createIfcColourRgb(self,r,g,b): - key = (r,g,b) - if self.compress and key in self.rgbs: - self.spared += 1 - return self.rgbs[key] - else: - c = self.ifcfile.createIfcColourRgb(None,r,g,b) - if self.compress: - self.rgbs[key] = c - return c - - def createIfcSurfaceStyleRendering(self,col,trans=0): - key = (col.Red,col.Green,col.Blue,trans) - if self.compress and key in self.ssrenderings: - self.spared += 1 - return self.ssrenderings[key] - else: - if trans == 0: - trans = None - c = self.ifcfile.createIfcSurfaceStyleRendering(col,trans,None,None,None,None,None,None,"FLAT") - if self.compress: - self.ssrenderings[key] = c - return c - - def createIfcCartesianTransformationOperator3D(self,axis1,axis2,origin,scale,axis3): - key = str(axis1.DirectionRatios) + str(axis2.DirectionRatios) + str(origin.Coordinates) + str(scale) + str(axis3.DirectionRatios) - if self.compress and key in self.transformationoperators: - self.spared += 1 - return self.transformationoperators[key] - else: - c = self.ifcfile.createIfcCartesianTransformationOperator3D(axis1,axis2,origin,scale,axis3) - if self.compress: - self.transformationoperators[key] = c - return c - - def createIfcSurfaceStyle(self,name,r,g,b,t=0): - if name: - key = name + str((r,g,b)) - else: - key = str((r,g,b)) - if self.compress and key in self.sstyles: - self.spared += 1 - return self.sstyles[key] - else: - col = self.createIfcColourRgb(r,g,b) - ssr = self.createIfcSurfaceStyleRendering(col,t) - c = self.ifcfile.createIfcSurfaceStyle(name,"BOTH",[ssr]) - if self.compress: - self.sstyles[key] = c - return c - - def createIfcPresentationStyleAssignment(self,name,r,g,b,t=0): - if name: - key = name+str((r,g,b,t)) - else: - key = str((r,g,b,t)) - if self.compress and key in self.psas: - self.spared += 1 - return self.psas[key] - else: - iss = self.createIfcSurfaceStyle(name,r,g,b,t) - c = self.ifcfile.createIfcPresentationStyleAssignment([iss]) - if self.compress: - self.psas[key] = c - return c - - -# ************************************************************************************************ def createFromProperties(propsets,ifcfile): "creates a FreeCAD parametric object from a set of properties" @@ -1780,3 +1589,195 @@ def getScaling(ifcfile): elif u.is_a("IfcSIUnit") or u.is_a("IfcUnit"): return getUnit(u) return 1.0 + + +# ************************************************************************************************ +# ********** classes ************** +class recycler: + + "the compression engine - a mechanism to reuse ifc entities if needed" + + # this object has some methods identical to corresponding ifcopenshell methods, + # but it checks if a similar entity already exists before creating a new one + # to compress a new type, just add the necessary method here + + def __init__(self,ifcfile): + + self.ifcfile = ifcfile + self.compress = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("ifcCompress",True) + self.cartesianpoints = {(0,0,0):self.ifcfile[8]} # from template + self.directions = {(1,0,0):self.ifcfile[6],(0,0,1):self.ifcfile[7],(0,1,0):self.ifcfile[10]} # from template + self.polylines = {} + self.polyloops = {} + self.propertysinglevalues = {} + self.axis2placement3ds = {'(0.0, 0.0, 0.0)(0.0, 0.0, 1.0)(1.0, 0.0, 0.0)':self.ifcfile[9]} # from template + self.axis2placement2ds = {} + self.localplacements = {} + self.rgbs = {} + self.ssrenderings = {} + self.sstyles = {} + self.transformationoperators = {} + self.psas = {} + self.spared = 0 + + def createIfcCartesianPoint(self,points): + if self.compress and points in self.cartesianpoints: + self.spared += 1 + return self.cartesianpoints[points] + else: + c = self.ifcfile.createIfcCartesianPoint(points) + if self.compress: + self.cartesianpoints[points] = c + return c + + def createIfcDirection(self,points): + if self.compress and points in self.directions: + self.spared += 1 + return self.directions[points] + else: + c = self.ifcfile.createIfcDirection(points) + if self.compress: + self.directions[points] = c + return c + + def createIfcPolyline(self,points): + key = "".join([str(p.Coordinates) for p in points]) + if self.compress and key in self.polylines: + self.spared += 1 + return self.polylines[key] + else: + c = self.ifcfile.createIfcPolyline(points) + if self.compress: + self.polylines[key] = c + return c + + def createIfcPolyLoop(self,points): + key = "".join([str(p.Coordinates) for p in points]) + if self.compress and key in self.polyloops: + self.spared += 1 + return self.polyloops[key] + else: + c = self.ifcfile.createIfcPolyLoop(points) + if self.compress: + self.polyloops[key] = c + return c + + def createIfcPropertySingleValue(self,name,ptype,pvalue): + key = str(name) + str(ptype) + str(pvalue) + if self.compress and key in self.propertysinglevalues: + self.spared += 1 + return self.propertysinglevalues[key] + else: + if isinstance(pvalue,float) and pvalue < 0.000000001: # remove the exp notation that some bim apps hate + pvalue = 0 + c = self.ifcfile.createIfcPropertySingleValue(name,None,ifcfile.create_entity(ptype,pvalue),None) + if self.compress: + self.propertysinglevalues[key] = c + return c + + def createIfcAxis2Placement3D(self,p1,p2,p3): + if p2: + tp2 = str(p2.DirectionRatios) + else: + tp2 = "None" + if p3: + tp3 = str(p3.DirectionRatios) + else: + tp3 = "None" + key = str(p1.Coordinates) + tp2 + tp3 + if self.compress and key in self.axis2placement3ds: + self.spared += 1 + return self.axis2placement3ds[key] + else: + c = self.ifcfile.createIfcAxis2Placement3D(p1,p2,p3) + if self.compress: + self.axis2placement3ds[key] = c + return c + + def createIfcAxis2Placement2D(self,p1,p2): + key = str(p1.Coordinates) + str(p2.DirectionRatios) + if self.compress and key in self.axis2placement2ds: + self.spared += 1 + return self.axis2placement2ds[key] + else: + c = self.ifcfile.createIfcAxis2Placement2D(p1,p2) + if self.compress: + self.axis2placement2ds[key] = c + return c + + def createIfcLocalPlacement(self,gpl): + key = str(gpl.Location.Coordinates) + str(gpl.Axis.DirectionRatios) + str(gpl.RefDirection.DirectionRatios) + if self.compress and key in self.localplacements: + self.spared += 1 + return self.localplacements[key] + else: + c = self.ifcfile.createIfcLocalPlacement(None,gpl) + if self.compress: + self.localplacements[key] = c + return c + + def createIfcColourRgb(self,r,g,b): + key = (r,g,b) + if self.compress and key in self.rgbs: + self.spared += 1 + return self.rgbs[key] + else: + c = self.ifcfile.createIfcColourRgb(None,r,g,b) + if self.compress: + self.rgbs[key] = c + return c + + def createIfcSurfaceStyleRendering(self,col,trans=0): + key = (col.Red,col.Green,col.Blue,trans) + if self.compress and key in self.ssrenderings: + self.spared += 1 + return self.ssrenderings[key] + else: + if trans == 0: + trans = None + c = self.ifcfile.createIfcSurfaceStyleRendering(col,trans,None,None,None,None,None,None,"FLAT") + if self.compress: + self.ssrenderings[key] = c + return c + + def createIfcCartesianTransformationOperator3D(self,axis1,axis2,origin,scale,axis3): + key = str(axis1.DirectionRatios) + str(axis2.DirectionRatios) + str(origin.Coordinates) + str(scale) + str(axis3.DirectionRatios) + if self.compress and key in self.transformationoperators: + self.spared += 1 + return self.transformationoperators[key] + else: + c = self.ifcfile.createIfcCartesianTransformationOperator3D(axis1,axis2,origin,scale,axis3) + if self.compress: + self.transformationoperators[key] = c + return c + + def createIfcSurfaceStyle(self,name,r,g,b,t=0): + if name: + key = name + str((r,g,b)) + else: + key = str((r,g,b)) + if self.compress and key in self.sstyles: + self.spared += 1 + return self.sstyles[key] + else: + col = self.createIfcColourRgb(r,g,b) + ssr = self.createIfcSurfaceStyleRendering(col,t) + c = self.ifcfile.createIfcSurfaceStyle(name,"BOTH",[ssr]) + if self.compress: + self.sstyles[key] = c + return c + + def createIfcPresentationStyleAssignment(self,name,r,g,b,t=0): + if name: + key = name+str((r,g,b,t)) + else: + key = str((r,g,b,t)) + if self.compress and key in self.psas: + self.spared += 1 + return self.psas[key] + else: + iss = self.createIfcSurfaceStyle(name,r,g,b,t) + c = self.ifcfile.createIfcPresentationStyleAssignment([iss]) + if self.compress: + self.psas[key] = c + return c