I'm trying to write a script to record player movement in Rocket League using the RLBot framework. I've got very minimal experience with code and I've been getting the error:
Traceback (most recent call last):
File "c:/Users/Julian/AppData/Local/RLBotGUIX/RLBotPackDeletable/RLBotPack-master/RLBotPack/CustomMutators/playerRecorder.py", line 27, in <module>
class playerRecorder(BaseScript):
File "c:/Users/Julian/AppData/Local/RLBotGUIX/RLBotPackDeletable/RLBotPack-master/RLBotPack/CustomMutators/playerRecorder.py", line 45, in playerRecorder
for car in packet.game_cars:
NameError: name 'packet' is not defined
Packet is defined within def run(self): but I'm still getting an error for it not being defined. Below is my full script from within VS Code. Any help is appreciated.
from typing import Optional
from rlbot.agents.base_agent import BaseAgent, GameTickPacket, SimpleControllerState
import os
import time
import math
from rlbot.agents.base_agent import BaseAgent, SimpleControllerState
from rlbot.utils.structures.game_data_struct import GameTickPacket
from rlbot.utils.game_state_util import GameState, BallState, CarState, Physics, Vector3 as vector3, Rotator
import random
from rlbot.agents.base_script import BaseScript
from rlbot.utils.game_state_util import GameState
DIRECTORY_LOCATION = "C:\Logs\Recorder\log"
randNum = random.randint(0,9999999999)
# Extending the BaseScript class is purely optional. It's just convenient / abstracts you away from
# some strange classes like GameInterface
class playerRecorder(BaseScript):
def __init__(self):
super().__init__("playerRecorder")
packet = self.get_game_tick_packet()
self.writeFile = open(DIRECTORY_LOCATION+"\\"+"HumanLog"+str(car.team)+"-"+str(randNum), "w")
def run(self):
while True:
packet = self.get_game_tick_packet()
get_output(packet)
sleep(1 / 3)
print("test")
for car in packet.game_cars:
if not car.is_bot:
team = car.team
index = car.index
break
def get_output(self, game_tick_packet):
#***************************************************************
packet = self.get_game_tick_packet()
goodTeam = str(car.team)
goodLoc = packet.game_cars[car.index].physics.location
goodLocX = str(goodLoc.x)
goodLocY = str(goodLoc.y)
goodLocZ = str(goodLoc.z)
goodRot = packet.game_cars[car.index].physics.rotation
goodRotP = str(goodRot.pitch)
goodRotY = str(goodRot.yaw)
goodRotR = str(goodRot.roll)
goodVel = packet.game_cars[car.index].physics.velocity
goodVelX = str(goodVel.x)
goodVelY = str(goodVel.y)
goodVelZ = str(goodVel.z)
goodAngVel = packet.game_cars[car.index].physics.angular_velocity
goodAngVelX = str(goodAngVel.x)
goodAngVelY = str(goodAngVel.y)
goodAngVelZ = str(goodAngVel.z)
hasWC = str(packet.game_cars[car.index].has_wheel_contact)
isSS = str(packet.game_cars[car.index].is_super_sonic)
jumped = str(packet.game_cars[car.index].jumped)
dJumped = str(packet.game_cars[car.index].double_jumped)
bst = str(packet.game_cars[car.index].boost)
ballLoc = packet.game_ball.physics.location
ballLocX = str(ballLoc.x)
ballLocY = str(ballLoc.y)
ballLocZ = str(ballLoc.z)
ballVel = packet.game_ball.physics.velocity
ballVelX = str(ballVel.x)
ballVelY = str(ballVel.y)
ballVelZ = str(ballVel.z)
self.writeFile.write(goodTeam+";"+
goodLocX+","+goodLocY+","+goodLocZ+";"+
goodRotP+","+goodRotY+","+goodRotR+";"+
goodVelX+","+goodVelY+","+goodVelZ+";"+
goodAngVelX+","+goodAngVelY+","+goodAngVelZ+";"+
hasWC+";"+isSS+";"+jumped+";"+dJumped+";"+bst+";"+
ballLocX+","+ballLocY+","+ballLocZ+";"+
ballVelX+","+ballVelY+","+ballVelZ)
self.writeFile.write("\n")
## WRITE OPPONENT
badIndex = -1
for i in range(len(packet.game_cars)):
if i != car.index:
badIndex = i
break
assert badIndex != car.index
assert badIndex != -1
badTeam = str(packet.game_cars[badIndex].team)
badLoc = packet.game_cars[badIndex].physics.location
badLocX = str(badLoc.x)
badLocY = str(badLoc.y)
badLocZ = str(badLoc.z)
badRot = packet.game_cars[badIndex].physics.rotation
badRotP = str(badRot.pitch)
badRotY = str(badRot.yaw)
badRotR = str(badRot.roll)
badVel = packet.game_cars[badIndex].physics.velocity
badVelX = str(badVel.x)
badVelY = str(badVel.y)
badVelZ = str(badVel.z)
badAngVel = packet.game_cars[badIndex].physics.angular_velocity
badAngVelX = str(badAngVel.x)
badAngVelY = str(badAngVel.y)
badAngVelZ = str(badAngVel.z)
badhasWC = str(packet.game_cars[badIndex].has_wheel_contact)
badisSS = str(packet.game_cars[badIndex].is_super_sonic)
badjumped = str(packet.game_cars[badIndex].jumped)
baddJumped = str(packet.game_cars[badIndex].double_jumped)
badbst = str(packet.game_cars[badIndex].boost)
self.writeFile.write(badTeam+";"+
badLocX+","+badLocY+","+badLocZ+";"+
badRotP+","+badRotY+","+badRotR+";"+
badVelX+","+badVelY+","+badVelZ+";"+
badAngVelX+","+badAngVelY+","+badAngVelZ+";"+
badhasWC+";"+badisSS+";"+badjumped+";"+baddJumped+";"+badbst)
self.writeFile.write("\n")
## WRITE ACTION
self.writeFile.write(str(action.throttle)+";"+str(action.steer)+";"+str(action.pitch)+";"+str(action.yaw)+";"+str(action.action.roll)+";"+str(action.jump)+";"+str(action.boost))
self.writeFile.write("\n")
##*****************************************************
return action
In the run(...) function you should type self.get_output(packet) instead of get_output(). You have to pass a packet as a parameter to a function and also you should write self before the name of a function because it's inside a class. I think you also misspelled the parameter of the get_output function because you've named it game_tick_packet and in the function you are using variable named just a packet.
Related
I have these 2 functions that are really similar except for the different format of log it will receive and return. One look and return 4 values when the other return 3.
Is there any way I can make 1 general function for these 2? Thank you
> - Borrow book: B#<day>#<Student Name>#<Book name>#<days borrowed for>
> - Return book: R#<day>#<Student Name>#<Book name>
def read_borrow_log(log):
borrow_day = []
borrow_student = []
borrow_book = []
borrow_duration = []
for line in log:
hash_func = line.find("#")
hash_day = line.find("#", hash_func+1)
hash_student = line.find("#", hash_day+1)
hash_book = line.find("#", hash_student+1)
hash_duration = line.find("#", hash_book+1)
borrow_day.append(int(line[(hash_func+1):(hash_day)]))
borrow_student.append(line[(hash_day+1):(hash_student)])
borrow_book.append(line[(hash_student+1):(hash_duration)])
borrow_duration.append(line[(hash_duration+1):])
return borrow_day, borrow_student, borrow_book, borrow_duration
def read_return_log(log):
return_day = []
return_student = []
return_book = []
for line in log:
hash_func = line.find("#")
hash_day = line.find("#", hash_func+1)
hash_student = line.find("#", hash_day+1)
return_day.append(int(line[(hash_func+1):(hash_day)]))
return_student.append(line[(hash_day+1):(hash_student)])
return_book.append(line[(hash_student+1):])
return return_day, return_student, return_book
def main():
borrow_day, borrow_student, borrow_book, borrow_duration = read_borrow_log(borrow_log)
return_day, return_student, return_book = read_return_log(return_log)
Try using python's built-in string split:
def extract_log_parts(log):
recs = []
for line in log:
recs.append(line.split('#'))
# we want the record *columns* -- transpose the table
return tuple(map(list, zip(*recs)))
one thing you might do is to make the 'extra' work done only when a certain optional parameter is passed in as shown:
def read_borrow_log(log,borrow_log=True):
borrow_day = []
borrow_student = []
borrow_book = []
if borrow_log is True:
borrow_duration = []
for line in log:
hash_func = line.find("#")
hash_day = line.find("#", hash_func + 1)
hash_student = line.find("#", hash_day + 1)
if borrow_log is True:
hash_book = line.find("#", hash_student + 1)
hash_duration = line.find("#", hash_book + 1)
borrow_day.append(int(line[(hash_func + 1):(hash_day)]))
borrow_student.append(line[(hash_day + 1):(hash_student)])
borrow_book.append(line[(hash_student + 1):(hash_duration)])
if borrow_log is True:
borrow_duration.append(line[(hash_duration + 1):])
if borrow_log is True:
return borrow_day, borrow_student, borrow_book, borrow_duration
else:
return borrow_day, borrow_student, borrow_book
def main():
borrow_day, borrow_student, borrow_book, borrow_duration = read_borrow_log(borrow_log)
return_day, return_student, return_book = read_borrow_log(return_log,borrow_log=False)
however you might want to rethink the naming convention used since this function will now do more than one thing, which is bad for documentation purposes (and is generally a bad practice to have functions do more than one thing, bad enough that i should downvote my own answer if i can)
I have created GUI program in python which converts C2F and F2C when I run my program I get an error though I imported module correctly. Can anyone please help me to solve an error
Code:
from breezypythongui import EasyFrame
#from tkinter import PhotoImage
from tkinter import *
class ProgDemo(EasyFrame):
def __init__(self):
EasyFrame.__init__(self,width="600", title = "Program")
self.addLabel(text = "Temp",row = 1, column = 0)
self.getinput = self.addFloatField(value = 0.0,row = 1,column = 1)
self.addLabel(text = "Output",row = 2, column = 0)
self.op = self.addFloatField(value = 0.0,row = 2,column = 1)
self.grp1 = self.addRadiobuttonGroup(row = 3,column = 0)
C_to_F = self.grp1.addRadiobutton(text = "C to F")
F_to_C = self.grp1.addRadiobutton(text = "F to C")
self.conBtn = self.addButton(text = "convert",row = 5, column = 0,command = self.tempc)
self.resetBtn = self.addButton(text = "reset",row = 5, column = 1,command = self.reseti)
def tempc(self):
ipval = self.getinput.getNumber()
if self.grp1.getSelectedButton()["value"] == "C to F":
op = 9.0/5.0 * ipval + 32
else:
op = (ipval - 32) * 5.0/9.0
self.op.setValue(op)
def reseti(self):
self.getinput.setValue(0);
self.op.setValue(0);
def main():
ProgDemo().mainloop()
if __name__ == "__main__":
main()
Screenshot:
It seems like, the module is missing and you need it.
So download and install it: http://home.wlu.edu/~lambertk/breezypythongui/
You need to have the module breezepythongui.py and your python code in the same folder. Not only having the folder but both modules must be in the same folder.
For example; My python code "myfirstguiproject.py" and "breezypythongui.py" are in the same folder.
I know when you extract the downloaded zip file named breezypythongui.zip, it will create a folder and in that folder there is the "breezypythongui.py" module. You need to get rid of the folder and only keep the module (breezypythongui.py).
I`ve obtain this error
File "/class.py", line 246, in __init__
if d and self.rf == 2 and d["descriptionType"] in ["900000000000003001"] and d["conceptId"] in konZer.zerrenda:
TypeError: 'Desk' object is not subscriptable
I created this object
class Desk:
descriptionId = ""
descriptionStatus = ""
conceptId = ""
term = ""
And I called it in another class
class DescriptionList():
def deskJ(self,line):
er = line.strip().split('\t')
desc = Desk()
if er[1] == "0":
desc.descriptionId = er[0]
desc.descriptionStatus = er[1]
desc.conceptId = er[2]
desc.term = er[3]
return description
Then I called the function "deskJ" at init and I get the error at this part (I've deleted some parts of the function):
def __init__(self,fitx,konZer,lanZer={}):
with codecs.open(fitx,encoding='utf-8') as fitx:
lines = fitx.read().split('\n')[1:-1]
for line in lines:
d = self.deskJ(line)
if d and self.rf == 2 and d["descriptionType"] in ["900000000000003001"] and d["conceptId"] in konZer.zerrenda:
c = konZer.zerrenda[d["conceptId"]]
c["fullySpecifiedName"] = d["term"]
What am I doing wrong?
Using d["descriptionType"] is trying to access d with the key "descriptionType". That doesn't work, though, because d is a Desk object that doesn't have keys. Instead, get the attributes:
if d and self.rf == 2 and d.descriptionType in ["900000000000003001"] and d.conceptId in konZer.zerrenda:
I have a question for some of you who are familiar with the Revit API and python:
I’ve been using the spring nodes package in dynamo to create a rather large series of freeform objects each in their own family. The way that the FamilyInstance.ByGeometry works, it takes a list of solids and creates a family instance for each using a template family file. The result is quite good. (spring nodes can be found here: https://github.com/dimven/SpringNodes)
However, the drawback is that that now I have roughly 200 separate instances, so to make changes to each is rather painful. I thought at first it would be possible to use dynamo to create a new subcategory and set the solid inside each family instance to this new subcategory. Unfortunately, I realized this is not possible since dynamo cannot be open in two different Revit environments simultaneously (the project I am working in and each instance of the family). This leads me to look to see if I can do this using python.
I have used python in rhino and can get along pretty well, I am still learning the Revit API however. But basically my idea would be to:
1. select a series of family instances in the Revit project environment
2. loop through each instance
3. save it to a specified location
4. create a new subcategory in each family instances (the subcategory would the same for all the selected family instances)
5. select the solid in each in instance
6. set the solid to this newly created subcategory
7. close the family instance and save
My question for you is does this sound like it is achievable based on your knowledge of the Revit API?
Many thanks for your time and advice.
UPDATE:
I've found a section in the revit api that describes what i'm looking to do: http://help.autodesk.com/view/RVT/2015/ENU/?guid=GUID-FBF9B994-ADCB-4679-B50B-2E9A1E09AA48
I've made a first pass at inserting this into the python code of the dynamo node. The rest of the code works fine except for the new section im adding (see below). Please excuse the variables, I am simply keeping with logic of the original author of the code i am hacking:
(Note: the variables come in are in arrays)
#set subcategory
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
Any help or advice with this section of code would be much appreciated.
UPDATE:
See full code below for context of the section in question:
#Copyright(c) 2015, Dimitar Venkov
# #5devene, dimitar.ven#gmail.com
import clr
import System
from System.Collections.Generic import *
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
import sys
sys.path.append("%s\IronPython 2.7\Lib" %pf_path)
import traceback
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import StructuralType
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
def output1(l1):
if len(l1) == 1: return l1[0]
else: return l1
def PadLists(lists):
len1 = max([len(l) for l in lists])
for i in xrange(len(lists)):
if len(lists[i]) == len1:
continue
else:
len2 = len1 - len(lists[i])
for j in xrange(len2):
lists[i].append(lists[i][-1])
return lists
class FamOpt1(IFamilyLoadOptions):
def __init__(self):
pass
def OnFamilyFound(self,familyInUse, overwriteParameterValues):
return True
def OnSharedFamilyFound(self,familyInUse, source, overwriteParameterValues):
return True
geom = tolist(IN[0])
fam_path = IN[1]
names = tolist(IN[2])
category = tolist(IN[3])
material = tolist(IN[4])
isVoid = tolist(IN[5])
subcategory = tolist(IN[6])
isRvt2014 = False
if app.VersionName == "Autodesk Revit 2014": isRvt2014 = True
units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits
factor = UnitUtils.ConvertToInternalUnits(1,units)
acceptable_views = ["ThreeD", "FloorPlan", "EngineeringPlan", "CeilingPlan", "Elevation", "Section"]
origin = XYZ(0,0,0)
str_typ = StructuralType.NonStructural
def NewForm_background(s1, name1, cat1, isVoid1, mat1, subcat1):
t1 = TransactionManager.Instance
TransactionManager.ForceCloseTransaction(t1)
famdoc = doc.Application.NewFamilyDocument(fam_path)
message = None
temp_path = System.IO.Path.GetTempPath()
sat_path = "%s%s.sat" % (temp_path, name1)
try:
if factor != 1:
s1 = s1.Scale(factor)
sat1 = Geometry.ExportToSAT(s1, sat_path)
satOpt = SATImportOptions()
satOpt.Placement = ImportPlacement.Origin
satOpt.Unit = ImportUnit.Foot
view_fec = FilteredElementCollector(famdoc).OfClass(View)
view1 = None
for v in view_fec:
if str(v.ViewType) in acceptable_views:
view1 = v
break
t1.EnsureInTransaction(famdoc)
satId = famdoc.Import(sat1, satOpt, view1)
opt1 = Options()
opt1.ComputeReferences = True
el1 = famdoc.GetElement(satId)
geom1 = el1.get_Geometry(opt1)
enum = geom1.GetEnumerator()
enum.MoveNext()
geom2 = enum.Current.GetInstanceGeometry()
enum2 = geom2.GetEnumerator()
enum2.MoveNext()
s1 = enum2.Current
famdoc.Delete(satId)
TransactionManager.ForceCloseTransaction(t1)
System.IO.File.Delete(sat_path)
except:
message = traceback.format_exc()
pass
if message == None:
try:
save_path = "%s%s.rfa" % (temp_path, name1)
SaveAsOpt = SaveAsOptions()
SaveAsOpt.OverwriteExistingFile = True
t1.EnsureInTransaction(famdoc)
#set the category
try:
fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name)
famdoc.OwnerFamily.FamilyCategory = fam_cat
except: pass
s2 = FreeFormElement.Create(famdoc,s1)
if isVoid1:
void_par = s2.get_Parameter("Solid/Void")
void_par.Set(1)
void_par2 = famdoc.OwnerFamily.get_Parameter("Cut with Voids When Loaded")
void_par2.Set(1)
else: #voids do not have a material value
try:
mat_fec = FilteredElementCollector(famdoc).OfClass(Material)
for m in mat_fec:
if m.Name == mat1:
fam_mat = m
break
mat_par = s2.get_Parameter("Material")
mat_par.Set(fam_mat.Id)
except: pass
#set subcategory
try:
#create new sucategory
fam_subcat = document.Settings.Categories.NewSubcategory(document.OwnerFamily.FamilyCategory, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
TransactionManager.ForceCloseTransaction(t1)
famdoc.SaveAs(save_path, SaveAsOpt)
family1 = famdoc.LoadFamily(doc, FamOpt1())
famdoc.Close(False)
System.IO.File.Delete(save_path)
symbols = family1.Symbols.GetEnumerator()
symbols.MoveNext()
symbol1 = symbols.Current
t1.EnsureInTransaction(doc)
if not symbol1.IsActive: symbol1.Activate()
inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ)
TransactionManager.ForceCloseTransaction(t1)
return inst1.ToDSType(False), family1.ToDSType(False)
except:
message = traceback.format_exc()
return message
else:
return message
def NewForm_background_R16(s1, name1, cat1, isVoid1, mat1, subcat1):
t1 = TransactionManager.Instance
TransactionManager.ForceCloseTransaction(t1)
famdoc = doc.Application.NewFamilyDocument(fam_path)
message = None
temp_path = System.IO.Path.GetTempPath()
sat_path = "%s%s.sat" % (temp_path, name1)
try:
if factor != 1:
s1 = s1.Scale(factor)
sat1 = Geometry.ExportToSAT(s1, sat_path)
satOpt = SATImportOptions()
satOpt.Placement = ImportPlacement.Origin
satOpt.Unit = ImportUnit.Foot
view_fec = FilteredElementCollector(famdoc).OfClass(View)
view1 = None
for v in view_fec:
if str(v.ViewType) in acceptable_views:
view1 = v
break
t1.EnsureInTransaction(famdoc)
satId = famdoc.Import(sat1, satOpt, view1)
opt1 = Options()
opt1.ComputeReferences = True
el1 = famdoc.GetElement(satId)
geom1 = el1.get_Geometry(opt1)
enum = geom1.GetEnumerator()
enum.MoveNext()
geom2 = enum.Current.GetInstanceGeometry()
enum2 = geom2.GetEnumerator()
enum2.MoveNext()
s1 = enum2.Current
famdoc.Delete(satId)
TransactionManager.ForceCloseTransaction(t1)
System.IO.File.Delete(sat_path)
except:
message = traceback.format_exc()
pass
if message == None:
try:
save_path = "%s%s.rfa" % (temp_path, name1)
SaveAsOpt = SaveAsOptions()
SaveAsOpt.OverwriteExistingFile = True
t1.EnsureInTransaction(famdoc)
#set the category
try:
fam_cat = famdoc.Settings.Categories.get_Item(cat1.Name)
famdoc.OwnerFamily.FamilyCategory = fam_cat
except: pass
s2 = FreeFormElement.Create(famdoc,s1)
if isVoid1:
void_par = s2.LookupParameter("Solid/Void")
void_par.Set(1)
void_par2 = famdoc.OwnerFamily.LookupParameter("Cut with Voids When Loaded")
void_par2.Set(1)
else: #voids do not have a material value
try:
mat_fec = FilteredElementCollector(famdoc).OfClass(Material)
for m in mat_fec:
if m.Name == mat1:
fam_mat = m
break
mat_par = s2.LookupParameter("Material")
mat_par.Set(fam_mat.Id)
except: pass
#apply same subcategory code as before
#set subcategory
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(fam_cat, get_Item(subcat1.Name))
#assign the mataterial(fam_mat.Id) to the subcategory
fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
TransactionManager.ForceCloseTransaction(t1)
famdoc.SaveAs(save_path, SaveAsOpt)
family1 = famdoc.LoadFamily(doc, FamOpt1())
famdoc.Close(False)
System.IO.File.Delete(save_path)
symbols = family1.GetFamilySymbolIds().GetEnumerator()
symbols.MoveNext()
symbol1 = doc.GetElement(symbols.Current)
t1.EnsureInTransaction(doc)
if not symbol1.IsActive: symbol1.Activate()
inst1 = doc.Create.NewFamilyInstance(origin, symbol1, str_typ)
TransactionManager.ForceCloseTransaction(t1)
return inst1.ToDSType(False), family1.ToDSType(False)
except:
message = traceback.format_exc()
return message
else:
return message
if len(geom) == len(names) == len(category) == len(isVoid) == len(material) == len(subcategory):
if isRvt2014:
OUT = output1(map(NewForm_background, geom, names, category, isVoid, material, subcategory))
else:
OUT = output1(map(NewForm_background_R16, geom, names, category, isVoid, material, subcategory))
elif len(geom) == len(names):
padded = PadLists((geom, category, isVoid, material, subcategory))
p_category = padded[1]
p_isVoid = padded[2]
p_material = padded[3]
p_subcategory = padded [4]
if isRvt2014:
OUT = output1(map(NewForm_background, geom, names, p_category, p_isVoid, p_material, p_subcategory))
else:
OUT = output1(map(NewForm_background_R16, geom, names, p_category, p_isVoid, p_material, subcategory))
else: OUT = "Make sure that each geometry\nobject has a unique family name."
Update:
Was able to get it working:
try:
#create new sucategory
fam_subcat = famdoc.Settings.Categories.NewSubcategory(famdoc.OwnerFamily.FamilyCategory, subcat1)
#assign the mataterial(fam_mat.Id) to the subcategory
#fam_subcat.Material = famdoc.GetElement(fam_mat.Id)
#assign the subcategory to the element (s2)
s2.Subcategory = fam_subcat
except: pass
As I answered on your initial query per email, what you are aiming for sounds perfectly feasible to me in the Revit API. Congratulations on getting as far as you have. Looking at the link to the Revit API help file and developer guide that you cite above, it seems that the code has to be executed in the family document while defining the family. The context in which you are trying to execute it is not clear. Have you used EditFamily to open the family definition document? What context are you executing in?
Here's the error:
File "/Users/KarenLee/Desktop/temp/worldmodel.py", line 76, in update_on_time
obj = VeinAction(entity, image_store)
NameError: global name 'VeinAction' is not defined
And here is my code (this is in the file "actions.py"):
import entities
import worldmodel
import pygame
import math
import random
import point
import image_store
BLOB_RATE_SCALE = 4
BLOB_ANIMATION_RATE_SCALE = 50
BLOB_ANIMATION_MIN = 1
BLOB_ANIMATION_MAX = 3
FREEZE_ANIMATION_RATE = 100
FREEZE_STEPS = 4
ORE_CORRUPT_MIN = 20000
ORE_CORRUPT_MAX = 30000
QUAKE_STEPS = 10
QUAKE_DURATION = 1100
QUAKE_ANIMATION_RATE = 100
VEIN_SPAWN_DELAY = 500
VEIN_RATE_MIN = 8000
VEIN_RATE_MAX = 17000
WYVERN_RATE_MIN = 200
WYVERN_RATE_MAX = 600
WYVERN_ANIMATION_RATE = 100
class VeinAction:
def __init__(self, entity, image_store):
self.entity = entity
self.image_store = image_store
def vein_action(self, world, action, ticks):
entity = self.entity
open_pt = find_open_around(world, entities.get_position(entity),
entities.get_resource_distance(entity))
if open_pt:
ore = create_ore(world,
"ore - " + entities.get_name(entity) + " - " + str(ticks),
open_pt, ticks, action.image_store)
worldmodel.add_entity(world, ore)
tiles = [open_pt]
else:
tiles = []
schedule_action(world, entity, VeinAction(entity, action.image_store),
ticks + entities.get_rate(entity))
return tiles
def vein_take_action(self, world, action, ticks):
entities.remove_pending_action(self.entity, action)
if isinstance(action, VeinAction):
return self.vein_action(world, action, ticks)
And this is in the file "worldmodel.py":
import entities
import pygame
import ordered_list
import actions
import occ_grid
import point
class WorldModel:
def __init__(self, num_rows, num_cols, background):
self.background = occ_grid.Grid(num_cols, num_rows, background)
self.num_rows = num_rows
self.num_cols = num_cols
self.occupancy = occ_grid.Grid(num_cols, num_rows, None)
self.entities = []
self.action_queue = ordered_list.OrderedList()
def update_on_time(world, ticks):
tiles = []
next = world.action_queue.head()
obj = VeinAction(entity, image_store)
while next and next.ord < ticks:
world.action_queue.pop()
tiles.extend(obj.vein_take_action(world, next.item, ticks))
tiles.extend(actions.take_action(world, next.item, ticks))
next = world.action_queue.head()
return tiles
The error message comes from the update_on_time function in "worldmodel.py". I thought that this was how you would call a method from a class in a different file in a function, but it doesn't work! What is the correct way to do this? Or, is it possible to do this? Thanks in advance.
You imported the module actions which contains the class VeinAction. However, Python does not know this. You need to tell Python where VeinAction is located by adding actions. before it:
obj = actions.VeinAction(entity, image_store)
That, or you could import VeinAction directly:
from actions import VeinAction
Either way, you need to make sure that Python can find the class VeinAction.