I’m trying to create detail lines based off geometry in a CAD link. I would like it to basically work like pick line tool.
One issue I’m running into is getting different type of geometry and trying to pull useable data out of them to us with the doc.Create.NewDetailCurve method. Is there a simpler way to do this than having different workflows for arc, polylines, and lines?
I’m starting with the PolyLine class, but can’t seem to get curves from it, only coordinates and I don’t think that is enough to make accurate lines.
For arcs it looks like I could get radius, center getendpoints which would probably be enough.
# -*- coding: utf-8 -*-
__title__ = "CADLinesToDetaillines"
__author__ = "AD"
__version__ = "Version: 1.1"
__doc__ = """Version = 1.0
Date = 31.10.2023
_____________________________________________________________________
Description:
Check wether any door does have a tag.
_____________________________________________________________________
How-to:
-> Click on the button
-> Create Detaillines based on CADLayers
-> check the result
_____________________________________________________________________
Last update:
- [11.02.2022] - 1.1 added Revit 2022 Support.
- [21.12.2021] - 1.0 RELEASE
_____________________________________________________________________
To-Do:
- Move functions to lib
_____________________________________________________________________"""
# ╦╔╦╗╔═╗╔═╗╦═╗╔╦╗╔═╗
# ║║║║╠═╝║ ║╠╦╝ ║ ╚═╗
# ╩╩ ╩╩ ╚═╝╩╚═ ╩ ╚═╝ IMPORTS
#====================================================================================================
import os, sys, datetime
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
from Autodesk.Revit.DB.Architecture import *
import time
import traceback
# pyRevit
from pyrevit import forms, revit, script
# .NET Imports
import clr
clr.AddReference('System')
from System.Collections.Generic import List
# List_example = List[ElementId]()
from Autodesk.Revit.DB import *
import System
doc = __revit__.ActiveUIDocument.Document
# ╦ ╦╔═╗╦═╗╦╔═╗╔╗ ╦ ╔═╗╔═╗
# ╚╗╔╝╠═╣╠╦╝║╠═╣╠╩╗║ ║╣ ╚═╗
# ╚╝ ╩ ╩╩╚═╩╩ ╩╚═╝╩═╝╚═╝╚═╝ VARIABLES
#====================================================================================================
time_start = time.time()
def purge_points(coords_xyz):
out_pts = []
for c_xyz in coords_xyz:
if all(p.DistanceTo(c_xyz) > 0.001 for p in out_pts):
out_pts.append(c_xyz)
return out_pts
def get_Curves_from_CAD(importinstance, lst_layerName=[]):
datas = [] # 💥 Initialize an empty list to store data
# 🔹 Create an Options object for importing geometry
opt = Options()
# 🎈 Get the geometry of the import instance
geoSet = importinstance.get_Geometry(opt)
# Iterate through the geometry set
for geo in geoSet:
if isinstance(geo, GeometryInstance):
for g in geo.GetInstanceGeometry():
if isinstance(g, DB.PolyLine):
# 📍 Get the graphics style and name of the current polyline
gStyle = doc.GetElement(g.GraphicsStyleId)
gstyleName = gStyle.GraphicsStyleCategory.Name
# ❗ Check if the layer name is in the specified list
if gstyleName in lst_layerName:
purge_coordinates = purge_points(g.GetCoordinates())
# ▶ Create a DesignScript polycurve from the polyline
ds_polycurve = DS.PolyCurve.ByPoints([p.ToPoint() for p in purge_coordinates], False)
datas.append(ds_polycurve)
return datas
# 1️⃣ import instance and layer name list from the Revit input
importInstance = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_RvtLinks).WhereElementIsNotElementType().ToElements()
lst_layerName = "101_Demo"
# 2️⃣ Call the function and assign the result to the output variable
OUT = get_Curves_from_CAD(importInstance, lst_layerName)
print(OUT)
time_end = time.time()
duration = time_end - time_start
print("\n The code took {} seconds to run.".format(duration))
# ✅ End
def create_detail_lines_from_geometry(geometry_elements):
"""Create detail lines from the geometry of an import instance.
args:
geometry_elements: The geometry elements of the import instance.
return: The created detail lines."""
ids = []
for g in geometry_elements:
if "PolyLine" in str(g):
polyline = DB.PolyLine.Clone(g)
# get coordinates of the polyline
points = polyline.GetCoordinates()
# create detail lines for each segment
for i in range(len(points) - 1):
line = DB.Line.CreateBound(points[i], points[i + 1])
x = doc.Create.NewDetailCurve(doc.ActiveView, line)
elif "Arc" in str(g):
x = doc.Create.NewDetailCurve(doc.ActiveView, DB.Arc.Clone(g))
elif "Ellipse" in str(g):
x = doc.Create.NewDetailCurve(doc.ActiveView, DB.Ellipse.Clone(g))
elif "Line" in str(g) and "PolyLine" not in str(g):
style_id = g.GraphicsStyleId
style_cat = doc.GetElement(style_id).GraphicsStyleCategory
if "DIM" in str(style_cat.Name):
pass
else:
x = doc.Create.NewDetailCurve(doc.ActiveView, DB.Line.Clone(g))
elif "Curve" in str(g):
x = doc.Create.NewDetailCurve(doc.ActiveView, DB.Curve.Clone(g))
elif "Solid" in str(g):
create_filled_region(g)
else:
print("Unknown geometry type:", str(g))
ids.append(x.Id)
return x