Advertisement
Guest User

Untitled

a guest
Apr 1st, 2020
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.24 KB | None | 0 0
  1. """
  2. Implemented by: Aires Marco S. Ladaga ??/03/2020
  3. Description:
  4. Consolidated SSW 4.3.1 (d) (ii), SSW 4.3.1 (d) (iii) and SSW 4.3.1 (d) (iv)
  5. ToDo:
  6.  
  7. Updated by: --
  8. Description: --
  9. ToDo: --
  10. """
  11.  
  12. import json
  13. import threading
  14. from json import encoder #<< Python Library; Including the python module>>
  15.  
  16.  
  17. def ModifyTableStructure(queryArr):#creates Dictionary, with mainElement GUID as index, with value of --> table of table of items
  18. modifiedIndexTbl = {}
  19.  
  20. for ele in queryArr["Table1"]:
  21. icGUID, siteGUID, wallGUID = ele["elementid"], ele["siteid"], ele["wallid"]
  22.  
  23. if icGUID is not None:
  24. val = modifiedIndexTbl.get(icGUID) #Check if index eleGUID is available. if None, will create one and add list under it
  25.  
  26. if val is None:
  27. tempTbl = []
  28. modifiedIndexTbl[icGUID] = tempTbl
  29.  
  30. modifiedIndexTbl[icGUID].append([siteGUID, wallGUID])
  31.  
  32. return modifiedIndexTbl
  33.  
  34.  
  35. def main():
  36. BindCheckFunc("CheckRule")
  37. RunPipeLine()
  38.  
  39.  
  40. def CheckRule():
  41. inspectionChamberQuery = GetQueryByElementGroupName("Inspection chamber")
  42. pipeQuery = GetQueryByElementGroupName("Pipe")
  43. manholeQuery = GetQueryByElementGroupName("Manhole")
  44. junctionQuery = GetQueryByElementGroupName("Junction")
  45. siteQuery = GetQueryByElementGroupName("Site")
  46. boundaryWallQuery = GetQueryByElementGroupName("Boundary wall")
  47.  
  48. queryEle = """select distinct allele.* from(
  49. select ic.elementid , 'ic' as separator from(
  50. """+inspectionChamberQuery+"""
  51. )ic
  52. UNION
  53. select pipe.elementid , 'pipe' as separator from(
  54. """+pipeQuery+"""
  55. )pipe
  56. UNION
  57. select manhole.elementid , 'manhole' as separator from(
  58. """+manholeQuery+"""
  59. )manhole
  60. UNION
  61. select junction.elementid , 'junction' as separator from(
  62. """+junctionQuery+"""
  63. )junction
  64. )allele"""
  65.  
  66. queryDIIChecking = """
  67. select distinct ic.elementid, site.siteid, wall.wallid from(
  68. select ic.elementid, sp.xminbound, sp.xmaxbound, sp.yminbound, sp.ymaxbound from(
  69. """+inspectionChamberQuery+"""
  70. )ic inner join bimrl_spatialindex sp
  71. on ic.elementid = sp.elementid
  72. )ic left join
  73. (
  74. select site.elementid as siteid, spforsite.xminbound, spforsite.xmaxbound, spforsite.yminbound, spforsite.ymaxbound from(
  75. """+siteQuery+"""
  76. )site inner join bimrl_spatialindex spforsite
  77. on site.elementid = spforsite.elementid
  78. )site on ic.xminbound = site.xminbound
  79. and ic.xmaxbound = site.xmaxbound
  80. and ic.yminbound = site.yminbound
  81. and ic.ymaxbound = site.ymaxbound
  82. inner join bimrl_spatialindex spforwall
  83. on site.siteid = spforwall.elementid
  84. left join
  85. (
  86. select wall.elementid as wallid, sp.xminbound, sp.xmaxbound, sp.yminbound, sp.ymaxbound from(
  87. """+boundaryWallQuery+"""
  88. )wall inner join bimrl_spatialindex sp
  89. on wall.elementid = sp.elementid
  90. )wall on spforwall.xminbound = wall.xminbound
  91. and spforwall.xmaxbound = wall.xmaxbound
  92. and spforwall.yminbound = wall.yminbound
  93. and spforwall.ymaxbound = wall.ymaxbound
  94. """
  95.  
  96. queryHighestLowestElev = """select worldbbox[1]::point3d as wordlowpos, worldbbox[2]::point3d as worldhighpos
  97. from bimrl_federatedmodel
  98. where federatedid = '"""+str(GetFederatedId())+"""'"""
  99.  
  100.  
  101. eleQueryArr = FXBIMRL.GetJsonObjFromQuery(queryEle)
  102. DIIQueryArr = FXBIMRL.GetJsonObjFromQuery(queryDIIChecking)
  103. worldbboxArr = FXBIMRL.GetJsonObjFromQuery(queryHighestLowestElev)
  104.  
  105. icTbl, sewerJuncTbl, sewerPipeTbl, manholeTbl = list(), list(), list(), list()
  106. icDictSiteWall = ModifyTableStructure(DIIQueryArr)
  107. worldBBoxLP = worldbboxArr["Table1"][0]["wordlowpos"]
  108. worldBBoxHP = worldbboxArr["Table1"][0]["worldhighpos"]
  109.  
  110.  
  111. for tbl in eleQueryArr["Table1"]:
  112. guid = tbl["elementid"]
  113. eleSeparator = tbl["separator"]
  114.  
  115. if eleSeparator == "ic": icTbl.append(guid)
  116. elif eleSeparator == "pipe": sewerPipeTbl.append(guid)
  117. elif eleSeparator == "manhole": manholeTbl.append(guid)
  118. elif eleSeparator == "junction": sewerJuncTbl.append(guid)
  119.  
  120. GenerateSysGraph(2)
  121. sewerConTbl, lastICTable, lastMHTable, backDropTbl = GetSewerConnection(icTbl, manholeTbl, sewerJuncTbl)
  122.  
  123. if lastICTable:
  124. for index, lastIcGuid in enumerate(lastICTable):
  125. icExtrude, icPolyhedron, icProjection = GetExtrusionFromLowestToHighest(lastIcGuid, worldBBoxHP["Z"], worldBBoxLP["Z"])
  126.  
  127. icMidPnt = icPolyhedron.boundingBox.Center
  128. eleObj = GetObjectByElementId(lastIcGuid)
  129. thisSewerConTbl = sewerConTbl[index]
  130.  
  131. lastELeToPublicSewerGUID = lastMHTable[index]
  132. lastEleToPublicSewerObj = GetObjectByElementId(lastELeToPublicSewerGUID)
  133. lastElePredef = lastEleToPublicSewerObj.TypeData["predefinedtype"]
  134.  
  135. # sewerConDiam = PipeGeom.GetPipeDiameter(thisSewerConTbl[0])*1000
  136.  
  137. listOfListSiteWall = icDictSiteWall.get(lastIcGuid)
  138. print lastElePredef
  139. if lastElePredef == "MANHOLE":
  140. for sewerConGUID in thisSewerConTbl:
  141. sewerConObj = GetObjectByElementId(sewerConGUID)
  142. sewerConDiam = round(PipeGeom.GetPipeDiameter(sewerConGUID)*1000)
  143. pipeStatus = filter(lambda x:x["propertyname"] == "Status", sewerConObj.PropertyTable)
  144. pipeStatus = ", ".join([str(x) for x in pipeStatus]) #join with separator works well with str
  145.  
  146. if pipeStatus and "new" in pipeStatus.lower():
  147. if sewerConDiam >= 200:
  148. print lastIcGuid,sewerConGUID,sewerConDiam,"Compliant"
  149. else:
  150. print lastIcGuid,sewerConGUID,sewerConDiam,"NC"
  151.  
  152. pipeMaterial = map(lambda x:x["materialname"], sewerConObj.MaterialTable)
  153. pipeMaterial = ", ".join([str(x) for x in pipeMaterial]) #join with separator works well with str
  154.  
  155. if "upvc" not in pipeMaterial.lower():
  156. print lastIcGuid,sewerConGUID,pipeMaterial,"Compliant"
  157. else:
  158. print lastIcGuid,sewerConGUID,pipeMaterial,"NC"
  159. else:
  160. print lastIcGuid,sewerConGUID,"NOT NEW"
  161. elif lastElePredef == "JUNCTION":
  162. yJuncPublicSewer = GetConnectedPipe(lastELeToPublicSewerGUID)
  163. yJuncPublicSewer = [guid for guid in yJuncPublicSewer if guid not in thisSewerConTbl]
  164. if len(yJuncPublicSewer) > 0:
  165. yJuncPublicSewerDiam = list(set([round(PipeGeom.GetPipeDiameter(guid)*1000) for guid in yJuncPublicSewer]))
  166.  
  167. if len(yJuncPublicSewerDiam) == 1:
  168. for sewerConGUID in thisSewerConTbl:
  169. sewerConObj = GetObjectByElementId(sewerConGUID)
  170. sewerConDiam = round(PipeGeom.GetPipeDiameter(sewerConGUID)*1000)
  171.  
  172. if sewerConDiam == yJuncPublicSewerDiam[0]:
  173. print (lastIcGuid,sewerConGUID, "Compliant same diam", sewerConDiam, yJuncPublicSewerDiam[0])
  174. print ("SHJALL follow material")
  175. else:
  176. print (lastIcGuid,sewerConGUID, "NC not same diam",sewerConDiam, yJuncPublicSewerDiam[0])
  177. else:
  178. print (lastIcGuid, yJuncPublicSewerDiam, "INCONSISTENT public sewer diameter")
  179. else:
  180. print (lastELeToPublicSewerGUID, "No connected public sewer")
  181.  
  182. dictSiteWithWall = dict()
  183. trueDictSiteAboveICWithWall = dict()
  184.  
  185. for tbl in listOfListSiteWall:#Modify data to dict, index = siteGUID value = listOfWalls
  186. siteGUID, bounaryWallGUID = tbl[0], tbl[1]
  187. if siteGUID is not None:
  188. if dictSiteWithWall.get(siteGUID) is None:
  189. tempTbl = list()
  190. dictSiteWithWall[siteGUID] = tempTbl
  191. if bounaryWallGUID is not None:
  192. dictSiteWithWall[siteGUID].append(bounaryWallGUID)
  193. # dictSiteWithWall = { for tbl in listOfListSiteWall if tbl[0] is not }
  194. sitePartialCoverTbl = list()#site partially covering IC
  195. # siteTotallyCoveredTbl = list()#site totally covering IC
  196. for siteGUID,tblWall in dictSiteWithWall.items(): #Use geometry to validate if Site if Intersecting to IC, and Site if intersecting to Wall, since all are still candidates
  197. #CHANGE EXTRUDE FROM ALLBOTTOMFACES
  198. siteExtrude, sitePolyhedron, siteProjection = GetExtrusionFromLowestToHighest(siteGUID, worldBBoxHP["Z"], worldBBoxLP["Z"])
  199. if FXGeometry.IsIntersectOrInside(icExtrude, sitePolyhedron):
  200. if checkSubtractedPrj(icProjection, siteProjection): #check if site if fully covering IC via projection
  201. trueTblWall = list()
  202. print tblWall
  203. for wallGUID in tblWall:
  204. wallPolyhed = FXGeometry.GetGeometryBodyByGUID(wallGUID)
  205. # CheckReport.DisplayResult("Attention", eleObj, "Elements to check are not provided.", None)
  206. # CheckReport.AddRelatedGeometry(wallPolyhed, "obb", "1,1,0", "W")
  207. # CheckReport.AddRelatedGeometry(siteExtrude, "obb", "1,1,0", "W")
  208.  
  209. if FXGeometry.IsIntersectOrInside(siteExtrude, wallPolyhed):
  210. trueTblWall.append([wallGUID, wallPolyhed])
  211. trueDictSiteAboveICWithWall[siteGUID] = [trueTblWall, siteProjection]
  212. else:
  213. sitePartialCoverTbl.append(siteGUID)
  214.  
  215. if sitePartialCoverTbl:
  216. print ("SITE PARTIALLY COVERING IC ", sitePartialCoverTbl)
  217. else:
  218. sewerConLine = PipeGeom.GetPipeCenterLine(thisSewerConTbl[0])
  219. pointDisToIcMid = {Point3D().sqDistance(pnt, icMidPnt):pnt for pnt in [sewerConLine.startPoint, sewerConLine.endPoint]}
  220. sortedPoint = [Point3D(pointDisToIcMid[i].X, pointDisToIcMid[i].Y, 0) for i in sorted(pointDisToIcMid)]
  221. modifiedSewerConLine = LineSegment3D(sortedPoint[0], sortedPoint[1])
  222. #worldBBoxDiagDist value will used to extend to sewerConLine, for Line to Line intersection
  223. worldBBoxDiagDist = LineSegment3D(Point3D(worldBBoxLP["X"], worldBBoxLP["Y"],0), Point3D(worldBBoxHP["X"], worldBBoxHP["Y"],0)).extent
  224. modifiedSewerConLine.extendAtEnd(worldBBoxDiagDist)
  225.  
  226. closestBoundaryDist = None
  227. closestBoundaryDistArrow = None
  228. print (trueDictSiteAboveICWithWall)
  229. for siteGUID, tbl in trueDictSiteAboveICWithWall.items():
  230. tblWallWithPolyhed = tbl[0]
  231. sitePrj = tbl[1]
  232.  
  233. if tblWallWithPolyhed:
  234. polyList = List[Polyhedron]()
  235. for tbl in tblWallWithPolyhed:
  236. polyList.Add(tbl[1])
  237. boundaryWallprj = FXGeometry.GetProjection(polyList, 0) #create projection to lowest elevation
  238. print (boundaryWallprj)
  239. for face in boundaryWallprj:
  240.  
  241. print "wall",face.OuterAndInnerBoundaries, icMidPnt, closestBoundaryDist, closestBoundaryDistArrow
  242. closestBoundaryDist, closestBoundaryDistArrow = GetClosestDistance(modifiedSewerConLine, face.OuterAndInnerBoundaries, icMidPnt, closestBoundaryDist, closestBoundaryDistArrow)
  243.  
  244. for face in sitePrj:
  245. print "site", face.OuterAndInnerBoundaries, icMidPnt, closestBoundaryDist, closestBoundaryDistArrow
  246. closestBoundaryDist, closestBoundaryDistArrow = GetClosestDistance(modifiedSewerConLine, face.OuterAndInnerBoundaries, icMidPnt, closestBoundaryDist, closestBoundaryDistArrow)
  247.  
  248.  
  249. # intersect line3dSegment to line3dSegment, by lengh of worldBBox
  250. # dictSiteWithWall = { for siteGUID, tblWall in enumerate(dictSiteWithWall) }
  251.  
  252.  
  253. else:
  254. print ("Last ic is not provided.")
  255.  
  256.  
  257. def GetClosestDistance(modifiedSewerConLine, tblBoundaries, icMidPnt, closestBoundaryDist, closestBoundaryDistArrow):
  258. closestDist, closestDD = None, None
  259. for line in tblBoundaries:
  260. if str(type(line)) == "<type 'List[LineSegment3D]'>": #outer boundaries
  261. for trueLine in line:
  262. startPnt = trueLine.startPoint
  263. endPnt = trueLine.endPoint
  264.  
  265. trueLine = LineSegment3D(Point3D(startPnt.X, startPnt.Y, 0), Point3D(endPnt.X, endPnt.Y, 0))
  266.  
  267. print LineSegment3D().intersect(modifiedSewerConLine, trueLine)
  268. else: #inner boundaries
  269. startPnt = line.startPoint
  270. endPnt = line.endPoint
  271.  
  272. line = LineSegment3D(Point3D(startPnt.X, startPnt.Y, 0), Point3D(endPnt.X, endPnt.Y, 0))
  273. print LineSegment3D().intersect(modifiedSewerConLine, line)
  274.  
  275. return closestDist, closestDD
  276.  
  277.  
  278. def checkSubtractedPrj(elePrj, prj2): #Check If prj2 is fully covering elePrj
  279. def SubPrjWithVal(face1, face2, elev, numSet):
  280. subbedPrj = FXGeometry.SubtractProjection(face1, face2, elev)
  281. if len(subbedPrj) > 0:
  282. numSet.append([face.Area for face in subbedPrj if face.Area is not None and int(face.Area) > 0 ])#add area thats not None and greater than 1 in areaSet
  283.  
  284. prjThreadList = list()
  285. areaSet = set()
  286.  
  287. for i in range(len(elePrj)):
  288. for u in range(len(prj2)):
  289. thread = threading.Thread(target=SubPrjWithVal, args=(elePrj[i], prj2[u], 0, areaSet))
  290. thread.start()
  291. prjThreadList.append(thread)
  292. for thread in prjThreadList:
  293. thread.join()
  294. if len(areaSet) > 0 : #if there's one of the area is greater than one, means it is not fully covered
  295. return False
  296. else:
  297. return True
  298.  
  299.  
  300. def GenerateSysGraph(flowdir, *args):
  301. excludeTbl = ["Dummy Port Element"]
  302. if len(args) > 0:
  303. excludeTbl = excludeTbl + list(args)
  304.  
  305. SystemGraph.InitFullSystemGraphs()
  306. SystemGraph.ExcludeElementID(excludeTbl)
  307. SystemGraph.SetSystemFlowDirection(flowdir)
  308. SystemGraph.GenerateGraph()
  309.  
  310.  
  311. def GetConnectedPipe(elementid):
  312. query = """select rl.connectedelementid from bimrl_relconnection rl, bimrl_element e, bimrl_type t
  313. where rl.connectingelementid = '"""+elementid+"""'
  314. and rl.connectedelementid = e.elementid
  315. and e.typeid = t.elementid
  316. and t.ifctype = 'IFCPIPESEGMENTTYPE'
  317. and t.predefinedtype in ('NOTDEFINED','RIGIDSEGMENT')"""
  318. arr = FXBIMRL.GetJsonObjFromQuery(query)
  319. return [tbl["connectedelementid"] for tbl in arr["Table1"]]
  320.  
  321.  
  322. def GetSewerConnection(inspectionChamberTable, manholeTable, junctionTable):
  323. # NOTE: RETURN SEWER CONNECTION, LAST IC, MANHOLE/JUNCTION, BACKDROP
  324. if manholeTable:
  325. mhTargetStr = GetTarget(manholeTable)
  326.  
  327. sewerJunctionAndManholeTable = manholeTable + junctionTable
  328.  
  329. lastICTable = []
  330. lastMHTable = []
  331. sewerConnTbl = []
  332. backDropTbl = []
  333.  
  334. for ic in inspectionChamberTable:
  335. for mh in sewerJunctionAndManholeTable:
  336. path = list(SystemGraph.FindPath(ic, mh, 0))
  337. if path:
  338. path = path[1:-1] #removing 1st and last item(-1 in python)
  339.  
  340. #NOTE: LAST IC: ELEMENTS IN modefied path(removed start ele and end ele) SHOULD BE PIPES AND FITTINGS(NOT JUNCTION)
  341. isLastIC = True
  342. # 1) mapping/ dict comprehension
  343. pathWithEleType = {id:str(GetObjectByElementId(id).ElementData['elementtype']).lower() for id in path}
  344. # 2) check different element type and junction
  345. diffEleTypeAndJunc = { k:v for (k,v) in pathWithEleType.items()
  346. if ("segment" not in v)
  347. or ("fitting" in v and (FXGeometry.GetFacesNearPortLocation(k).Count == 3) )
  348. }
  349.  
  350. if len(diffEleTypeAndJunc) > 0:
  351. isLastIC = False
  352.  
  353. if isLastIC:
  354. lastICTable.append(ic)
  355. pipeConnTbl = filter(lambda x: "segment" in str(GetObjectByElementId(x).ElementData['elementtype']).lower() , path)
  356.  
  357. mhObj = GetObjectByElementId(mh)
  358.  
  359. if "fitting" not in str(mhObj.ElementData['elementtype']).lower():
  360. # print " MANHOLE"
  361. lastMHTable.append(mh)
  362.  
  363. else: #FOR LAST IC TO JUNCTION
  364. # print " JUNCTION", GetObjectByElementId(mh).ElementData["elementtype"]
  365. faces = []
  366. dictFacesList = FXGeometry.GetClusterOfFacesNearPortLocation(mh)
  367.  
  368. for keyPair in dictFacesList:
  369. distance = None
  370. closestFace = None
  371. # print "wut"
  372. for face in keyPair.Value:
  373. dist = Point3D().distance(face.boundingBox.Center, keyPair.Key)
  374.  
  375. if not closestFace:
  376. distance = dist
  377. closestFace = face
  378. else:
  379. if distance > dist:
  380. distance = dist
  381. closestFace = face
  382.  
  383. faces.append(closestFace)
  384.  
  385. oneFacedDown = []
  386. twoHorizontal = []
  387.  
  388. for face in faces:
  389. dot = face.basePlane.normalVector.Z
  390. # print "dot", dot
  391. if dot <= -0.35:
  392. oneFacedDown.append(face)
  393. elif dot >= -0.02 and dot <= 0.02:
  394. twoHorizontal.append(face)
  395.  
  396. isBackDrop = len(oneFacedDown) == 1 and len(twoHorizontal) == 2
  397. # print "isBackDrop", isBackDrop
  398. if not isBackDrop:
  399. lastMHTable.append(mh)
  400. else:
  401. # print "BACKDROP"
  402. backDropTbl.append(mh)
  403.  
  404. path = SystemGraph.FindPathToSpecificTypeObject(mh, mhTargetStr, 0)
  405. if len(path) > 1:
  406. manhole = path[-1] #last item(-1 in python)
  407.  
  408. path = path[1:-1] #removing 1st and last item(-1 in python)
  409.  
  410. SystemGraph.ResetGraph()
  411. GenerateSysGraph(2,path)
  412.  
  413. path1 = SystemGraph.FindPath(manhole, mh, 0)
  414. if len(path1) > 1:
  415. path1 = filter(lambda x: "segment" in str(GetObjectByElementId(x).ElementData['elementtype']).lower() , path1)
  416. pipeConnTbl = pipeConnTbl + path + path1 #combining to lists of pipe
  417.  
  418. sewerConnTbl.append(pipeConnTbl)
  419.  
  420.  
  421. return sewerConnTbl, lastICTable, lastMHTable, backDropTbl
  422.  
  423.  
  424. def GetTarget(elementidList):
  425. def getTarget(x):
  426. tbl = []
  427. List = ['NOTDEFINED', 'USERDEFINED']
  428.  
  429. obj = GetObjectByElementId(x)
  430. predefinedType = str(obj.TypeData["predefinedtype"])
  431. objType = str(obj.ElementData["objecttype"])
  432. ifcType = str(obj.TypeData["ifctype"])
  433.  
  434. if predefinedType not in List:
  435. Value = predefinedType.upper()
  436. else:
  437. Value = objType.upper()
  438.  
  439. tbl.extend([ifcType, Value])
  440.  
  441. return tbl
  442.  
  443. targetStr = ""
  444. if len(elementidList) > 0:
  445. TargetList = map(getTarget, elementidList)
  446. targetStr = ",".join(TargetList[0])
  447.  
  448. return targetStr
  449.  
  450.  
  451. class PipeGeom:
  452. @staticmethod
  453. def GetPipeCenterLine(elementid):
  454. # Get centerline by Pipe's Portlocation
  455. # Args: elementid
  456. # Return: centerLine(Line3D)
  457.  
  458. if not ("segment" in str(GetObjectByElementId(elementid).ElementData["elementtype"]).lower()):
  459. return
  460.  
  461. centerLine = LineSegment3D()
  462. query = """SELECT con.connectingportlocation AS portpnt
  463. FROM bimrl_relconnection con
  464. WHERE con.connectingelementid = '"""+elementid+"""' """
  465.  
  466. PortArr = FXBIMRL.GetJsonObjFromQuery(query)
  467.  
  468. PortArr = map(lambda x: x["portpnt"], PortArr["Table1"])
  469.  
  470. # NOTE: IF len(PortArr) > 2, NEED TO DETERMINE THE 2 FARTHEST PNTS
  471. if len(PortArr) > 2:
  472. for v in PortArr:
  473. pnt1 = Point3D(v["X"], v["Y"], v["Z"])
  474. for v2 in PortArr:
  475. pnt2 = Point3D(v2["X"], v2["Y"], v2["Z"])
  476.  
  477. if not pnt1.Equals(pnt2):
  478. line = LineSegment3D(pnt1, pnt2)
  479.  
  480. if centerLine is None or centerLine.extent < line.extent:
  481. centerLine = line
  482. else:
  483. pnt1 = Point3D(PortArr[0]["X"], PortArr[0]["Y"], PortArr[0]["Z"])
  484. pnt2 = Point3D(PortArr[1]["X"], PortArr[1]["Y"], PortArr[1]["Z"])
  485. centerLine = LineSegment3D(pnt1, pnt2)
  486.  
  487. return centerLine
  488.  
  489. @staticmethod
  490. def GetPipeDiameter(elementid):
  491. # Get Diameter by circular face
  492. # Args: elementid
  493. # Return: Diameter(number) in meter
  494.  
  495. if not ("segment" in str(GetObjectByElementId(elementid).ElementData["elementtype"]).lower()):
  496. print "expected segment, got "+ GetObjectByElementId(elementid).ElementData["elementtype"]
  497. return None
  498.  
  499. diameter = 0
  500. circleFaces = PipeGeom.GetCircularFaces(elementid)
  501.  
  502. if circleFaces:
  503. cntrPnt = circleFaces[0]['centroid']
  504. outerPnt = circleFaces[0]['face'].OuterVertices[0]
  505.  
  506. diameter = (LineSegment3D(cntrPnt, outerPnt).extent) * 2
  507.  
  508. return diameter
  509.  
  510. @staticmethod
  511. def GetCircularFaces(elementid):
  512. # Get circular face using IsFaceCircular API
  513. # Args: elementid
  514. # Return: List["face":(Face3D), "centroid":(Point3D)]
  515.  
  516. faceQuery = """SELECT polygon, centroid, normal
  517. FROM bimrl_topo_face
  518. WHERE elementid = '"""+ elementid +"""'
  519. AND type = 'BODY' """
  520.  
  521. faceArr = FXBIMRL.GetJsonObjFromQuery(faceQuery)
  522. if faceArr is None: return None
  523.  
  524. circleFaces = filter(lambda x: FXGeometry.IsFaceCircular(FXGeometry.CreatePolygonFace(x["polygon"]), 0.1), faceArr["Table1"])
  525. circleFaces = map(lambda x: {"face": FXGeometry.CreatePolygonFace(x["polygon"]), "centroid": Point3D(x["centroid"]["X"], x["centroid"]["Y"], x["centroid"]["Z"])}, circleFaces)
  526.  
  527. return circleFaces
  528.  
  529.  
  530. def GetExtrusionFromLowestToHighest(guid, highElev, lowElev, polyhedron = False):
  531. if polyhedron is False:
  532. polyhedron = FXGeometry.GetGeometryBodyByGUID(guid)
  533. polyList = List[Polyhedron]()
  534. polyList.Add(polyhedron)
  535.  
  536. prj = FXGeometry.GetProjection(polyList, lowElev) #create projection to lowest elevation
  537.  
  538. extrudedPolyList = List[Polyhedron]()
  539. extrudeHeight = abs(float(highElev) - float(lowElev))
  540. extrudedPolyList.Add(FXGeometry.ExtrudeFaces(prj, Vector3D(0,0,1) , extrudeHeight)) # then extrude to highest elevation
  541. extrudedPoly = FXGeometry.UnionPolyhedronList(extrudedPolyList)
  542.  
  543. return extrudedPoly, polyhedron, prj
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement