Roof Perimeter , how?

Hello,

how do i use Geometry correctly in PyRevit, how can i replicate what i did in dynamo, look

i want the real perimeter of slanted roofs … who is able to change my script, that it also runs on Python, clean.

import clr

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Structure import *

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import * 

# Access the Revit application and document
app = DocumentManager.Instance.CurrentUIApplication
doc = DocumentManager.Instance.CurrentDBDocument

roofs = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Roofs).WhereElementIsNotElementType().ToElements()


results = [] # list for the output results
# 🎯 get ... what ever
for elem in roofs:
    if not elem.__class__ == [].__class__ : elem = [elem] #ensure that elem is a list, not an individual object, so that we can always prepare for a loop
    

    
    for e in elem: #for every element
        edges = [] #an empty list for the edges to process
        processed = [] #the list of processed edges which we want to keep
        geos = e.get_Geometry(Options()) #the geometry
        for geo in geos: #for every geometry found
            if geo.__class__ == Autodesk.Revit.DB.Solid: #if the geomtry is a solid
                faces = geo.Faces #get the faces
                for face in faces: #for every face
                    if face.FaceNormal.Z > 0.00001: [edges.append(i) for loop in face.EdgeLoops for i in loop] #if it is pointing up, add all of it's edges to the edges list
        pnts = [e.AsCurve().Evaluate(0.5,True) for e in edges] #get all the mid points of the edges
        for i in range(len(edges)): #for every item in the list of edges
            e = edges.pop(0) #remove the edge to process
            p = e.AsCurve().Evaluate(0.5,True) #get the midpoint
            distSum = sum([1 for i in pnts if i.DistanceTo(p) == 0]) #get the count of midpoints which are equal to the midpoint being evaluated
            if distSum == 1: processed.append(e.AsCurve().ToProtoType()) #if the count was 0 the edge isn't shared and is on the perimeter
        results.append(processed) #append the processed edges to our results list
OUT = results #return the results list to the Dynamo environment

KR

Andreas

What the hell is this??? :scream:
The correct way to check types in python is isinstance:

elem = elem if isinstance(elem, list) else [elem]

I don’t get what are you asking: is the script not running in pyrevit? What are the errors?
Have you tried to use the Element.Geometry property?

1 Like

@sanzoghenzo ,

i run well, but only with a .dyn script. I want to use .py.

KR

Andreas

Read again:

Please put some effort to provide us the information needed to help you. You can’t expect from us to (re)write the code for you.

2 Likes

@sanzoghenzo ,

the issue is i can`t import geometry references to to PyRevit!

Can i create this code only using Python?

KR

Andreas

OK, “I can’t import geometry references” is way better than a generic “how can I use Geometry in pyRevit”. I suppose that english not being our native language didn’t help us to understand each other :sweat_smile:

pyRevit already imports many of the needed libraries for you, so the first thing to try is to remove all the clr.AddReference and the imports from that libraries.
You don’t need most of them anyway, I suppose these are boilerplate code added by dynamo.
You can also remove the app variable, since it is not used anywhere, and use the doc object from pyrevit.revit.

2 Likes

@sanzoghenzo ,

true my english is not evaluated by a translator… :wink:
how to skip these Errors?


grafik
KR
Andreas

not tried but
if you imported

from pyrevit import DB in your boiler plate

if type(geo) == DB.Solid:

or if geo == DB.Solid: should do the trick

1 Like

@Jean-Marc ,

thanks that a progress, in dynamo i got lines at least
grafik

Could be this ToProtoType() is Dynamo Issue?

KR
Andreas

yes, remove this
this is a dynamo Geometry thing

1 Like

@Jean-Marc ,

Still remains

finialy i get something

KR

Andreas

As I stated in my first answer, the correct way to check for a type in python is isinstance.

if isinstance(geo, DB.Solid):

the if geo == DB.Solid checks if geo is the type DB.Solid not an instance of that type; this is why the edges list doesn’t get populated.

1 Like