# -*- 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(): temp = [] for item in currentScore: temp.append(item) scores.append(temp) 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() 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() currentScore.append(position) currentScore.append(moduleIndex) 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() conf.myprint("scores=",scores) 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]; 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 isUseCenterOverRoom(useCenterPosition): if useCenterPosition[0] < 0 or useCenterPosition[0]>conf.roomLengths[0] or useCenterPosition[1] < 0 or useCenterPosition[1]>conf.roomLengths[1]: return True return False # 从插入点开始顺时针记录已摆放的组件 def tempStoragePosition(x,y,wallIndex,blockIndex,blockReference): position = getCenterPoint(wallIndex, x, y, blockIndex); # 判断可用区域中点是否超出房间 if(isUseCenterOverRoom(position[3])): 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],1) 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 = "实体区域" 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+conf.doorAlign[1])/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]) currentScore.append(drawLines(includePoints)) 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]) currentScore.append(drawLines(includePoints)) # 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[1]-centerPoint[1])>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())