123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- # -*- coding: UTF-8 -*-
- from pyautocad import Autocad, APoint
- from utils import conf,MovePath
- import math
- #这个true表示没有文件则打开一个,CAD有弹窗时会打开或者创建失败
- acad = Autocad(create_if_not_exists = False)
- # 组件实体点位置
- positoins={}
- currentPosition = {}
- # 组件使用点位置
- useAreaPositions={}
- # 组件与门距离
- distinceWithDoor = {}
- # 组件间距离
- distinceWithOthers={}
- # 旋转后需删除的组件
- needDeleteBlockReferences=[]
- scores=[]
- # 分别存储位置,雷达长度,入口与模块长度,模块间长度,撞点个数
- currentScore=[]
- # acad.prompt("Hello, Autocad from Python\n")
- # conf.myprint(acad.doc.Name)
- def printObjects():
- #遍历cad图形对象
- for obj in acad.iter_objects():
- conf.myprint(obj.ObjectName)
- def printBlockObjects():
- #遍历cad图形对象
- for obj in acad.iter_objects("BlockReference"):
- conf.myprint(obj.name,obj.HasAttributes)
- if obj.HasAttributes:
- attrs = obj.GetAttributes()
- for attrib in attrs:
- conf.myprint(" {}: {}".format(attrib.TagString, attrib.TextString))
- def printTheTypeObject(type):
- #按类型查找出所有某种图元
- for text in acad.iter_objects(type):
- conf.myprint(text.name)
- # 保存正确方案的分数
- def addCurrentScoreToScores(moveResult):
- temp = []
- for item in currentScore:
- temp.append(item)
- if moveResult > 0:
- scores.append(temp)
- # 根据scores给方案打分
- def scoreModule():
- moduleScores = []
- tempLength = len(scores[0])-1
- # socres中目前存储 位置、入口雷达半径、入口与模块连线长度、模块间连线长度,入口与模块间撞点,模块与模块间撞点
- maxs = [0]*tempLength
- mins = [0]*tempLength
- detarLength = [0]*tempLength
- fullSocres = [10,10,10,5,5]
- fullSocresDirect = [1,-1,-1,-1,-1]
- # 先获取最大值和最小值
- for item in scores:
- for itemIndex in range(tempLength):
- if item[itemIndex+1]>maxs[itemIndex]:
- maxs.pop(itemIndex)
- maxs.insert(itemIndex,item[itemIndex+1])
- elif item[itemIndex+1]<mins[itemIndex]:
- mins.pop(itemIndex)
- mins.insert(itemIndex,item[itemIndex+1])
- for i in range(tempLength):
- detarLength[i] = maxs[i]-min(i)
- templateScore = []
- for item in scores:
- templateScore.append(item[0])
- for itemIndex in range(tempLength):
- if(fullSocresDirect[itemIndex] == 1):
- templateScore.append((item[itemIndex+1]-mins[itemIndex])*fullSocres[itemIndex]/detarLength[itemIndex])
- else:
- templateScore.append(fullSocres[itemIndex] - (item[itemIndex+1]-mins[itemIndex])*fullSocres[itemIndex]/detarLength[itemIndex])
- moduleScores.append(templateScore)
- conf.myprint("moduleScores=",moduleScores)
- # 方案不合适返回0,否则返回方案评分
- def moveBlockReference(position):
- positoins.clear()
- useAreaPositions.clear()
- conf.myprint(conf.moduleLengths)
- currentScore.clear()
- currentScore.append(position)
- moveResult = 1
- for blockReference in acad.iter_objects("BlockReference"):
- conf.myprint(blockReference.name)
- for item in conf.names:
- if(blockReference.name == item):
- currentPosition[0] = position
- currentPosition[1] = conf.names.index(item)
- result = moveBlockReferenceToWall(blockReference,position[conf.names.index(item)])
- if(result == 0):
- moveResult = result
- conf.myprint("currentScore size =",len(currentScore),",scores size=",len(scores))
- addCurrentScoreToScores(moveResult)
- conf.myprint("scores=",scores)
- for blockReference in needDeleteBlockReferences:
- blockReference.delete()
- needDeleteBlockReferences.clear()
- return moveResult
- def moveBlockReferenceToWall(blockReference,wallIndex):
- wallIndex = int(wallIndex)
- blockReference.rotate(APoint(blockReference.InsertionPoint),0.5*(wallIndex+1)*math.pi)
- blockIndex = conf.names.index(blockReference.name)
- conf.myprint("begin to put ",blockReference.name)
- if(wallIndex == 0):
- blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomLengths[0]-conf.roomUsedLengths[0],0))
- conf.roomUsedLengths[0] = conf.roomUsedLengths[0]+conf.moduleLengths[blockIndex];
- elif (wallIndex == 1):
- blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomLengths[0],conf.roomLengths[1]-conf.roomUsedLengths[1]))
- conf.roomUsedLengths[1] = conf.roomUsedLengths[1]+conf.moduleLengths[blockIndex];
- elif (wallIndex == 2):
- blockReference.move(APoint(blockReference.InsertionPoint),APoint(conf.roomUsedLengths[2],conf.roomLengths[1]))
- conf.roomUsedLengths[2] = conf.roomUsedLengths[2]+conf.moduleLengths[blockIndex];
- else:
- blockReference.move(APoint(blockReference.InsertionPoint),APoint(0,conf.roomLengths[1]-conf.roomUsedLengths[3]-conf.moduleLengths[blockIndex]))
- conf.roomUsedLengths[3] = conf.roomUsedLengths[3]+conf.moduleLengths[blockIndex];
- checkPositionIntersect = tempStoragePosition(blockReference.InsertionPoint[0],blockReference.InsertionPoint[1],wallIndex,blockIndex,blockReference)
- if(checkPositionIntersect == 0):
- conf.myprint("wallIndex=",wallIndex,blockReference.name," not walkable......")
- return 0
- else:
- return 1
- # 根据新顺序移动模块
- def moveBlockReferenceWithNewIndex(position,moduleIndex):
- moveResult = 1
- positoins.clear()
- useAreaPositions.clear()
- currentScore.clear()
- firstScoreItem = []
- for item in position:
- firstScoreItem.append(item)
- firstScoreItem.append(moduleIndex)
- currentScore.append(firstScoreItem)
- conf.myprint(conf.moduleLengths)
- blockReferences = []
- for blockReference in acad.iter_objects("BlockReference"):
- conf.myprint(blockReference.name)
- for item in conf.names:
- if(blockReference.name == item):
- blockReferences.append(blockReference)
- for index in moduleIndex:
- currentPosition[0] = position
- currentPosition[1] = moduleIndex
- currentPosition[2] = moduleIndex.index(index)
- result = moveBlockReferenceToWall(blockReferences[index],position[moduleIndex.index(index)])
- if(result == 0):
- moveResult = result
- conf.myprint("currentScore size =",len(currentScore),",scores size=",len(scores))
- addCurrentScoreToScores(moveResult)
- conf.myprint("scores=",scores)
- for blockReference in needDeleteBlockReferences:
- blockReference.delete()
- needDeleteBlockReferences.clear()
- return moveResult
- # 重置已使用墙的长度
- def resetConfUsed():
- conf.roomUsedLengths=[0,0,0,0]
- # 对模块重新排序
- def changeConfModuleIndex(moduleIndex):
- names=[]
- moduleLengths=[]
- for index in range(len(conf.moduleLengths)):
- names.append(conf.names[moduleIndex[index]])
- moduleLengths.append(conf.moduleLengths[moduleIndex[index]])
- conf.names = names
- conf.moduleLengths = tuple(moduleLengths)
- # 重置模块顺序
- def resetModuleIndex():
- conf.names=['md_py','md_xs','md_rc']
- conf.moduleLengths = (800,1000,800)
- # 判断位置是否可行
- def isWorkable(position):
- resetConfUsed()
- conf.myprint("position=",position)
- needLength=[0]*4
- for positionIndex in range(len(position)):
- wallIndex = int(position[positionIndex])
- needLength[wallIndex]+=conf.moduleLengths[positionIndex]
- if(needLength[wallIndex]+conf.roomUsedLengths[wallIndex] > conf.roomWallLengths[wallIndex]):
- conf.myprint(needLength[wallIndex]+conf.roomUsedLengths[wallIndex],conf.roomLengths[math.floor(wallIndex/2)],wallIndex)
- return 0
- return 1
- # 获取组件的四点坐标
- def getCenterPoint(wallIndex, x, y, blockIndex):
- height = conf.moduleLengths[blockIndex]-conf.moduleLengthOffsets[blockIndex];
- width = conf.moduleHeights[blockIndex];
- useHeight = conf.moduleUseLength[blockIndex]
- useWidth = conf.humenLenght
- usePointPosition = conf.moduleUsePoint[blockIndex]
- useCenterPointPosition = conf.moduleUseCenterPoint[blockIndex]
- pointA = (x,y)
- conf.myprint("insertPoint=",x,y)
- if(wallIndex == 0):
- pointB = (x,y+width)
- pointC = (x-height,y+width)
- pointD = (x-height,y)
- centerPoint = (x-height/2,y+width/2)
- usePoint= (x-usePointPosition[1],y+usePointPosition[0])
- useCenterPoint= (x-useCenterPointPosition[1],y+useCenterPointPosition[0])
- centerPointOffset = (height,width)
- useCenterPointOffset = (useHeight,useWidth)
- elif(wallIndex == 1):
- pointB = (x-width,y)
- pointC = (x-width,y-height)
- pointD = (x,y-height)
- centerPoint = (x-width/2,y-height/2)
- usePoint= (x-usePointPosition[0],y-usePointPosition[1])
- useCenterPoint= (x-useCenterPointPosition[0],y-useCenterPointPosition[1])
- centerPointOffset = (width,height)
- useCenterPointOffset = (useWidth,useHeight)
- elif(wallIndex == 2):
- pointB = (x,y-width)
- pointC = (x+height,y-width)
- pointD = (x+height,y)
- centerPoint = (x+height/2,y-width/2)
- usePoint= (x+usePointPosition[1],y-usePointPosition[0])
- useCenterPoint= (x+useCenterPointPosition[1],y-useCenterPointPosition[0])
- centerPointOffset = (height,width)
- useCenterPointOffset = (useHeight,useWidth)
- else:
- pointB = (x+width,y)
- pointC = (x+width,y+height)
- pointD = (x,y+height)
- centerPoint = (x+width/2,y+height/2)
- usePoint= (x+usePointPosition[0],y+usePointPosition[1])
- useCenterPoint= (x+useCenterPointPosition[0],y+useCenterPointPosition[1])
- centerPointOffset = (width,height)
- useCenterPointOffset = (useWidth,useHeight)
- positoin = [centerPoint,centerPointOffset,usePoint,useCenterPoint,useCenterPointOffset];
- conf.myprint(wallIndex,width,height)
- # drawPointCircle((pointA, pointB, pointC, pointD, centerPoint, usePoint, useCenterPoint))
- conf.myprint(positoin)
- return positoin
- # 打印辅助点
- def drawPointCircle(points):
- for point in points:
- acad.model.AddCircle(APoint(point[0],point[1]), 50)
- # 判断可用区域是否超出房间
- def isUseAreaOverRoom(useCenterPosition,useCenterPositionOffset):
- if useCenterPosition[0]- useCenterPositionOffset[0]/2< 0 or useCenterPosition[0]+useCenterPositionOffset[0]/2>conf.roomLengths[0] or useCenterPosition[1]-useCenterPositionOffset[1]/2 < 0 or useCenterPosition[1]+useCenterPositionOffset[1]/2>conf.roomLengths[1]:
- return True
- return False
- # 从插入点开始顺时针记录已摆放的组件
- def tempStoragePosition(x,y,wallIndex,blockIndex,blockReference):
- position = getCenterPoint(wallIndex, x, y, blockIndex);
- # 判断可用区域中点是否超出房间
- if(isUseAreaOverRoom(position[3],position[4])):
- mirrorPy(blockReference,position)
- useCenterPosition = (position[3],position[4])
- doorFeasible = isPositionFeasibleWithDoor(position)
- conf.myprint("doorFeasible=",doorFeasible)
- if(doorFeasible == 0):
- return doorFeasible
- getDoorBeginAndModuleUsePointDistince(position,wallIndex)
- result = 1
- for item in positoins:
- # 判断实体是否相交
- result = isPositionFeasible(position,positoins[item],0)
- if(result == 1):
- # 判断当前实体是否与已摆放的可用区域相交
- result = isPositionFeasible(position,useAreaPositions[item],1)
- if(result == 1):
- # 判断可用区域是否与实体相交
- result = isPositionFeasible(useCenterPosition,positoins[item],1)
- if(result == 0):
- return result
- if(result == 1):
- positoins[len(positoins)] = position
- useAreaPositions[len(useAreaPositions)] = useCenterPosition
- return result
- # 计算位置是否可行type:0 实体 1可用区域
- def isPositionFeasible(position1,position2,type):
- areaName = "可用区域"
- if type==0:
- # acad.model.AddLine(APoint(position1[0][0],position1[0][1]),APoint(position2[0][0],position2[0][1]))
- # acad.model.AddCircle(APoint(position1[0][0],position1[0][1]), 50)
- areaName = "实体区域"
- # 画出实体区域间的可用点连线
- moduleIncludePoints = MovePath.getModuleMovePath(position1[0][0],position1[0][1],position1[1][0],position1[1][1],position1[2][0],position1[2][1],position2[0][0],position2[0][1],position2[1][0],position2[1][1],position2[2][0],position2[2][1])
- conf.myprint("moduleIncludePoints=",moduleIncludePoints)
- # 模块间距离
- moduleDistince = drawLines(moduleIncludePoints)
- if(len(currentScore) == 3):
- currentScore.append(moduleDistince)
- else:
- moduleDistince += currentScore.pop(3)
- currentScore.insert(3,moduleDistince)
- # 撞点个数
- knockPointNo = len(moduleIncludePoints)-2
- if(len(currentScore) == 4):
- currentScore.append(knockPointNo)
- else:
- knockPointNo += currentScore.pop(4)
- currentScore.insert(4,knockPointNo)
- 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):
- conf.myprint(areaName,"sorry! can not put here",currentPosition,"position1=",position1,"position2=",position2)
- return 0
- else:
- conf.myprint(areaName,"can put here")
- return 1
- # 计算实体位置是否与门使用区域相交
- def isPositionFeasibleWithDoor(position):
- length = conf.doorAlign[0]+conf.doorAlign[1]+conf.doorLength;
- width = conf.doorLength+conf.doorAlign[2];
- doorPosition = [(length/2,width/2),(length,width)]
- return isPositionFeasible(position,doorPosition,1)
- # 计算两点间距离
- def getDistince(point1,point2):
- detarX = point1[0]-point2[0]
- detarY = point1[1]-point2[1]
- return math.sqrt(detarX**2+detarY**2)
- def getDoorBeginPoint():
- return (conf.doorAlign[0]+conf.doorLength/2,0)
- def drawLines(includePoints):
- lineLength = 0;
- if(len(includePoints)>1):
- for item in range(len(includePoints)):
- if(item>0):
- acad.model.AddLine(APoint(includePoints[item-1][0],includePoints[item-1][1]),APoint(includePoints[item][0],includePoints[item][1]))
- lineLength += getDistince((includePoints[item-1][0],includePoints[item-1][1]),(includePoints[item][0],includePoints[item][1]))
- return lineLength
- def getDoorBeginAndModuleUsePointDistince(position,wallIndex):
- doorBeginPoint = getDoorBeginPoint()
- includePoints = MovePath.getDoorBeginAndModuleUsePointDistince(position[0][0],position[0][1],position[1][0],position[1][1],doorBeginPoint[0],doorBeginPoint[1])
- doorBeginAndModuleUsePointDistince = drawLines(includePoints)
- if(len(currentScore) == 1):
- currentScore.append(doorBeginAndModuleUsePointDistince)
- elif(currentScore[1] > doorBeginAndModuleUsePointDistince):
- currentScore.pop(1)
- currentScore.insert(1,doorBeginAndModuleUsePointDistince)
- includePoints = MovePath.getMovePath(position[0][0],position[0][1],position[1][0],position[1][1],doorBeginPoint[0],doorBeginPoint[1],position[2][0],position[2][1])
- moveLength = drawLines(includePoints)
- if(len(currentScore) == 2):
- currentScore.append(moveLength)
- else:
- moveLength += currentScore.pop(2)
- currentScore.insert(2,moveLength)
- # distinceWithDoor[len(distinceWithDoor)] = getDistince(doorBeginPoint,usePoint)
- # 以mirrorPoint和可用区域重点为对称抽翻转py
- def mirrorPy(py,position):
- insertPoint = py.InsertionPoint
- centerPoint = position[0]
- newCenterPoint = [position[3][0],position[3][1]]
- newUsePoint = [position[2][0],position[2][1]]
- conf.myprint("newUsePoint after mirror =",newUsePoint)
- if((insertPoint[0]-centerPoint[0])*(insertPoint[1]-centerPoint[1])>0):
- mirrorPoint = (insertPoint[0],centerPoint[1])
- direction = 1 if (insertPoint[1]-centerPoint[1])>0 else -1;
- newCenterPoint[1]=position[3][1]+position[4][1]*direction
- newUsePoint[1]=position[2][1]+position[1][1]*direction
- else:
- mirrorPoint = (centerPoint[0],insertPoint[1])
- direction = 1 if (insertPoint[0]-centerPoint[0])>0 else -1;
- newCenterPoint[0]=position[3][0]+position[4][0]*direction
- newUsePoint[0]=position[2][0]+position[1][0]*direction
- position[3] = newCenterPoint
- position[2] = newUsePoint
- conf.myprint("newUsePoint after mirror =",newUsePoint)
- py.mirror(APoint(mirrorPoint[0],mirrorPoint[1]),APoint(centerPoint[0],centerPoint[1]))
- conf.myprint("delete blockReference name",py.name)
- needDeleteBlockReferences.append(py)
- # printObjects()
- # printBlockObjects()
- # printTheTypeObject("BlockReference")
- # moveBlockReference('222')
- # a=[0,1,2]
- # moveBlockReferenceWithNewIndex('001',a)
- # conf.myprint(isWorkable('222'))
- # getCenterPoint(3,4162.85,0,2)
- # print(getDistince((0,3),(4,0)))
- # print(getDoorBeginPoint())
|