GetAllModule.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. # -*- coding: UTF-8 -*-
  2. from pyautocad import Autocad, APoint
  3. from utils import conf
  4. import math
  5. #这个true表示没有文件则打开一个,CAD有弹窗时会打开或者创建失败
  6. acad = Autocad(create_if_not_exists = False)
  7. # 组件实体点位置
  8. positoins={}
  9. currentPosition = {}
  10. # 组件使用点位置
  11. useAreaPositions={}
  12. # 组件与门距离
  13. distinceWithDoor = {}
  14. # 组件间距离
  15. distinceWithOthers={}
  16. # 旋转后需删除的组件
  17. needDeleteBlockReferences=[]
  18. # acad.prompt("Hello, Autocad from Python\n")
  19. # conf.myprint(acad.doc.Name)
  20. def printObjects():
  21. #遍历cad图形对象
  22. for obj in acad.iter_objects():
  23. conf.myprint(obj.ObjectName)
  24. def printBlockObjects():
  25. #遍历cad图形对象
  26. for obj in acad.iter_objects("BlockReference"):
  27. conf.myprint(obj.name,obj.HasAttributes)
  28. if obj.HasAttributes:
  29. attrs = obj.GetAttributes()
  30. for attrib in attrs:
  31. conf.myprint(" {}: {}".format(attrib.TagString, attrib.TextString))
  32. def printTheTypeObject(type):
  33. #按类型查找出所有某种图元
  34. for text in acad.iter_objects(type):
  35. conf.myprint(text.name)
  36. def moveBlockReference(position):
  37. positoins.clear()
  38. useAreaPositions.clear()
  39. conf.myprint(conf.moduleLengths)
  40. moveResult = 1
  41. for blockReference in acad.iter_objects("BlockReference"):
  42. conf.myprint(blockReference.name)
  43. for item in conf.names:
  44. if(blockReference.name == item):
  45. currentPosition[0] = position
  46. currentPosition[1] = conf.names.index(item)
  47. result = moveBlockReferenceToWall(blockReference,position[conf.names.index(item)])
  48. if(result == 0):
  49. moveResult = result
  50. for blockReference in needDeleteBlockReferences:
  51. blockReference.delete()
  52. needDeleteBlockReferences.clear()
  53. return moveResult
  54. def moveBlockReferenceToWall(blockReference,wallIndex):
  55. wallIndex = int(wallIndex)
  56. blockReference.rotate(APoint(blockReference.InsertionPoint),0.5*(wallIndex+1)*math.pi)
  57. blockIndex = conf.names.index(blockReference.name)
  58. conf.myprint("begin to put ",blockReference.name)
  59. if(wallIndex == 0):
  60. blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomLengths[0]-conf.roomUsedLengths[0],0))
  61. conf.roomUsedLengths[0] = conf.roomUsedLengths[0]+conf.moduleLengths[blockIndex];
  62. elif (wallIndex == 1):
  63. blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomLengths[0],conf.roomLengths[1]-conf.roomUsedLengths[1]))
  64. conf.roomUsedLengths[1] = conf.roomUsedLengths[1]+conf.moduleLengths[blockIndex];
  65. elif (wallIndex == 2):
  66. blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomUsedLengths[2],conf.roomLengths[1]))
  67. conf.roomUsedLengths[2] = conf.roomUsedLengths[2]+conf.moduleLengths[blockIndex];
  68. else:
  69. blockReference.move(APoint(blockReference.InsertionPoint),APoint(0,conf.roomLengths[1]-conf.roomUsedLengths[3]-conf.moduleLengths[blockIndex]))
  70. conf.roomUsedLengths[3] = conf.roomUsedLengths[3]+conf.moduleLengths[blockIndex];
  71. checkPositionIntersect = tempStoragePosition(blockReference.InsertionPoint[0],blockReference.InsertionPoint[1],wallIndex,blockIndex,blockReference)
  72. if(checkPositionIntersect == 0):
  73. conf.myprint("wallIndex=",wallIndex,blockReference.name," not walkable......")
  74. return 0
  75. else:
  76. return 1
  77. # 根据新顺序移动模块
  78. def moveBlockReferenceWithNewIndex(position,moduleIndex):
  79. moveResult = 1
  80. positoins.clear()
  81. useAreaPositions.clear()
  82. conf.myprint(conf.moduleLengths)
  83. blockReferences = []
  84. for blockReference in acad.iter_objects("BlockReference"):
  85. conf.myprint(blockReference.name)
  86. for item in conf.names:
  87. if(blockReference.name == item):
  88. blockReferences.append(blockReference)
  89. for index in moduleIndex:
  90. currentPosition[0] = position
  91. currentPosition[1] = moduleIndex
  92. currentPosition[2] = moduleIndex.index(index)
  93. result = moveBlockReferenceToWall(blockReferences[index],position[moduleIndex.index(index)])
  94. if(result == 0):
  95. moveResult = result
  96. return moveResult
  97. # 重置已使用墙的长度
  98. def resetConfUsed():
  99. conf.roomUsedLengths=[0,0,0,0]
  100. # 对模块重新排序
  101. def changeConfModuleIndex(moduleIndex):
  102. names=[]
  103. moduleLengths=[]
  104. for index in range(len(conf.moduleLengths)):
  105. names.append(conf.names[moduleIndex[index]])
  106. moduleLengths.append(conf.moduleLengths[moduleIndex[index]])
  107. conf.names = names
  108. conf.moduleLengths = tuple(moduleLengths)
  109. # 重置模块顺序
  110. def resetModuleIndex():
  111. conf.names=['md_py','md_xs','md_rc']
  112. conf.moduleLengths = (800,1000,800)
  113. # 判断位置是否可行
  114. def isWorkable(position):
  115. resetConfUsed()
  116. conf.myprint("position=",position)
  117. needLength=[0]*4
  118. for positionIndex in range(len(position)):
  119. wallIndex = int(position[positionIndex])
  120. needLength[wallIndex]+=conf.moduleLengths[positionIndex]
  121. if(needLength[wallIndex]+conf.roomUsedLengths[wallIndex] > conf.roomWallLengths[wallIndex]):
  122. conf.myprint(needLength[wallIndex]+conf.roomUsedLengths[wallIndex],conf.roomLengths[math.floor(wallIndex/2)],wallIndex)
  123. return 0
  124. return 1
  125. # 获取组件的四点坐标
  126. def getCenterPoint(wallIndex, x, y, blockIndex):
  127. height = conf.moduleLengths[blockIndex];
  128. width = conf.moduleHeights[blockIndex];
  129. useHeight = conf.moduleUseLength[blockIndex]
  130. useWidth = conf.humenLenght
  131. usePointPosition = conf.moduleUsePoint[blockIndex]
  132. useCenterPointPosition = conf.moduleUseCenterPoint[blockIndex]
  133. pointA = (x,y)
  134. conf.myprint("insertPoint=",x,y)
  135. if(wallIndex == 0):
  136. pointB = (x,y+width)
  137. pointC = (x-height,y+width)
  138. pointD = (x-height,y)
  139. centerPoint = (x-height/2,y+width/2)
  140. usePoint= (x-usePointPosition[1],y+usePointPosition[0])
  141. useCenterPoint= (x-useCenterPointPosition[1],y+useCenterPointPosition[0])
  142. centerPointOffset = (height,width)
  143. useCenterPointOffset = (useHeight,useWidth)
  144. elif(wallIndex == 1):
  145. pointB = (x-width,y)
  146. pointC = (x-width,y-height)
  147. pointD = (x,y-height)
  148. centerPoint = (x-width/2,y-height/2)
  149. usePoint= (x-usePointPosition[0],y-usePointPosition[1])
  150. useCenterPoint= (x-useCenterPointPosition[0],y-useCenterPointPosition[1])
  151. centerPointOffset = (width,height)
  152. useCenterPointOffset = (useWidth,useHeight)
  153. elif(wallIndex == 2):
  154. pointB = (x,y-width)
  155. pointC = (x+height,y-width)
  156. pointD = (x+height,y)
  157. centerPoint = (x+height/2,y-width/2)
  158. usePoint= (x+usePointPosition[1],y-usePointPosition[0])
  159. useCenterPoint= (x+useCenterPointPosition[1],y-useCenterPointPosition[0])
  160. centerPointOffset = (height,width)
  161. useCenterPointOffset = (useHeight,useWidth)
  162. else:
  163. pointB = (x+width,y)
  164. pointC = (x+width,y+height)
  165. pointD = (x,y+height)
  166. centerPoint = (x+width/2,y+height/2)
  167. usePoint= (x+usePointPosition[0],y+usePointPosition[1])
  168. useCenterPoint= (x+useCenterPointPosition[0],y+useCenterPointPosition[1])
  169. centerPointOffset = (width,height)
  170. useCenterPointOffset = (useWidth,useHeight)
  171. positoin = [centerPoint,centerPointOffset,usePoint,useCenterPoint,useCenterPointOffset];
  172. conf.myprint(wallIndex,width,height)
  173. # drawPointCircle((pointA, pointB, pointC, pointD, centerPoint, usePoint, useCenterPoint))
  174. conf.myprint(positoin)
  175. return positoin
  176. # 打印辅助点
  177. def drawPointCircle(points):
  178. for point in points:
  179. acad.model.AddCircle(APoint(point[0],point[1]), 50)
  180. # 判断可用区域中点是否超出房间
  181. def isUseCenterOverRoom(useCenterPosition):
  182. if useCenterPosition[0] < 0 or useCenterPosition[0]>conf.roomLengths[0] or useCenterPosition[1] < 0 or useCenterPosition[1]>conf.roomLengths[1]:
  183. return True
  184. return False
  185. # 从插入点开始顺时针记录已摆放的组件
  186. def tempStoragePosition(x,y,wallIndex,blockIndex,blockReference):
  187. position = getCenterPoint(wallIndex, x, y, blockIndex);
  188. # 判断可用区域中点是否超出房间
  189. if(isUseCenterOverRoom(position[3])):
  190. mirrorPy(blockReference,position)
  191. useCenterPosition = (position[3],position[4])
  192. doorFeasible = isPositionFeasibleWithDoor(position)
  193. conf.myprint("doorFeasible=",doorFeasible)
  194. if(doorFeasible == 0):
  195. return doorFeasible
  196. getDoorBeginAndModuleUsePointDistince(position,wallIndex)
  197. result = 1
  198. for item in positoins:
  199. # 判断实体是否相交
  200. result = isPositionFeasible(position,positoins[item],1)
  201. if(result == 1):
  202. # 判断当前实体是否与已摆放的可用区域相交
  203. result = isPositionFeasible(position,useAreaPositions[item],1)
  204. if(result == 1):
  205. # 判断可用区域是否与实体相交
  206. result = isPositionFeasible(useCenterPosition,positoins[item],1)
  207. if(result == 0):
  208. return result
  209. if(result == 1):
  210. positoins[len(positoins)] = position
  211. useAreaPositions[len(useAreaPositions)] = useCenterPosition
  212. return result
  213. # 计算位置是否可行type:0 实体 1可用区域
  214. def isPositionFeasible(position1,position2,type):
  215. areaName = "可用区域"
  216. if type==0:
  217. acad.model.AddLine(APoint(position1[0][0],position1[0][1]),APoint(position2[0][0],position2[0][1]))
  218. acad.model.AddCircle(APoint(position1[0][0],position1[0][1]), 50)
  219. areaName = "实体区域"
  220. if(abs(position1[0][0]-position2[0][0]) < (position1[1][0]+position2[1][0])/2 and abs(position1[0][1]-position2[0][1]) < (position1[1][1]+position2[1][1])/2):
  221. conf.myprint(areaName,"sorry! can not put here",currentPosition,"position1=",position1,"position2=",position2)
  222. return 0
  223. else:
  224. conf.myprint(areaName,"can put here")
  225. return 1
  226. # 计算实体位置是否与门使用区域相交
  227. def isPositionFeasibleWithDoor(position):
  228. length = conf.doorAlign[0]+conf.doorAlign[1]+conf.doorLength;
  229. width = conf.doorLength+conf.doorAlign[2];
  230. doorPosition = [(length/2,width/2),(length,width)]
  231. return isPositionFeasible(position,doorPosition,1)
  232. # 计算两点间距离
  233. def getDistince(point1,point2):
  234. detarX = point1[0]-point2[0]
  235. detarY = point1[1]-point2[1]
  236. return math.sqrt(detarX**2+detarY**2)
  237. def getDoorBeginPoint():
  238. return ((conf.doorAlign[0]+conf.doorLength+conf.doorAlign[1])/2,0)
  239. def getDoorBeginAndModuleUsePointDistince(position,wallIndex):
  240. doorBeginPoint = getDoorBeginPoint()
  241. usePoint = position[2]
  242. useCenterPoint = (position[0][0],position[0][1])
  243. d1 = getDistince(doorBeginPoint,useCenterPoint);
  244. d2 = getDistince(doorBeginPoint,usePoint)
  245. if(d1 < d2):
  246. #不可直接连接
  247. conf.myprint("wallIndex=",wallIndex)
  248. if(wallIndex == 0):
  249. # 先连c
  250. acad.model.AddLine(APoint(doorBeginPoint[0],doorBeginPoint[1]),APoint(position[0][0]-position[1][0]/2,position[0][1]+position[1][1]/2))
  251. acad.model.AddLine(APoint(position[0][0]-position[1][0]/2,position[0][1]+position[1][1]/2),APoint(usePoint[0],usePoint[1]))
  252. else:
  253. # 只有0,3需要绕过,先连b
  254. # acad.model.AddLine(APoint(doorBeginPoint[0],doorBeginPoint[1]),APoint(position[0][0]+position[1][0]/2,position[0][1]-position[1][1]/2))
  255. # acad.model.AddLine(APoint(position[0][0]+position[1][0]/2,position[0][1]-position[1][1]/2),APoint(usePoint[0],usePoint[1]))
  256. acad.model.AddLine(APoint(doorBeginPoint[0],doorBeginPoint[1]),APoint(usePoint[0],usePoint[1]-position[1][1]))
  257. else:
  258. acad.model.AddLine(APoint(doorBeginPoint[0],doorBeginPoint[1]),APoint(usePoint[0],usePoint[1]))
  259. # distinceWithDoor[len(distinceWithDoor)] = getDistince(doorBeginPoint,usePoint)
  260. # 以mirrorPoint和可用区域重点为对称抽翻转py
  261. def mirrorPy(py,position):
  262. insertPoint = py.InsertionPoint
  263. centerPoint = position[0]
  264. newCenterPoint = [position[3][0],position[3][1]]
  265. if((insertPoint[0]-centerPoint[0])*(insertPoint[1]-centerPoint[1])>0):
  266. mirrorPoint = (insertPoint[0],centerPoint[1])
  267. direction = 1 if (insertPoint[1]-centerPoint[1])>0 else -1;
  268. newCenterPoint[1]=position[3][1]+position[4][0]*direction
  269. else:
  270. mirrorPoint = (centerPoint[0],insertPoint[1])
  271. direction = 1 if (insertPoint[1]-centerPoint[1])>0 else -1;
  272. newCenterPoint[0]=position[3][0]+position[4][1]*direction
  273. position[3] = newCenterPoint
  274. py.mirror(APoint(mirrorPoint[0],mirrorPoint[1]),APoint(centerPoint[0],centerPoint[1]))
  275. conf.myprint("delete blockReference name",py.name)
  276. needDeleteBlockReferences.append(py)
  277. # printObjects()
  278. # printBlockObjects()
  279. # printTheTypeObject("BlockReference")
  280. # moveBlockReference('222')
  281. # a=[0,1,2]
  282. # moveBlockReferenceWithNewIndex('001',a)
  283. # conf.myprint(isWorkable('222'))
  284. # getCenterPoint(3,4162.85,0,2)
  285. # print(getDistince((0,3),(4,0)))
  286. # print(getDoorBeginPoint())