Quantcast
Channel: All Revit API Forum posts
Viewing all articles
Browse latest Browse all 67020

Re: Count Group (Model and Details), Instances and Types Without Arrays Counted as Groups

$
0
0

No idea whether this helps, but I asked Gemini for you. Here is the response from Gemini 1.5:

   

Certainly, let's delve into the issue of accurately counting model and detail group instances and types in Revit, excluding those within arrays.

Understanding the Problem

The provided code snippet for counting model group instances seems to have a fundamental flaw. It relies on checking if the model group ID is not present in the arrays_groups_ids list, which might not accurately exclude groups within arrays.

Key Considerations

  1. Array Membership: Determining whether a group is truly within an array is more complex than simply checking if its ID is present in the array's member IDs. A group might be a member of an array, but it could also be placed independently elsewhere in the model.
  2. Array Types: Revit arrays can have different behaviors. Some arrays might "own" their members, while others might simply reference them.
  3. Performance: Efficiently iterating through large numbers of elements and checking their relationships within arrays can significantly impact performance.

Revised Approach

Here's a revised approach that aims to more accurately count model group instances while excluding those within arrays:

Python
 
from Autodesk.Revit.DB import *defget_group_instances_count(doc, is_model_group=True):"""
    Counts the number of group instances in the given document, 
    excluding those that are members of arrays.

    Args:
        doc (Document): The Revit document to search.
        is_model_group (bool): True for model groups, False for detail groups.

    Returns:
        int: The count of group instances.
    """

    collector = (
        FilteredElementCollector(doc)
        .OfCategory(
            BuiltInCategory.OST_IOSModelGroups
            if is_model_groupelse BuiltInCategory.OST_IOSDetailGroups
        )
        .WhereElementIsNotElementType()
    )

    group_instances = list(collector)

    count = 0for group in group_instances:# Check if the group is a member of any array
        is_array_member = Falsefor array in (
            FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_IOSArrays)
        ):if group.Id in array.GetOriginalMemberIds() or group.Id in array.GetCopiedMemberIds():
                is_array_member = Truebreakifnot is_array_member:
            count += 1return count# Example usage:
model_group_instance_count = get_group_instances_count(doc, True)
detail_group_instance_count = get_group_instances_count(doc, False)

Explanation

  1. Iterate through Group Instances: The code iterates through each group instance in the document.
  2. Check Array Membership: For each group, it checks if the group's ID is present in the GetOriginalMemberIds()or GetCopiedMemberIds() of any array in the document.
  3. Count Non-Array Members: If the group is not found within any array, the count is incremented.

Key Improvements

  • Direct Array Membership Check: This approach directly checks if the group is a member of any array, providing a more accurate exclusion.
  • Readability and Maintainability: The code is more organized and easier to understand.
  • Flexibility: The function can be easily adapted to count both model and detail group instances.

Further Considerations

  • Performance Optimization: For large models, consider optimizing the array membership checks using more efficient data structures or algorithms.
  • Array Types: If you need to handle specific array types or behaviors, you might need to refine the array membership check accordingly.

Disclaimer: This revised code provides a more robust approach to counting group instances while excluding those within arrays. However, it's essential to thoroughly test it in various scenarios and with different Revit models to ensure its accuracy and reliability in your specific use cases.

I hope this revised approach and explanation are helpful! Feel free to ask if you have any further questions or require more specific guidance.

   

Gemini 2.0 is sometimes a bit smarter:

   

Let's dive into this Revit API challenge. You're on the right track, but there's a subtle nuance with how Revit handles groups within arrays that needs addressing. The issue stems from the fact that GetOriginalMemberIds and GetCopiedMemberIds return the IDs of group instances, not the group types. When a group is part of an array, Revit treats each instance within the array as a separate entity, even though they share the same group type. Your current approach counts each of these instances, leading to overcounting, especially in complex models like the Revit Architecture sample.

Here's a refined approach that leverages the group type to ensure accurate counts, even within arrays:

Python
 
import clr
clr.AddReference('RevitAPI')from Autodesk.Revit import DBdefcount_groups_and_instances(doc):"""Counts model and detail group instances and types, handling arrays correctly."""

    group_counts = {
        "model_instance_count": 0,"model_type_count": 0,"detail_instance_count": 0,"detail_type_count": 0
    }for bic in [DB.BuiltInCategory.OST_IOSModelGroups, DB.BuiltInCategory.OST_DetailGroups]:
        group_instances = DB.FilteredElementCollector(doc).OfCategory(bic).WhereElementIsNotElementType().ToElements()
        group_types = set()  # Use a set to store unique group type IDsfor instance in group_instances:
            group_type_id = instance.GetTypeId()if group_type_id notin group_types:
                group_types.add(group_type_id)# Check if this instance is part of an array. If not, increment instance count.ifnot is_instance_in_array(doc, instance.Id):if bic == DB.BuiltInCategory.OST_IOSModelGroups:
                        group_counts["model_instance_count"] += 1else:
                        group_counts["detail_instance_count"] += 1if bic == DB.BuiltInCategory.OST_IOSModelGroups:
            group_counts["model_type_count"] = len(group_types)else:
            group_counts["detail_type_count"] = len(group_types)return group_countsdefis_instance_in_array(doc, instance_id):"""Checks if an element instance is part of an array."""
    array_list = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_IOSArrays).ToElements()for array in array_list:
        member_ids = array.GetAllMemberIds() # Use GetAllMemberIds for both original and copied membersif instance_id in member_ids:returnTruereturnFalse# Example usage:
counts = count_groups_and_instances(doc)
print(counts)

Key Improvements and Explanations:

  1. Directly Working with Group Types: The code now collects group instances initially but uses instance.GetTypeId() to get the corresponding group type ID. This allows us to count unique group types, preventing overcounting due to arrays.

  2. is_instance_in_array Function: This function efficiently determines if a given group instance is part of an array by checking both original and copied member IDs. It uses array.GetAllMemberIds() which is more efficient and robust.

  3. GetAllMemberIds(): This method of the Array class is crucial. It retrieves all member IDs (both original and copied) within the array. This ensures that we correctly identify instances within arrays, regardless of whether they are original or copied. Your previous approach of using separate GetOriginalMemberIds() and GetCopiedMemberIds() and then using extend and set was inefficient.

  4. Clearer Counting Logic: The code now directly increments the instance count only if the instance is not part of an array. This logic is more explicit and avoids the need for list comprehensions and set operations for instance counting, making it more performant.

  5. Combined Function: The code consolidates the counting logic for model and detail groups into a single function, making it more organized and reusable.

Practical Demonstration:

  1. Revit Architecture Sample: Run this revised code on the Revit Architecture sample model. You should now get accurate counts for model and detail group instances and types, even those within arrays.

  2. Custom Models: Test with your own models, especially those containing complex array arrangements. The is_instance_in_array function, combined with the focus on group types, should handle these scenarios correctly.

This approach provides a more robust and accurate solution to your group counting problem. It directly addresses the issue of arrays by focusing on group types and efficiently identifying instances within arrays. This will give you the correct counts you're looking for, even in complex Revit models.

   

I'll leave it up to you to evaluate and either discard as hallucinated junk or delve in deeper by correcting mistakes and asking for further clarification. I hope this can provide a starting point at least. Please let me know whether it helps and how you end up solving this. Thank you!±

    


Viewing all articles
Browse latest Browse all 67020

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>