Advertisement
Guest User

Untitled

a guest
Apr 2nd, 2020
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.11 KB | None | 0 0
  1. class PipeGeom:
  2. @staticmethod
  3. def GetPipeDiameter(elementid):
  4. """
  5. Get Diameter by circular face
  6. Args: elementid
  7. Return: Diameter(number) in meter
  8. """
  9.  
  10. if not ("segment" in str(GetObjectByElementId(elementid).ElementData["elementtype"]).lower()):
  11. print "expected segment, got "+ GetObjectByElementId(elementid).ElementData["elementtype"]
  12. return None
  13.  
  14. diameter = 0
  15. circleFaces = PipeGeom.GetCircularFaces(elementid)
  16.  
  17. if circleFaces:
  18. for i in circleFaces:
  19. if i['centroid'] is not None:
  20. cntrPnt = i['centroid']
  21. outerPnt = i['face'].OuterVertices[0]
  22. currDiam = (LineSegment3D(cntrPnt, outerPnt).extent) * 2
  23. # GET THE SMALLEST DIAMETER. POSSIBLE THAT 1 PIPE HAVE DIFFERENT CIRCLE FACE
  24. if diameter == 0:
  25. diameter = currDiam
  26. else:
  27. if currDiam < diameter:
  28. diameter = currDiam
  29. else:
  30. faceP = i['face']
  31. if type(faceP) == Polyhedron:
  32. # GET DIAMETER: BY GETTING THE LONGESTLINE IN BROKEN FACES
  33. # 2 POINTS NEAR HIGHPOS AND LOWPOS OF faceP.boundingBox
  34. highPnt = faceP.boundingBox.LLB
  35. lowPnt = faceP.boundingBox.URT
  36.  
  37. pnt1 = Point3D()
  38. pnt2 = Point3D()
  39. nearDist1 = sys.float_info.epsilon
  40. nearDist2 = sys.float_info.epsilon
  41.  
  42. pntL = faceP.Vertices
  43. for pnt in pntL:
  44. currDist1 = Point3D().sqDistance(pnt, highPnt)
  45. currDist2 = Point3D().sqDistance(pnt, lowPnt)
  46.  
  47. if nearDist1 == sys.float_info.epsilon:
  48. nearDist1 = currDist1
  49. else:
  50. if nearDist1 > currDist1:
  51. nearDist1 = currDist1
  52. pnt1 = pnt
  53.  
  54. if nearDist2 == sys.float_info.epsilon:
  55. nearDist2 = currDist2
  56. else:
  57. if nearDist2 > currDist2:
  58. nearDist2 = currDist2
  59. pnt2 = pnt
  60.  
  61. diameter = Point3D().distance(pnt1, pnt2)
  62.  
  63. return diameter
  64.  
  65. @staticmethod
  66. def GetCircularFaces(elementid):
  67. """
  68. Get circular face using IsFaceCircular API or using broken faces near portlocation (alternative solution)
  69. Args: elementid
  70. Return: List["face":(Face3D), "centroid":(Point3D)]
  71. """
  72.  
  73. query = """SELECT topo.polygon, topo.centroid, port.connectingportlocation
  74. FROM bimrl_topo_face topo, bimrl_relconnection port
  75. WHERE topo.elementid = '{0}' AND topo.type = 'BODY'
  76. AND topo.elementid = port.connectingelementid""".format(elementid)
  77.  
  78. qResult = FXBIMRL.GetJsonObjFromQuery(query)
  79. if qResult is None: return None
  80.  
  81. circleFaces = []
  82. # GET CIRCULAR FACE USING IsFaceCircular API
  83. circleFaces = filter(lambda x: FXGeometry.IsFaceCircular(FXGeometry.CreatePolygonFace(x["polygon"]), 0.1), qResult["Table1"])
  84.  
  85. if len(circleFaces) > 0:
  86. circleFaces = map(lambda x: {
  87. "face": FXGeometry.CreatePolygonFace(x["polygon"]),
  88. "centroid": Point3D(x["centroid"]["X"], x["centroid"]["Y"], x["centroid"]["Z"]) },
  89. circleFaces)
  90. return circleFaces
  91.  
  92. # GET CIRCULAR FACE USING BROKEN FACES NEAR PORTLOCATION (ALTERNATIVE SOLUTION)
  93. faceL = List[Face3D]()
  94. portL = []
  95. for row in qResult["Table1"]:
  96. face = FXGeometry.CreatePolygonFace(row["polygon"])
  97. faceL.Add(face)
  98. portL.append(Point3D(row["connectingportlocation"]["X"], row["connectingportlocation"]["Y"], row["connectingportlocation"]["Z"]))
  99.  
  100. faceNearPort = {}
  101. portL = list(set(portL))
  102.  
  103. # GET FACES NEAR PORTLOCATION
  104. for face in faceL:
  105. portNearFace = None
  106. centerPnt = face.boundingBox.Center
  107. distTemp = sys.float_info.epsilon
  108. for port in portL:
  109. currDist = Point3D().sqDistance(port, centerPnt)
  110. if distTemp == sys.float_info.epsilon:
  111. distTemp = currDist
  112. portNearFace = port
  113. else:
  114. if distTemp > currDist:
  115. distTemp = currDist
  116. portNearFace = port
  117.  
  118. if portNearFace:
  119. if faceNearPort.get(portNearFace) is None:
  120. tempL = []
  121. faceNearPort[portNearFace] = tempL
  122.  
  123. faceNearPort[portNearFace].append(face)
  124.  
  125. for port, faceL in faceNearPort.items():
  126.  
  127. # SORT BY FACES NORMAL
  128. faceDict = {}
  129. for face in faceL:
  130. fNormal = round(face.basePlane.normalVector.Z,1)
  131. if faceDict.get(fNormal) is None:
  132. tempL = []
  133. faceDict[fNormal] = tempL
  134.  
  135. faceDict[fNormal].append(face)
  136.  
  137. # GET THE NORMAL WITH MANY FACES
  138. maxCntFace = 0
  139. maxFaceL = List[Face3D]()
  140. for _, faces in faceDict.iteritems():
  141. if maxCntFace < len(faces):
  142. maxCntFace = len(faces)
  143. for face in faces:
  144. maxFaceL.Add(face)
  145.  
  146. lastFacePoly = Polyhedron(maxFaceL)
  147. if lastFacePoly.IsSolid:
  148. circleFaces.append(
  149. { "face": lastFacePoly, "centroid": None })
  150. break
  151.  
  152. return circleFaces
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement