Create a collection of item ids Revit API in Python - python-3.x

So I am trying to use a list of input strings to isolate them in a view using Revit API. I got this far, but I am getting stuck where I am trying to create a set that takes all elements in a view and removes ones that are created from input IDs. I am doing this to end up with a set of all elements except ones that i want to isolate.
dataEnteringNode = IN0
view = IN0
str_ids = IN1
doc = __doc__
collector = FilteredElementCollector(doc, view.Id)
for i in str_ids:
int_id = int(i)
id = ElementId(int_id)
element = doc.GetElement(id)
element_set = ElementSet()
element_set.Insert(element)
elements_to_hide = collector.WhereElementIsNotElementType().Excluding(element_set).ToElements()
#Assign your output to the OUT variable
OUT = elements_to_hide
I would greatly appreciate a help in solving this error. I am getting that "expected ICollection[ElementId], got set". I am guessing the problem lies in a Excluding filter where i need to create a collection of Ids to exclude but I dont know how. Thank you in advance. Thank you for help in advance!

The reason your code doesn't work is that ElementSet in the Revit API does not implement the ICollection<T> interface - just the IEnumerable<T>. So, to get your code working, you will need to create an ICollection<T> object from your set.
Try something like this:
# ...
from System.Collections.Generic import List
element_collection = List[ElementId](element_set)
elements_to_hide = collector.WhereElementIsNotElementType().Excluding(element_collection).ToElements()

Related

Is there a more efficient way to interact with ItemPaged objects from azure-data-tables SDK function query_entities?

The quickest method I have found is to just convert the ItemPaged object to a list using list() and then I'm able to manipulate/extract using a Pandas DataFrame. However, if I have millions of results, the process can be quite time-consuming, especially if I only want every nth result over a certain time-frame, for instance. Typically, I would have to query the entire time-frame and then re-loop to only obtain every nth element. Does anyone know a more efficient way to use query_entities OR how to more efficiently return every nth item from ItemPaged or more explicitly from table.query_entities? Portion of my code below:
connection_string = "connection string here"
service = TableServiceClient.from_connection_string(conn_str=connection_string)
table_string = ""
table = service.get_table_client(table_string)
entities = table.query_entities(filter, select, etc.)
results = pd.DataFrame(list(entities))
Does anyone know a more efficient way to use query_entities OR how to more efficiently return every nth item from ItemPaged or more explicitly from table.query_entities?
After reproducing from my end, one of the ways to achieve your requirement using get_entity() instead of query_entities(). Below is the complete code that worked for me.
entity = tableClient.get_entity(partition_key='<PARTITION_KEY>', row_key='<ROW_KEY>')
print("Results using get_entity :")
print(format(entity))
RESULTS:

Why does "ElementId(BuiltInCategory.OST_Walls)" fails within Revit API 2019?

I am trying to filter walls. For that I use
categories = List[ElementId]()
myId = ElementId(BuiltInCategory.OST_Walls)
categories.Add(myId)
..but this obviously doesn't return a valid ElementId, as when I print it, it has some negative value (and if I print "doc.GetElement(myId)", I get "None").
Then, indeed when creating the filter...
filter = ParameterFilterElement.Create(doc, "Walls filter", categories)
...I get an ArgumentException.
I'm using Revit 2019 (with pyRevit). As far as I remember, it used to work with Revit 2018, but I don't see any reason it shouldn't anymore. What am I missing?
Thanks a lot!
You can simply use the filtered element collector OfCategory Method.
E.g., check out The Building Coder hints on filtered element collector optimisation.
Apply an ElementCategoryFilter to the collector to get all the walls of the project. By using the following code you can filter any kind of category. I have tried this on Revit 2019.
FilteredElementCollector collector = new FilteredElementCollector(document);
ICollection<Element> walls = collector.OfCategory(BuiltInCategory.OST_Walls).ToElements();
I agree with #Mah Noor answer.
If you need to have a filter with multiple categories, you can use:
ElementCategoryFilter wallFilter = new ElementCategoryFilter(BuiltInCategory.OST_Walls);
ElementCategoryFilter windowFilter = new ElementCategoryFilter(BuiltInCategory.OST_Windows);
LogicalOrFilter wallAndWindowFilter = new LogicalOrFilter(wallFilter, windowFilter);
ICollection<Element> collection = new FilteredElementCollector(doc).WherePasses(wallAndWindowFilter);
Bonus tip, you may want to add .WhereElementIsNotElementType() or .WhereElementIsElementType() to your query.
Best regards
François

