GetOriginalGeometry and get_Geometry position

Hi everyone, I am trying to use GetOriginalGeometry and get_Geometry in the same code. However, when I choose just get_Geometry for the same element, it shows the wrong position even though I used the GetTransformed() method. It works correctly for GetOriginalGeometry. Am I doing something wrong?

clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import GeometryInstance
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Lấy tài liệu hiện tại
doc = DocumentManager.Instance.CurrentDBDocument

# Lấy FamilyInstance
familyInstance = UnwrapElement(IN[0])
getOriginal = IN[1]
# Lấy GeometryElement từ FamilyInstance
options = Options()
if getOriginal:
    geometryElement = familyInstance.GetOriginalGeometry(options).GetTransformed(familyInstance.GetTransform())
else:
    geometryElement = familyInstance.get_Geometry(options).GetTransformed(familyInstance.GetTransform())

# Danh sách các vật liệu và solids
solids = []
materials = []

# Duyệt qua các GeometryObject trong GeometryElement
for geomObj in geometryElement:
    # Kiểm tra nếu geomObj là Solid
    if isinstance(geomObj, Solid) and geomObj.Volume > 0:  # Kiểm tra nếu Solid có thể tích lớn hơn 0
        solid = geomObj
        solids.append(solid.ToProtoType())
        
        subdict = {}
        for face in solid.Faces:
            mat_id = face.MaterialElementId
            if mat_id.IntegerValue != -1:  # Kiểm tra nếu có vật liệu
                mat_e = doc.GetElement(mat_id)
                subdict[mat_id] = mat_e
        
        # Chuyển subdict thành danh sách các vật liệu không trùng lặp
        sublist = list(set(subdict.values()))
        materials.extend(sublist)
OUT = solids

on this documentation, check the remark

The instance's geometry will reflect the values of all instance level parameters (e.g. reference levels for columns) and of the placement conditions (so a beam placed along a 20' long line will be 20' long). It excludes all modifications made to the geometry due to operations like joining, cutting, openings, coping, or extensions.

in short:
GetOriginalGeometry = unmodified instance
get_Geometry = modified instance

1 Like

Thank you @jmark , but I think there might be a misunderstanding about my issue. I selected one element and ran the same code, only changing the parameter from true to false to use 1 of these method. However, in Dynamo, the element is displayed in two different positions. I understand what get_Geometry and GetOriginalGeometry do. I want to know about the position after using GetTransformed(). The geometry from GetOriginalGeometry is in the correct position, but the geometry from get_Geometry is still in the wrong position. I’m using Element.Geometry to determine which one is incorrectly positioned.

Hi,

familyInstance.get_Geometry(options) return, an
IEnumerable of GeometryObject including GeometryInstance (not necessarily a solid)

here a solution

import clr
import sys
import re
pyEngineName = sys.implementation.name 
# example usage
# if pyEngineName == "ironpython":
import System
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import GeometryInstance
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Lấy tài liệu hiện tại
doc = DocumentManager.Instance.CurrentDBDocument

# Lấy FamilyInstance
familyInstance = UnwrapElement(IN[0])
getOriginal = IN[1]
# Lấy GeometryElement từ FamilyInstance
options = Options()
if getOriginal:
    geometryElement = familyInstance.GetOriginalGeometry(options)#.GetTransformed(familyInstance.GetTransform())
else:
    geometryElement = [x for geo in familyInstance.get_Geometry(options) for x in geo.GetInstanceGeometry()]#.GetTransformed(familyInstance.GetTransform())

# Danh sách các vật liệu và solids
solids = []
materials = []

# Duyệt qua các GeometryObject trong GeometryElement
for geomObj in geometryElement:
    # Kiểm tra nếu geomObj là Solid
    if isinstance(geomObj, Solid) and geomObj.Volume > 0:  # Kiểm tra nếu Solid có thể tích lớn hơn 0
        solid = geomObj
        solids.append(solid.ToProtoType())
        
        subdict = {}
        for face in solid.Faces:
            mat_id = face.MaterialElementId
            if mat_id.IntegerValue != -1:  # Kiểm tra nếu có vật liệu
                mat_e = doc.GetElement(mat_id)
                subdict[mat_id] = mat_e
        
        # Chuyển subdict thành danh sách các vật liệu không trùng lặp
        sublist = list(set(subdict.values()))
        materials.extend(sublist)
OUT = solids, geometryElement
1 Like

@c.poupin
thank you a lot, you don’t know how amazing you are
here my final code, to get solid and solid material from FamilyInstance can choose get OriginalGeometry or not by boolean, hope will help somebody who want to do it

import clr
import System
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB import GeometryInstance
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

# Lấy tài liệu hiện tại
doc = DocumentManager.Instance.CurrentDBDocument

# Lấy FamilyInstance
familyInstance = UnwrapElement(IN[0])
getOriginal = IN[1]
# Lấy GeometryElement từ FamilyInstance
options = Options()
if getOriginal:
    geometryElement = familyInstance.GetOriginalGeometry(options).GetTransformed(familyInstance.GetTransform())
else:
    geometryElement = familyInstance.get_Geometry(options)

# Danh sách các vật liệu và solids
solids = []
materials = []

# Hàm đệ quy để lấy tất cả các GeometryObject từ GeometryElement
def get_all_solids(geoElement):
    for geomObj in geoElement:
        if isinstance(geomObj, Solid) and geomObj.Volume > 0:
            solids.append(geomObj.ToProtoType())
            
            subdict = {}
            for face in geomObj.Faces:
                mat_id = face.MaterialElementId
                if mat_id.IntegerValue != -1:
                    mat_e = doc.GetElement(mat_id)
                    subdict[mat_id] = mat_e
            
            sublist = list(set(subdict.values()))
            materials.extend(sublist)
        elif isinstance(geomObj, GeometryInstance):
            get_all_solids(geomObj.GetInstanceGeometry())

# Gọi hàm đệ quy để xử lý GeometryElement
get_all_solids(geometryElement)

OUT = solids, materials
2 Likes