NotesException: Unknown or unsupported object type in Vector

I'm trying to add new names to the address book programmatically but I'm getting the following error:
[TypeError] Exception occurred calling method NotesDocument.replaceItemValue(string, Array)
Unknown or unsupported object type in Vector
Code snippet below:
var addressBook = session.getDatabase("","names.nsf");
var gView:NotesView = addressBook.getView("($VIMGroups)");
var gDoc:NotesDocument = gView.getDocumentByKey("groupName", true);
var newg:java.util.Vector = [];
var mems:java.util.Vector = new Array(gDoc.getItemValue('Members'));
newg.push(mems);
var newNames:java.util.Vector = new Array(getComponent("NewMems").getValue());
newg.push(newNames);
gDoc.replaceItemValue("Members", newg);
gDoc.save();
Adding a single user works fine, but then it does not save users in the required canonical format below:
CN=John Doe/O=Org
Instead it is saved in the original format below:
John Doe/Org
I look forward to your suggestions. Thanks.
You can't store an Array in a field. Make newg a java.util.Vector instead and integrate with that.
For OpenNTF Domino API the team wrote a lot of code to auto-convert to Vectors, which may cover Arrays.
Don't use an Array (which is a JS thing). Initialize it as a Vector.
var newg:java.util.Vector = new java.util.Vectory();
Then look up the Vector methods to see how to add to that vector. Not sure if you will have to convert the names using the Name method but I would store them as "CN=Joe Smith/O=Test Org" to be sure you got the right format.
I was able to solve the issue using a forloop to loop through the list and push it into a newly created array. Using the forloop seems to make the difference.
var newg = [];
var group = new Array(getComponent("NewMems").getValue()), lenGA = group.length;
for(i = 0; i < lenGA; i++){
newg.push(group[i]);
}
gDoc.replaceItemValue("Members", newg);
gDoc.save();
An explanation about this behaviour will be appreciated.

How to extract raw values for comparison or manipulation from Gremlin (Tinkerpop)

I know I'm missing something obvious here. I'm trying to extract values from TitanDB using Gremlin in order to compare them within Groovy.
graph = TinkerFactory.createModern()
g = graph.traversal(standard())
markoCount = g.V().has('name','marko').outE('knows').count()
lopCount = g.V().has('name','lop').outE('knows').count()
if(markoCount > lopCount){
// Do something
}
But apparently what I'm actually (incorrectly) doing here is comparing traversal steps which obviously won't work:
Cannot compare org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal with value '[TinkerGraphStep(vertex,[name.eq(marko)]), VertexStep(OUT,[knows],edge), CountGlobalStep]' and org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal with value '[TinkerGraphStep(vertex,[name.eq(lop)]), VertexStep(OUT,[knows],edge), CountGlobalStep]'
I'm having the same issue extracting values from properties for use in Groovy as well. I didn't see anything in the docs indicating how to set raw values like this.
What is needed to return actual values from Gremlin that I can use later in my Groovy code?
Figured it out, I needed next():
graph = TinkerFactory.createModern()
g = graph.traversal(standard())
markoCount = g.V().has('name','marko').outE('knows').count().next()
lopCount = g.V().has('name','lop').outE('knows').count().next()
if(markoCount > lopCount){
// Do something
}

CouchDB "[Circular]" when writing to an array

In CouchDB, I am writing to an array and keep getting the message "[Circular]". I am using Node.js to create the data to be written like this.
Say I have an two email objects in the same document in CouchDB:
unverifiedEmail = [{"address":"john#example.com","dateAdded":"1389215329484"}]
verifiedEmail = []
Now in Node.js I do this before writing.
var oldData = readFromCouchDb();
var newData = oldData;
newData.verifiedEmail.unshift(newData.unverifiedEmail[0]);
writeToCouchDb(newData);
Then when I view the document in Futon I see this:
unverifiedEmail = [{"address":"john#example.com","dateAdded":"1389215329484"}]
verifiedEmail = "[Circular]"
What's going on here?
I found out the issue has to do with the depth of the way to set Javascript objects equal to each other.
To solve this, I used the following code in place of the unshift above:
newData.verifiedEmail.unshift(JSON.parse(JSON.stringify(newData.unverifiedEmail[0])));

Resources