├── py ├── Geometry.ReadTag.py ├── Utility.GetData.py ├── Utility.SetData.py ├── Geometry.WriteTag.py ├── List.MaxIndex.py ├── List.MinIndex.py ├── Utility.Announce.py ├── TkMesh.Merge.py ├── FamilyTemplatePaths.CommonPaths.py ├── Wall.IsCurtainWall.py ├── Quads.ByPointMatrix.py ├── Document.CentralPath.py ├── Number.ToString.py ├── Dictionary.ByKeysValues.py ├── Document.ActiveView.py ├── List.MergeByBoolMask.py ├── Application.OpenViews.py ├── RevitLinkType.IsLoaded.py ├── TkMesh.Flatten.py ├── Element.GetParameterUnitValue.py ├── Process.EmptyWorkingSet.py ├── RelativeLevel.AtHeight.py ├── FilePath.Size.py ├── Surface.TrimWithLoopsFix.py ├── Point.ToString.py ├── Surface.OuterPerimeterCurves.py ├── Points.PruneDuplicates+.py ├── Collect.CurrentSelection.py ├── String.ReplaceIllegalChars.py ├── Mesh.BoundingBox.py ├── FilePath.CanWriteTo.py ├── Geometry.GroupByDistance.py ├── Geometry.IndexByDistance.py ├── List.FilterByCategoryName.py ├── Line.ToString.py ├── Collect.View3DTemplates.py ├── Views.Get3dTemplates.py ├── List.RandomiseDivide.py ├── Polygon.2DArea.py ├── List.FilterByClassName.py ├── Points.ConvexHull2D.py ├── Elements.GroupByDistance.py ├── Polygon.ContainmentTest+.py ├── Collect.Revisions.py ├── Polygon.3DArea.py ├── Polygon.IsRectangular.py ├── Element.SetParameterToNone.py ├── Element.Unjoin.py ├── Element.IsCutting.py ├── Document.DeleteElements.py ├── SelectLinkedElement.py ├── FilledRegion.ByCurves+.py ├── Element.IsCut.py ├── SelectInRevit.py ├── Collect.AllTypesOf.py ├── Collect.AllElementsOf.py ├── SelectElementsInOrder.py ├── Element.RemoveVoidCut.py ├── List.ToString.py ├── Document.CopyFromViewToView.py ├── Document.CopyFromLinkInstance.py ├── ElementType.Instances.py ├── Sheet.Views+.py ├── FamilyInstance.ByViewAndPoint.py ├── SelectLinkedElements.py ├── Beams.FixExtents.py ├── ElementType.Duplicate.py ├── SelectFaces+.py ├── FamilyInstance.ByHostAndPoint.py ├── Collect.Sheets.py ├── Collect.Views.py ├── Opening.InFloorByCurves.py ├── TkMesh.Thicken.py ├── FamilyInstance.ByPointsLevelsBatch.py ├── Collect.ElementsInView.py ├── Opening.ShaftByCurves.py ├── Element.MeshGeometry.py ├── SelectLinkedFace.py ├── Mesh.VolumeArea.py ├── DirectShape.Translate.py ├── FamilyInstance.ByFaceAndPoint.py ├── AreaPlan.ByLevelName.py ├── ViewSet.ByViewsName.py ├── Mesh.ToPolySurface.py ├── TextNote.ByPoint.py ├── SelectLinkedElementsInOrder.py ├── DirectShape.Transform.py ├── tkMesh.ByPolygon.py ├── Parse.ErrorReport.py ├── LineLoop.Merge.py ├── Collect.LinkedInstanceElements.py ├── Element.SetLocation.py ├── Collect.ElementSketch.py ├── List.DropDown.py └── Points.MinAreaRectangle.py ├── _misc ├── bg.jpg ├── Logo1.png ├── Spring Nodes Logo.jpg └── package_description.md ├── spring nodes logo.jpg ├── Samples ├── Direct Shape 10k cars.rvt ├── HostedInstance Revit 2015.rvt ├── Shaft.ByCurves Revit 2015.rvt ├── Beams.FixExtents Revit 2015.rvt ├── Direct Shape 10k cars Revit 2016.rvt ├── FloorOpening.ByCurves Revit 2015.rvt ├── Lines.Group&FixCorners Revit 2015.rvt ├── FamilyInsance.ByFacePoints sample R16.rvt ├── FloorOpening.ByCurves expected result.png ├── DirectShape chain sample │ ├── DirectShape filters.png │ ├── DirectShape sample 1.png │ ├── DirectShape schedule.png │ ├── DS Chain_R16 example end.rvt │ └── DS Chain_R16 example start.rvt ├── Adaptive Components sample │ └── AC_flower_field_R16.rfa └── Beams.FixExtents.dyn ├── LICENSE └── _outdated ├── 090716_last 0.82 compatible ├── List.GetOdd.dyf ├── List.DropLast.dyf ├── List.Subpairs.dyf ├── List.GetEven.dyf ├── PlanarFace.FixDomain.dyf ├── Number.ToString.dyf ├── Fn.ElementsOfCategory.dyf ├── Wall.WallType.dyf ├── Active View.dyf ├── NullGetParameter.dyf ├── FamilyInstance.Rotation.dyf ├── Input.Wait.dyf ├── List.ShiftIndices+.dyf ├── Color2Decimal.dyf ├── List.DropFirstLast.dyf ├── NullAllIndicesOf.dyf ├── Decimal2Color.dyf ├── List.EveryOther.dyf ├── Select Edges.dyf ├── Collector.CurrentSelection.dyf ├── Select Linked Element.dyf ├── PolyCurve.Chamfer.dyf ├── File.Size.dyf ├── Select Linked Elements.dyf ├── Select Elements (ordered).dyf ├── Select Linked Face.dyf ├── Line.StraightenZ.dyf ├── Pt2Str.dyf ├── Str2Pt.dyf ├── Ln2Str.dyf ├── Math.AlmostEqual.dyf ├── Str2Ln.dyf ├── Line.StraightenXY.dyf └── Collector.ElementsInView.dyf ├── Excel.ImportFirstWorksheet.dyf └── LevelAbove.dyf /py/Geometry.ReadTag.py: -------------------------------------------------------------------------------- 1 | OUT = IN[0].Tags.LookupTag(IN[1]) -------------------------------------------------------------------------------- /_misc/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/_misc/bg.jpg -------------------------------------------------------------------------------- /_misc/Logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/_misc/Logo1.png -------------------------------------------------------------------------------- /spring nodes logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/spring nodes logo.jpg -------------------------------------------------------------------------------- /_misc/Spring Nodes Logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/_misc/Spring Nodes Logo.jpg -------------------------------------------------------------------------------- /Samples/Direct Shape 10k cars.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Direct Shape 10k cars.rvt -------------------------------------------------------------------------------- /Samples/HostedInstance Revit 2015.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/HostedInstance Revit 2015.rvt -------------------------------------------------------------------------------- /Samples/Shaft.ByCurves Revit 2015.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Shaft.ByCurves Revit 2015.rvt -------------------------------------------------------------------------------- /Samples/Beams.FixExtents Revit 2015.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Beams.FixExtents Revit 2015.rvt -------------------------------------------------------------------------------- /py/Utility.GetData.py: -------------------------------------------------------------------------------- 1 | import System 2 | 3 | dataKey, _ = IN 4 | OUT = System.AppDomain.CurrentDomain.GetData("_Dyn_Wireless_%s" % dataKey) -------------------------------------------------------------------------------- /Samples/Direct Shape 10k cars Revit 2016.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Direct Shape 10k cars Revit 2016.rvt -------------------------------------------------------------------------------- /Samples/FloorOpening.ByCurves Revit 2015.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/FloorOpening.ByCurves Revit 2015.rvt -------------------------------------------------------------------------------- /py/Utility.SetData.py: -------------------------------------------------------------------------------- 1 | import System 2 | 3 | dataKey, data = IN 4 | System.AppDomain.CurrentDomain.SetData("_Dyn_Wireless_%s" % dataKey, data) -------------------------------------------------------------------------------- /Samples/Lines.Group&FixCorners Revit 2015.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Lines.Group&FixCorners Revit 2015.rvt -------------------------------------------------------------------------------- /Samples/FamilyInsance.ByFacePoints sample R16.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/FamilyInsance.ByFacePoints sample R16.rvt -------------------------------------------------------------------------------- /Samples/FloorOpening.ByCurves expected result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/FloorOpening.ByCurves expected result.png -------------------------------------------------------------------------------- /Samples/DirectShape chain sample/DirectShape filters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/DirectShape chain sample/DirectShape filters.png -------------------------------------------------------------------------------- /Samples/DirectShape chain sample/DirectShape sample 1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/DirectShape chain sample/DirectShape sample 1.png -------------------------------------------------------------------------------- /Samples/DirectShape chain sample/DirectShape schedule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/DirectShape chain sample/DirectShape schedule.png -------------------------------------------------------------------------------- /Samples/Adaptive Components sample/AC_flower_field_R16.rfa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/Adaptive Components sample/AC_flower_field_R16.rfa -------------------------------------------------------------------------------- /Samples/DirectShape chain sample/DS Chain_R16 example end.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/DirectShape chain sample/DS Chain_R16 example end.rvt -------------------------------------------------------------------------------- /Samples/DirectShape chain sample/DS Chain_R16 example start.rvt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dimven/SpringNodes/HEAD/Samples/DirectShape chain sample/DS Chain_R16 example start.rvt -------------------------------------------------------------------------------- /py/Geometry.WriteTag.py: -------------------------------------------------------------------------------- 1 | geo, par, val,override = IN 2 | setPreviously = False 3 | try: 4 | tags = geo.Tags 5 | if tags.LookupTag(par) is None or override: 6 | tags.AddTag(par, val) 7 | except ValueError: 8 | setPreviously = True 9 | OUT = IN[0], setPreviously -------------------------------------------------------------------------------- /py/List.MaxIndex.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | return [x] 8 | 9 | data = tolist(IN[0]) 10 | OUT = max(enumerate(data), key=lambda x: x[1]) -------------------------------------------------------------------------------- /py/List.MinIndex.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | return [x] 8 | 9 | data = tolist(IN[0]) 10 | OUT = min(enumerate(data), key=lambda x: x[1]) -------------------------------------------------------------------------------- /py/Utility.Announce.py: -------------------------------------------------------------------------------- 1 | import clr 2 | clr.AddReference('System.Speech') 3 | import System.Speech as sp 4 | import System.Speech.Synthesis as sy 5 | 6 | se = sy.SpeechSynthesizer() 7 | se.SelectVoiceByHints(sy.VoiceGender.Female, sy.VoiceAge.Adult) 8 | se.Rate = 3 9 | se.SpeakAsync(IN[0]) -------------------------------------------------------------------------------- /py/TkMesh.Merge.py: -------------------------------------------------------------------------------- 1 | meshes = IN[0] 2 | vertices, indices = [], [] 3 | lastInd = 0 4 | 5 | for m in meshes: 6 | vertices.extend(m.Vertices() ) 7 | indices.extend([i + lastInd for i in m.VertexIndicesByTri()]) 8 | lastInd += int(m.VertexCount) 9 | 10 | OUT = m.ByVerticesAndIndices(vertices, indices) -------------------------------------------------------------------------------- /py/FamilyTemplatePaths.CommonPaths.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | 6 | app = DocumentManager.Instance.CurrentUIApplication.Application 7 | ver = int(app.VersionNumber) 8 | OUT = app.FamilyTemplatePath 9 | if ver > 2020: 10 | OUT += r"\English" -------------------------------------------------------------------------------- /py/Wall.IsCurtainWall.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | else : return [x] 8 | 9 | walls = UnwrapElement(tolist(IN[0])) 10 | 11 | OUT = [getattr(w, 'CurtainGrid', None) is not None for w in walls] -------------------------------------------------------------------------------- /py/Quads.ByPointMatrix.py: -------------------------------------------------------------------------------- 1 | pts, ccw = IN 2 | OUT = [] 3 | 4 | for i in xrange(len(pts) - 1): 5 | for j in xrange(len(pts[0]) - 1): 6 | if ccw: 7 | OUT.append([pts[i][j], 8 | pts[i][j+1], 9 | pts[i+1][j+1], 10 | pts[i+1][j]]) 11 | else: 12 | OUT.append([pts[i][j], 13 | pts[i+1][j], 14 | pts[i+1][j+1], 15 | pts[i][j+1]]) -------------------------------------------------------------------------------- /py/Document.CentralPath.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | doc = DocumentManager.Instance.CurrentDBDocument 6 | 7 | clr.AddReference('RevitAPI') 8 | from Autodesk.Revit.DB import * 9 | 10 | OUT = None 11 | if doc.IsWorkshared: 12 | cp = doc.GetWorksharingCentralModelPath() 13 | OUT = ModelPathUtils.ConvertModelPathToUserVisiblePath(cp) -------------------------------------------------------------------------------- /py/Number.ToString.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | else : return [x] 8 | 9 | def n2s(n, digits=IN[1]): 10 | if digits is not None: 11 | n = round(n, digits) 12 | n = unicode(n) 13 | if n.endswith('.0'): 14 | n = n[:-2] 15 | return n 16 | 17 | OUT = map(n2s, tolist(IN[0])) -------------------------------------------------------------------------------- /py/Dictionary.ByKeysValues.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(obj1): 6 | if hasattr(obj1,"__iter__"): return obj1 7 | else: return [obj1] 8 | 9 | OUT = [] 10 | 11 | keys = tolist(IN[0]) 12 | elements = tolist(IN[1]) 13 | searchVals = tolist(IN[2]) 14 | 15 | dict1 = dict(zip(keys,elements) ) 16 | OUT = [dict1.get(sv, IN[3]) for sv in searchVals] -------------------------------------------------------------------------------- /py/Document.ActiveView.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | clr.AddReference("RevitNodes") 11 | import Revit 12 | clr.ImportExtensions(Revit.Elements) 13 | 14 | OUT = doc.ActiveView.ToDSType(True) -------------------------------------------------------------------------------- /py/List.MergeByBoolMask.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(obj1): 6 | if hasattr(obj1,'__iter__'): return obj1 7 | else: return [obj1] 8 | 9 | t1 = tolist(IN[0]) 10 | l1 = list(reversed(tolist(IN[1]) ) ) 11 | l2 = list(reversed(tolist(IN[2]) ) ) 12 | 13 | try: OUT = [l1.pop() if i else l2.pop() for i in t1] 14 | except Exception as e: OUT = str(e) -------------------------------------------------------------------------------- /py/Application.OpenViews.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | doc = DocumentManager.Instance.CurrentDBDocument 6 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 7 | 8 | clr.AddReference('RevitNodes') 9 | import Revit 10 | clr.ImportExtensions(Revit.Elements) 11 | 12 | OUT = [doc.GetElement(v.ViewId).ToDSType(1) for v in uidoc.GetOpenUIViews()] -------------------------------------------------------------------------------- /py/RevitLinkType.IsLoaded.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | doc = DocumentManager.Instance.CurrentDBDocument 6 | 7 | clr.AddReference('RevitAPI') 8 | import Autodesk.Revit.DB as DB 9 | 10 | def tolist(x): 11 | if hasattr(x,'__iter__'): return x 12 | return [x] 13 | 14 | links = tolist(UnwrapElement(IN[0])) 15 | OUT = [DB.RevitLinkType.IsLoaded(doc, x.Id) for x in links] -------------------------------------------------------------------------------- /py/TkMesh.Flatten.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2020, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | import Autodesk.DesignScript.Geometry as DS 8 | 9 | meshes, Z = IN 10 | 11 | OUT = [] 12 | for m in meshes: 13 | vertices = [DS.Point.ByCoordinates(p.X, p.Y, Z) for p in m.Vertices()] 14 | indices = m.VertexIndicesByTri() 15 | OUT.append(m.ByVerticesAndIndices(vertices, indices)) -------------------------------------------------------------------------------- /py/Element.GetParameterUnitValue.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitAPI') 4 | import Autodesk.Revit.DB as DB 5 | 6 | elems, parName = UnwrapElement(IN) 7 | OUT = [] 8 | 9 | for e in elems: 10 | par = e.LookupParameter(parName) 11 | if par is None or par.StorageType.ToString() != "Double" or not par.HasValue: 12 | OUT.append("") 13 | continue 14 | val = DB.UnitUtils.ConvertFromInternalUnits(par.AsDouble(), par.DisplayUnitType) 15 | OUT.append(val) -------------------------------------------------------------------------------- /py/Process.EmptyWorkingSet.py: -------------------------------------------------------------------------------- 1 | import System 2 | from System.Diagnostics import Process 3 | 4 | pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) 5 | import sys 6 | sys.path.append('%s\IronPython 2.7\Lib' %pf_path) 7 | import ctypes 8 | 9 | #flush = ctypes.windll.psapi.EmptyWorkingSet #before Windows 7 10 | flush = ctypes.windll.kernel32.K32EmptyWorkingSet 11 | try_flush = flush(Process.GetCurrentProcess().Handle) 12 | OUT = try_flush != 0 -------------------------------------------------------------------------------- /py/RelativeLevel.AtHeight.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from itertools import izip 6 | 7 | heights, elevs, names, belowOnly = IN 8 | BIG_VAL = float('inf') 9 | 10 | def evalHeight(e, belowOnly=belowOnly): 11 | if belowOnly: 12 | if e > z: 13 | return BIG_VAL 14 | return abs(z - e) 15 | 16 | lvl_dict = dict(izip(map(int,elevs), names)) 17 | OUT = [lvl_dict[min(lvl_dict, key=evalHeight)] for z in heights] -------------------------------------------------------------------------------- /_misc/package_description.md: -------------------------------------------------------------------------------- 1 | Spring Nodes focuses on enchanting Dynamo's interaction with Revit and explore any means that can help accelerate BIM work-flows. Your recommendations and ideas on how to improve things are always welcome. For more information, sample files or recommendations, be sure to check out the repository: 2 | https://github.com/dimven/SpringNodes 3 | twitter: @5devene 4 | 5 | Please report any issues on the GitHub repository. 6 | 7 | key: spring api revit design script bad monkey opening -------------------------------------------------------------------------------- /py/FilePath.Size.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from System.IO import FileInfo 6 | 7 | def tolist(x): 8 | if hasattr(x,'__iter__'): return x 9 | else : return [x] 10 | 11 | paths = tolist(IN[0]) 12 | mb = 1048576.0 13 | kb = 1024.0 14 | def getSize(p, mb=mb, kb=kb, kbOnly = IN[1]): 15 | sb = FileInfo(p).Length 16 | if sb < mb or kbOnly: 17 | return '%.3f KB' % (sb / kb) 18 | else: 19 | return '%.3f MB' % (sb / mb) 20 | 21 | OUT = map(getSize, paths) -------------------------------------------------------------------------------- /py/Surface.TrimWithLoopsFix.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | from Autodesk.DesignScript.Geometry import Point 8 | 9 | surf, trims = IN 10 | original = True 11 | for t in trims: 12 | bb = t.BoundingBox 13 | a, b = bb.MinPoint, bb.MaxPoint 14 | c = Point.ByCoordinates((a.X + b.X)/2, (a.Y + b.Y)/2, (a.Z + b.Z)/2) 15 | temp = surf.Trim(t, c)[0] 16 | if original: 17 | original = False 18 | else: 19 | surf.Dispose() 20 | surf = temp 21 | OUT = surf -------------------------------------------------------------------------------- /py/Point.ToString.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | else : return [x] 8 | 9 | def n2s(n, digits): 10 | if digits is not None: 11 | n = round(n, digits) 12 | s1 = str(n) 13 | if s1[-2:] == '.0': 14 | s1 = s1[:-2] 15 | return s1 16 | def p2s(p, sep=IN[1], digits=IN[2]): 17 | x = n2s(p.X, digits) 18 | y = n2s(p.Y, digits) 19 | z = n2s(p.Z, digits) 20 | return ''.join( (x, sep, y, sep, z) ) 21 | 22 | pts = tolist(IN[0]) 23 | 24 | OUT = map(p2s, pts) -------------------------------------------------------------------------------- /py/Surface.OuterPerimeterCurves.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2020, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | import Autodesk.DesignScript.Geometry as DS 8 | 9 | def tolist(x): 10 | if hasattr(x,'__iter__'): return x 11 | return [x] 12 | 13 | surfaces = tolist(IN[0]) 14 | 15 | def dropSurfaceOpenings(srf): 16 | face = srf.Faces[0] 17 | extLoop = [lp for lp in srf.Faces[0].Loops if lp.IsExternal][0] 18 | return [ce.Edge.CurveGeometry for ce in extLoop.CoEdges] 19 | 20 | OUT = map(dropSurfaceOpenings, surfaces) -------------------------------------------------------------------------------- /py/Points.PruneDuplicates+.py: -------------------------------------------------------------------------------- 1 | import clr 2 | from itertools import groupby 3 | from operator import itemgetter 4 | clr.AddReference('ProtoGeometry') 5 | from Autodesk.DesignScript.Geometry import Point 6 | 7 | def p2t(p) : return round(p.X,4), round(p.Y,4), round(p.Z,4) 8 | 9 | pts = map(p2t, IN[0]) 10 | unique_pts = set(pts) 11 | if not IN[1]: 12 | same_z = [(i[:2],i[-1]) for i in unique_pts] 13 | same_z.sort(key = itemgetter(0) ) 14 | unique_pts = [] 15 | for k, g in groupby(same_z, itemgetter(0) ): 16 | coord = list(k) 17 | coord.append(max([i[-1] for i in g]) ) 18 | unique_pts.append(coord) 19 | OUT = [Point.ByCoordinates(*i) for i in unique_pts] -------------------------------------------------------------------------------- /py/Collect.CurrentSelection.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitNodes") 7 | import Revit 8 | clr.ImportExtensions(Revit.Elements) 9 | 10 | clr.AddReference("RevitServices") 11 | import RevitServices 12 | from RevitServices.Persistence import DocumentManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 15 | 16 | def output1(l1): 17 | if len(l1) == 1: return l1[0] 18 | else: return l1 19 | 20 | selid = uidoc.Selection.GetElementIds() 21 | OUT = output1([doc.GetElement(id).ToDSType(True) for id in selid]) -------------------------------------------------------------------------------- /py/String.ReplaceIllegalChars.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from itertools import imap, repeat 6 | import System 7 | badChars = set(System.IO.Path.GetInvalidFileNameChars() ) 8 | 9 | def tolist(x): 10 | if hasattr(x,'__iter__'): return x 11 | else : return [x] 12 | 13 | def fixName(n, rep="", badChars=badChars): 14 | n1 = (c if c not in badChars else rep for c in iter(n) ) 15 | return ''.join(n1) 16 | 17 | names = tolist(IN[0]) 18 | replacement = str(IN[1]) 19 | other = tolist(IN[2]) 20 | 21 | badChars.update(other) 22 | OUT = map(fixName, imap(str, names), repeat(replacement, len(names) ) ) -------------------------------------------------------------------------------- /py/Mesh.BoundingBox.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | from Autodesk.DesignScript.Geometry import BoundingBox, Point, Mesh 8 | 9 | def tolist(x): 10 | if hasattr(x,'__iter__'): return x 11 | else : return [x] 12 | 13 | meshes = tolist(IN[0]) 14 | OUT = [] 15 | 16 | for m in meshes: 17 | if isinstance(m, Mesh): 18 | co = zip(*((v.X, v.Y, v.Z) for v in m.VertexPositions)) 19 | else: 20 | co = zip(*((v.X, v.Y, v.Z) for v in m.Vertices())) 21 | 22 | OUT.append(BoundingBox.ByCorners(Point.ByCoordinates(*map(min, co)), Point.ByCoordinates(*map(max, co)))) -------------------------------------------------------------------------------- /py/FilePath.CanWriteTo.py: -------------------------------------------------------------------------------- 1 | from System.IO import File, Path, Directory, FileOptions 2 | 3 | def tolist(x): 4 | if hasattr(x,'__iter__'): return x 5 | return [x] 6 | 7 | def getDirectory(p): 8 | if File.Exists(p): 9 | return Path.GetDirectoryName(p) 10 | if Directory.Exists: 11 | return p 12 | return 13 | 14 | def canWriteToDir(d): 15 | try: 16 | with File.Create(Path.Combine(d, "__test_file_name__"), 17 | 1, FileOptions.DeleteOnClose) as f: 18 | return True 19 | except: 20 | return False 21 | 22 | paths = tolist(IN[0]) 23 | OUT = [] 24 | for p in paths: 25 | d = getDirectory(p) 26 | if d is not None: 27 | OUT.append(canWriteToDir(d)) 28 | else: 29 | OUT.append(False) -------------------------------------------------------------------------------- /py/Geometry.GroupByDistance.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | #Inspired from the "Group Curves" node by Konrad Sobon 4 | # @arch_laboratory, http://archi-lab.net 5 | 6 | import clr 7 | clr.AddReference('ProtoGeometry') 8 | from Autodesk.DesignScript.Geometry import Geometry 9 | 10 | pts = IN[0] 11 | margin = IN[1] 12 | dist1 = Geometry.DistanceTo 13 | 14 | Groups, Queue = [], [] 15 | while pts: 16 | group = [] 17 | Queue.append(pts.pop() ) 18 | while Queue: 19 | p1 = Queue.pop() 20 | group.append(p1) 21 | for i in xrange(len(pts)-1,-1,-1): 22 | if dist1(p1, pts[i]) <= margin: 23 | Queue.append(pts.pop(i) ) 24 | Groups.append(group) 25 | 26 | OUT = Groups -------------------------------------------------------------------------------- /py/Geometry.IndexByDistance.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from operator import lt, gt 6 | from sys import maxsize 7 | 8 | def tolist(x): 9 | if hasattr(x,'__iter__'): return x 10 | else : return [x] 11 | 12 | geom = tolist(IN[0]) 13 | other = tolist(IN[1]) 14 | isClosest = IN[2] 15 | 16 | _fn = lt if isClosest else gt 17 | _base = maxsize if isClosest else -maxsize 18 | inds, dists = [], [] 19 | OUT = inds, dists 20 | 21 | for g in geom: 22 | d = _base 23 | ind, i = 0, 0 24 | for o in other: 25 | d1 = g.DistanceTo(o) 26 | if _fn(d1, d): 27 | d = d1 28 | ind = i 29 | i += 1 30 | inds.append(ind) 31 | dists.append(d) -------------------------------------------------------------------------------- /py/List.FilterByCategoryName.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from itertools import imap 6 | 7 | def tolist(obj1): 8 | if hasattr(obj1,"__iter__"): return obj1 9 | else: return [obj1] 10 | 11 | elements = tolist(IN[0]) 12 | filter = map(str.lower, imap(str, tolist(IN[1]) ) ) 13 | in1, out1, nulls = [], [], [] 14 | OUT = in1, out1, nulls 15 | 16 | for e in elements: 17 | if e is None: 18 | nulls.append(e) 19 | continue 20 | 21 | c1 = UnwrapElement(e).Category 22 | if c1 is None: 23 | nulls.append(e) 24 | continue 25 | 26 | n1 = c1.Name.lower() 27 | if any(f in n1 for f in filter): 28 | in1.append(e) 29 | else: 30 | out1.append(e) -------------------------------------------------------------------------------- /py/Line.ToString.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(x): 6 | if hasattr(x,'__iter__'): return x 7 | else : return [x] 8 | 9 | def n2s(n, digits): 10 | if digits is not None: 11 | n = round(n, digits) 12 | s1 = str(n) 13 | if s1[-2:] == '.0': 14 | s1 = s1[:-2] 15 | return s1 16 | def p2s(p, sep, digits): 17 | x = n2s(p.X, digits) 18 | y = n2s(p.Y, digits) 19 | z = n2s(p.Z, digits) 20 | return ''.join( (x, sep, y, sep, z) ) 21 | 22 | def l2s(l, sep=IN[1], digits=IN[2]): 23 | a = p2s(l.StartPoint, sep, digits) 24 | b = p2s(l.EndPoint, sep, digits) 25 | return ''.join( (a, sep, b) ) 26 | 27 | lines = tolist(IN[0]) 28 | 29 | OUT = map(l2s, lines) -------------------------------------------------------------------------------- /py/Collect.View3DTemplates.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitAPI') 4 | import Autodesk.Revit.DB as DB 5 | 6 | clr.AddReference('RevitServices') 7 | from RevitServices.Persistence import DocumentManager 8 | doc = DocumentManager.Instance.CurrentDBDocument 9 | 10 | clr.AddReference('RevitNodes') 11 | import Revit 12 | clr.ImportExtensions(Revit.Elements) 13 | 14 | ueWrapper = None 15 | wrappers = clr.GetClrType(Revit.Elements.ElementWrapper).GetMethods() 16 | for w in wrappers: 17 | if w.ToString().startswith("Revit.Elements.UnknownElement"): 18 | ueWrapper = w 19 | break 20 | 21 | fec = DB.FilteredElementCollector(doc).OfClass(DB.View3D) 22 | OUT = [] 23 | for i in fec: 24 | if i.IsTemplate: 25 | OUT.append(ueWrapper.Invoke(None, (i, True) )) -------------------------------------------------------------------------------- /py/Views.Get3dTemplates.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitAPI') 4 | import Autodesk.Revit.DB as DB 5 | 6 | clr.AddReference('RevitServices') 7 | from RevitServices.Persistence import DocumentManager 8 | doc = DocumentManager.Instance.CurrentDBDocument 9 | 10 | clr.AddReference('RevitNodes') 11 | import Revit 12 | clr.ImportExtensions(Revit.Elements) 13 | 14 | ueWrapper = None 15 | wrappers = clr.GetClrType(Revit.Elements.ElementWrapper).GetMethods() 16 | for w in wrappers: 17 | if w.ToString().startswith("Revit.Elements.UnknownElement"): 18 | ueWrapper = w 19 | break 20 | 21 | fec = DB.FilteredElementCollector(doc).OfClass(DB.View3D) 22 | OUT = [] 23 | for i in fec: 24 | if i.IsTemplate: 25 | OUT.append(ueWrapper.Invoke(None, (i, True) )) -------------------------------------------------------------------------------- /py/List.RandomiseDivide.py: -------------------------------------------------------------------------------- 1 | import System 2 | pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) 3 | import sys 4 | sys.path.append('%s\IronPython 2.7\Lib' %pf_path) 5 | import random 6 | 7 | def tolist(x): 8 | if hasattr(x,'__iter__'): return x 9 | else : return [x] 10 | 11 | l1, rat, seed = IN 12 | l1 = tolist(l1) 13 | r = random.Random() 14 | r.seed(seed) 15 | r.shuffle(l1) 16 | len1 = len(l1) 17 | OUT = [] 18 | if len(rat) < 2: 19 | rat.append(1.0 - rat[0]) 20 | if sum(rat) < 1.0: 21 | rat.append(1.0 - sum(rat) ) 22 | start, end = 0, int(round(rat[0] * len1) ) 23 | len2 = len(rat) 24 | for i in xrange(len2): 25 | OUT.append(l1[start : end]) 26 | start = end 27 | j = (i + 1) % len2 28 | end += int(round(rat[j] * len1) ) 29 | if not OUT[-1]: 30 | del(OUT[-1]) -------------------------------------------------------------------------------- /py/Polygon.2DArea.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(obj1): 6 | if hasattr(obj1,'__iter__'): return obj1 7 | else: return [obj1] 8 | 9 | #https://stackoverflow.com/questions/2432428/is-there-any-algorithm-for-calculating-area-of-a-shape-given-co-ordinates-that-d 10 | 11 | polys = tolist(IN[0]) 12 | OUT = [] 13 | for p in polys: 14 | t1 = p.GetType().ToString() 15 | if 'Polygon' in t1 or 'Rectangle' in t1: 16 | pts = p.Points 17 | elif 'PolyCurve' in t1: 18 | pts = [c.StartPoint for c in p.Curves()] 19 | else: 20 | area.append(None) 21 | continue 22 | a = 0 23 | l1 = len(pts) 24 | for i in xrange(l1): 25 | j = i + 1 26 | if j == l1: 27 | j = 0 28 | a += pts[i].X * pts[j].Y 29 | a -= pts[i].Y * pts[j].X 30 | OUT.append(abs(a/2.0) ) -------------------------------------------------------------------------------- /py/List.FilterByClassName.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | from itertools import izip, imap, repeat 7 | 8 | def tolist(obj1): 9 | if hasattr(obj1,"__iter__"): return obj1 10 | else: return [obj1] 11 | 12 | OUT = [] 13 | elements = tolist(IN[0]) 14 | optNames = IN[1] 15 | filter = set(imap(str.lower, imap(str, tolist(IN[2]) ) ) ) 16 | 17 | useOptNames = optNames is not None and len(elements) == len(tolist(optNames) ) 18 | if useOptNames: 19 | optNames = map(str.lower, imap(str, tolist(optNames) ) ) 20 | else: 21 | optNames = repeat("", len(elements) ) 22 | 23 | for e, n in izip(elements, optNames): 24 | if useOptNames: 25 | n1 = n 26 | else: 27 | n1 = object.GetType(e).ToString().lower() if e is not None else "null" 28 | OUT.append(any(f in n1 for f in filter) ) -------------------------------------------------------------------------------- /py/Points.ConvexHull2D.py: -------------------------------------------------------------------------------- 1 | import clr 2 | clr.AddReference('ProtoGeometry') 3 | from Autodesk.DesignScript.Geometry import Point 4 | 5 | from itertools import chain 6 | 7 | pts = sorted( (p.X, p.Y) for p in IN[0]) 8 | elev = IN[1] 9 | 10 | def pCrs(o, a, b): 11 | return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) 12 | 13 | pLen = len(pts) 14 | if pLen < 4 : OUT = pts 15 | else: 16 | lower, upper = [], [] 17 | 18 | for i in xrange(pLen): 19 | j = pLen - 1 - i 20 | while len(lower) >= 2 and pCrs(lower[-2], lower[-1], pts[i]) <= 0.000001: 21 | lower.pop() 22 | lower.append(pts[i]) 23 | while len(upper) >= 2 and pCrs(upper[-2], upper[-1], pts[j]) <= 0.000001: 24 | upper.pop() 25 | upper.append(pts[j]) 26 | 27 | lower.pop() 28 | upper.pop() 29 | 30 | OUT = [Point.ByCoordinates(p[0], p[1], elev) for p in chain(lower, upper) ] -------------------------------------------------------------------------------- /py/Elements.GroupByDistance.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | #Inspired from the "Group Curves" node by Konrad Sobon 5 | # @arch_laboratory, http://archi-lab.net 6 | 7 | import clr 8 | 9 | clr.AddReference('ProtoGeometry') 10 | from Autodesk.DesignScript.Geometry import Geometry 11 | 12 | elem, loc, margin = IN 13 | 14 | pts = zip(elem, loc) 15 | dist1 = Geometry.DistanceTo 16 | Groups, Queue = [], [] 17 | while pts: 18 | group = [] 19 | Queue.append(pts.pop() ) 20 | while Queue: 21 | p1 = Queue.pop() 22 | group.append(p1) 23 | for i in xrange(len(pts)-1,-1,-1): 24 | if dist1(p1[1], pts[i][1]) <= margin: 25 | Queue.append(pts.pop(i) ) 26 | Groups.append(group) 27 | 28 | elem1 = [ [j[0] for j in i] for i in Groups] 29 | pts1 = [ [j[1] for j in i] for i in Groups] 30 | OUT = elem1, pts1 -------------------------------------------------------------------------------- /py/Polygon.ContainmentTest+.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | def tolist(obj1): 6 | if hasattr(obj1,'__iter__'): return obj1 7 | else: return [obj1] 8 | 9 | def containment(poly, pt): 10 | def testCCW(A,B,C): return (B.X - A.X) * (C.Y - A.Y) > (B.Y - A.Y) * (C.X - A.X) 11 | 12 | wn = 0 13 | ln1 = len(poly) 14 | for i in xrange(ln1): 15 | j = (i+1) % ln1 16 | isCCW = testCCW(poly[i], poly[j], pt) 17 | if poly[i].Y <= pt.Y: 18 | if poly[j].Y > pt.Y and isCCW: wn += 1 19 | else: 20 | if poly[j].Y <= pt.Y and not isCCW: wn -= 1 21 | 22 | return wn != 0 23 | 24 | poly = IN[0] 25 | pts = tolist(IN[1]) 26 | t1 = poly.GetType().ToString() 27 | if 'Polygon' in t1 or 'Rectangle' in t1: 28 | poly_pts = poly.Points 29 | else: 30 | poly_pts = [c.StartPoint for c in poly.Curves()] 31 | 32 | OUT = [containment(poly_pts, p) for p in pts] -------------------------------------------------------------------------------- /py/Collect.Revisions.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | 11 | clr.AddReference("RevitAPI") 12 | from Autodesk.Revit.DB import * 13 | 14 | clr.AddReference("RevitNodes") 15 | import Revit 16 | clr.ImportExtensions(Revit.Elements) 17 | 18 | rdat = IN[0].lower() 19 | all_rev, match = [], [] 20 | 21 | fec = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions) 22 | for f in fec: 23 | rev1 = f.ToDSType(True) 24 | all_rev.append(rev1) 25 | par1 = f.get_Parameter(BuiltInParameter.PROJECT_REVISION_REVISION_DATE) 26 | if par1.AsString().lower() == rdat: match.append(rev1) 27 | if len(match) != 0: OUT = match, all_rev 28 | else: OUT = "No revisions found from date %s" %rdat, all_rev -------------------------------------------------------------------------------- /py/Polygon.3DArea.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | from math import sqrt 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | from Autodesk.DesignScript.Geometry import Vector 8 | 9 | def tolist(obj1): 10 | if hasattr(obj1,'__iter__'): return obj1 11 | else: return [obj1] 12 | 13 | polys = tolist(IN[0]) 14 | OUT = [] 15 | for p in polys: 16 | t1 = p.GetType().ToString() 17 | if 'Polygon' in t1 or 'Rectangle' in t1: 18 | pts = p.Points 19 | elif 'PolyCurve' in t1: 20 | pts = [c.StartPoint for c in p.Curves()] 21 | else: 22 | area.append(None) 23 | continue 24 | total = Vector.ByCoordinates(0,0,0) 25 | vec = [p.AsVector() for p in pts] 26 | l1 = len(pts) 27 | for i in xrange(l1): 28 | j = i + 1 29 | if j == l1: 30 | j = 0 31 | prod = vec[i].Cross(vec[j]) 32 | total = total.Add(prod) 33 | OUT.append(abs(sqrt(total.Dot(total) ) / 2.0) ) -------------------------------------------------------------------------------- /py/Polygon.IsRectangular.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | from itertools import imap 6 | 7 | def tolist(obj1): 8 | if hasattr(obj1,'__iter__'): return obj1 9 | else: return [obj1] 10 | 11 | def isSq(pts): 12 | def _dist(a, b): 13 | return round( (a.X - b.X)**2 + (a.Y - b.Y)**2 + (a.Z - b.Z)**2, 5) 14 | isSquare, isRect = False, False 15 | ln1 = len(pts) 16 | if len(pts) != 4: 17 | return isSquare, isRect, isSquare ^ isRect 18 | a, b, c, d = pts 19 | ab, ac, bc, bd = map(_dist, (a,a,b,b), (b,c,c,d) ) 20 | if ac == bd: 21 | isSquare = ab == bc 22 | isRect = True if isSquare else ab == _dist(c, d) 23 | return isSquare, isRect, isSquare ^ isRect 24 | 25 | def getPts(p): 26 | return p.Points if 'Polygon' in p.GetType().ToString() else [c.StartPoint for c in p.Curves()] 27 | 28 | polys = tolist(IN[0]) 29 | OUT = zip(*map(isSq, imap(getPts, polys) ) ) -------------------------------------------------------------------------------- /py/Element.SetParameterToNone.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference('RevitAPI') 8 | from Autodesk.Revit.DB import ElementId 9 | 10 | clr.AddReference('RevitServices') 11 | from RevitServices.Persistence import DocumentManager 12 | from RevitServices.Transactions import TransactionManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | 15 | def tolist(x): 16 | if hasattr(x,'__iter__'): return x 17 | else : return [x] 18 | 19 | inv = ElementId.InvalidElementId 20 | 21 | items = tolist(IN[0]) 22 | param = IN[1] 23 | OUT = [] 24 | 25 | TransactionManager.Instance.EnsureInTransaction(doc) 26 | for i in items: 27 | itm = None 28 | par = i.InternalElement.LookupParameter(param) 29 | if par is not None: 30 | try: 31 | par.Set(inv) 32 | itm = i 33 | except: 34 | pass 35 | OUT.append(itm) 36 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/Element.Unjoin.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('RevitAPI') 7 | from Autodesk.Revit.DB import * 8 | from System.Collections.Generic import * 9 | clr.AddReference("RevitServices") 10 | import RevitServices 11 | from RevitServices.Persistence import DocumentManager 12 | from RevitServices.Transactions import TransactionManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | 15 | def singleton(x): 16 | if hasattr(x,'__iter__'): return x[0] 17 | else : return x 18 | 19 | def tolist(x): 20 | if hasattr(x,'__iter__'): return x 21 | else : return [x] 22 | 23 | floor = UnwrapElement(singleton(IN[0]) ) 24 | beams = UnwrapElement(tolist(IN[1]) ) 25 | 26 | OUT = 0 27 | TransactionManager.Instance.EnsureInTransaction(doc) 28 | for b in beams: 29 | if JoinGeometryUtils.AreElementsJoined(doc, floor, b): 30 | JoinGeometryUtils.UnjoinGeometry(doc, floor, b) 31 | OUT += 1 32 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/Element.IsCutting.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference("RevitServices") 4 | import RevitServices 5 | from RevitServices.Persistence import DocumentManager 6 | doc = DocumentManager.Instance.CurrentDBDocument 7 | 8 | clr.AddReference("RevitAPI") 9 | from Autodesk.Revit.DB import * 10 | 11 | clr.AddReference("RevitNodes") 12 | import Revit 13 | clr.ImportExtensions(Revit.Elements) 14 | 15 | def tolist(obj1): 16 | if hasattr(obj1,"__iter__"): return obj1 17 | else: return [obj1] 18 | 19 | elements = UnwrapElement(tolist(IN[0])) 20 | out1 = [] 21 | cut_el = [] 22 | 23 | cutU = InstanceVoidCutUtils 24 | for i in xrange(len(elements)): 25 | try: 26 | if cutU.IsVoidInstanceCuttingElement(elements[i]): 27 | cut1 = cutU.GetElementsBeingCut(elements[i]) 28 | if cut1.Count != 0: 29 | cut1 = [doc.GetElement(id).ToDSType(True) for id in cut1] 30 | out1.append(True) 31 | cut_el.append(cut1) 32 | else: 33 | out1.append(False) 34 | cut_el.append([]) 35 | except: 36 | out1.append(False) 37 | cut_el.append([]) 38 | 39 | OUT = out1, cut_el -------------------------------------------------------------------------------- /py/Document.DeleteElements.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | 12 | def tolist(obj1): 13 | if hasattr(obj1,"__iter__"): return obj1 14 | else: return [obj1] 15 | 16 | elems = UnwrapElement(tolist(IN[0]) ) 17 | 18 | if IN[1]: 19 | deleted, failed = [], [] 20 | TransactionManager.Instance.EnsureInTransaction(doc) 21 | for e in elems: 22 | id = None 23 | try: 24 | id = e.Id 25 | del_id = doc.Delete(id) 26 | deleted.extend([d.ToString() for d in del_id]) 27 | except: 28 | if id is not None: 29 | failed.append(id.ToString() ) 30 | TransactionManager.Instance.TransactionTaskDone() 31 | s = set(deleted) 32 | failed1 = [x for x in failed if x not in s] 33 | OUT = len(deleted), ';'.join(deleted), ';'.join(failed1) 34 | else: 35 | OUT = "Set confirm to True", "", "" -------------------------------------------------------------------------------- /py/SelectLinkedElement.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitAPIUI") 8 | from Autodesk.Revit.UI import Selection 9 | 10 | clr.AddReference("RevitAPI") 11 | from Autodesk.Revit.DB import RevitLinkInstance, Transform 12 | 13 | clr.AddReference("RevitServices") 14 | import RevitServices 15 | from RevitServices.Persistence import DocumentManager 16 | doc = DocumentManager.Instance.CurrentDBDocument 17 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 18 | 19 | clr.AddReference("RevitNodes") 20 | import Revit 21 | clr.ImportExtensions(Revit.Elements) 22 | clr.ImportExtensions(Revit.GeometryConversion) 23 | 24 | sel1 = uidoc.Selection 25 | ot = Selection.ObjectType.LinkedElement 26 | el_ref = sel1.PickObject(ot, "Pick a linked element.") 27 | linkInst = doc.GetElement(el_ref.ElementId) 28 | linkDoc = linkInst.GetLinkDocument() 29 | linkEl = linkDoc.GetElement(el_ref.LinkedElementId).ToDSType(1) 30 | tf1 = linkInst.GetTotalTransform().ToCoordinateSystem(1) 31 | OUT = linkEl, tf1 -------------------------------------------------------------------------------- /py/FilledRegion.ByCurves+.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference('RevitAPI') 8 | import Autodesk.Revit.DB as DB 9 | 10 | clr.AddReference('RevitServices') 11 | from RevitServices.Persistence import DocumentManager 12 | doc = DocumentManager.Instance.CurrentDBDocument 13 | from RevitServices.Transactions import TransactionManager 14 | 15 | clr.AddReference('RevitNodes') 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | clr.AddReference('System') 21 | from System.Collections.Generic import List 22 | 23 | view, frType, dynLoops = UnwrapElement(IN) 24 | OUT = [] 25 | rvtLoops = List[DB.CurveLoop]() 26 | for crvs in dynLoops: 27 | loop = DB.CurveLoop.Create([c.ToRevitType() for c in crvs]) 28 | rvtLoops.Add(loop) 29 | 30 | TransactionManager.Instance.EnsureInTransaction(doc) 31 | fr = DB.FilledRegion.Create(doc, frType.Id, view.Id, rvtLoops) 32 | OUT.append(fr.ToDSType(False) ) 33 | TransactionManager.Instance.TransactionTaskDone() 34 | -------------------------------------------------------------------------------- /py/Element.IsCut.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference("RevitServices") 4 | import RevitServices 5 | from RevitServices.Persistence import DocumentManager 6 | doc = DocumentManager.Instance.CurrentDBDocument 7 | 8 | clr.AddReference("RevitAPI") 9 | from Autodesk.Revit.DB import * 10 | 11 | clr.AddReference("RevitNodes") 12 | import Revit 13 | clr.ImportExtensions(Revit.Elements) 14 | 15 | def tolist(obj1): 16 | if hasattr(obj1,"__iter__"): return obj1 17 | else: return [obj1] 18 | 19 | elements = UnwrapElement(tolist(IN[0])) 20 | out1 = [] 21 | cutters = [] 22 | 23 | cutU = InstanceVoidCutUtils 24 | for i in xrange(len(elements)): 25 | try: 26 | if cutU.CanBeCutWithVoid(elements[i]): 27 | cut1 = cutU.GetCuttingVoidInstances(elements[i]) 28 | if cut1.Count == 0: 29 | out1.append(False) 30 | cutters.append([]) 31 | else: 32 | out1.append(True) 33 | cut1 = [doc.GetElement(id).ToDSType(True) for id in cut1] 34 | cutters.append(cut1) 35 | else: 36 | out1.append(False) 37 | cutters.append([]) 38 | except: 39 | out1.append(False) 40 | cutters.append([]) 41 | 42 | OUT = out1, cutters -------------------------------------------------------------------------------- /py/SelectInRevit.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | #inspired by Julien Benoit @jbenoit44 4 | #http://aecuandme.wordpress.com/ 5 | 6 | import clr 7 | 8 | clr.AddReference("RevitServices") 9 | import RevitServices 10 | from RevitServices.Persistence import DocumentManager 11 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 12 | 13 | clr.AddReference("RevitNodes") 14 | import Revit 15 | clr.ImportExtensions(Revit.Elements) 16 | 17 | clr.AddReference("RevitAPI") 18 | from Autodesk.Revit.DB import ElementId 19 | clr.AddReference("RevitAPIUI") 20 | from Autodesk.Revit.UI.Selection import * 21 | 22 | clr.AddReference("System") 23 | from System.Collections.Generic import List as cList 24 | 25 | def tolist(obj1): 26 | if hasattr(obj1,"__iter__"): return obj1 27 | else: return [obj1] 28 | 29 | elements = UnwrapElement(tolist(IN[0]) ) 30 | ids1 = [] 31 | for i in xrange(len(elements)): 32 | try:(ids1.append(elements[i].Id)) 33 | except: pass 34 | ids2 = cList[ElementId](ids1) 35 | uidoc.Selection.SetElementIds(ids2) 36 | OUT = "%s elements selected in Revit." %ids2.Count -------------------------------------------------------------------------------- /py/Collect.AllTypesOf.py: -------------------------------------------------------------------------------- 1 | import System 2 | import clr 3 | clr.AddReference('RevitAPI') 4 | import Autodesk.Revit.DB as DB 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | 11 | clr.AddReference('RevitNodes') 12 | import Revit 13 | clr.ImportExtensions(Revit.Elements) 14 | 15 | from System.Collections.Generic import List 16 | 17 | def tolist(x): 18 | if hasattr(x,'__iter__'): return x 19 | else : return [x] 20 | 21 | x = UnwrapElement(tolist(IN[0])) 22 | 23 | fec = DB.FilteredElementCollector(doc).WhereElementIsElementType() 24 | if isinstance(x[0], DB.Category): 25 | catId = List[DB.ElementId](c.Id for c in x) 26 | filter = DB.ElementMulticategoryFilter(catId) 27 | 28 | elif isinstance(x[0], DB.ElementType): 29 | types = List[System.Type](t.GetType() for t in x) 30 | filter = DB.ElementMulticlassFilter(types) 31 | else: 32 | types = List[System.Type](x) 33 | filter = DB.ElementMulticlassFilter(types) 34 | 35 | fec.WherePasses(filter) 36 | OUT = [e.ToDSType(1) for e in fec] 37 | fec.Dispose() 38 | filter.Dispose() -------------------------------------------------------------------------------- /py/Collect.AllElementsOf.py: -------------------------------------------------------------------------------- 1 | import System 2 | import clr 3 | clr.AddReference('RevitAPI') 4 | import Autodesk.Revit.DB as DB 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | 11 | clr.AddReference('RevitNodes') 12 | import Revit 13 | clr.ImportExtensions(Revit.Elements) 14 | 15 | from System.Collections.Generic import List 16 | 17 | def tolist(x): 18 | if hasattr(x,'__iter__'): return x 19 | else : return [x] 20 | 21 | x = UnwrapElement(tolist(IN[0])) 22 | 23 | fec = DB.FilteredElementCollector(doc).WhereElementIsNotElementType() 24 | if isinstance(x[0], DB.Category): 25 | catId = List[DB.ElementId](c.Id for c in x) 26 | filter = DB.ElementMulticategoryFilter(catId) 27 | 28 | elif isinstance(x[0], DB.ElementType): 29 | types = List[System.Type](t.GetType() for t in x) 30 | filter = DB.ElementMulticlassFilter(types) 31 | else: 32 | types = List[System.Type](x) 33 | filter = DB.ElementMulticlassFilter(types) 34 | 35 | fec.WherePasses(filter) 36 | OUT = [e.ToDSType(1) for e in fec] 37 | fec.Dispose() 38 | filter.Dispose() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Dimitar Venkov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /py/SelectElementsInOrder.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | #inspired by Troy Gates https://forums.autodesk.com/t5/revit-api/revit-api-selected-element-set-order/td-p/5597203 5 | 6 | import clr 7 | 8 | clr.AddReference("RevitAPIUI") 9 | from Autodesk.Revit.UI import * 10 | 11 | clr.AddReference("RevitServices") 12 | import RevitServices 13 | from RevitServices.Persistence import DocumentManager 14 | doc = DocumentManager.Instance.CurrentDBDocument 15 | uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 16 | 17 | clr.AddReference("RevitNodes") 18 | import Revit 19 | clr.ImportExtensions(Revit.Elements) 20 | 21 | def output1(l1): 22 | if len(l1) == 1: return l1[0] 23 | else: return l1 24 | 25 | sel1 = uidoc.Selection 26 | obt1 = Selection.ObjectType.Element 27 | msg1 = 'Pick elements in the desired order, hit ESC to stop picking.' 28 | out1 = [] 29 | 30 | flag = True 31 | TaskDialog.Show("Spring Nodes", msg1) 32 | while flag: 33 | try: 34 | el1 = doc.GetElement(sel1.PickObject(obt1, msg1).ElementId) 35 | out1.append(el1.ToDSType(True)) 36 | except : flag = False 37 | 38 | OUT = output1(out1) -------------------------------------------------------------------------------- /py/Element.RemoveVoidCut.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitServices") 8 | import RevitServices 9 | from RevitServices.Persistence import DocumentManager 10 | from RevitServices.Transactions import TransactionManager 11 | doc = DocumentManager.Instance.CurrentDBDocument 12 | 13 | clr.AddReference("RevitAPI") 14 | from Autodesk.Revit.DB import * 15 | 16 | def tolist(obj1): 17 | if hasattr(obj1,"__iter__"): return obj1 18 | else: return [obj1] 19 | 20 | def singleton(x): 21 | if hasattr(x,'__iter__'): return x[0] 22 | else : return x 23 | 24 | elem = UnwrapElement(singleton(IN[0]) ) 25 | cuts = UnwrapElement(tolist(IN[1]) ) 26 | out1 = [] 27 | 28 | cutU = InstanceVoidCutUtils 29 | OUT = 0 30 | if cutU.CanBeCutWithVoid(elem): 31 | TransactionManager.Instance.EnsureInTransaction(doc) 32 | for c in cuts: 33 | if cutU.IsVoidInstanceCuttingElement(c) and \ 34 | cutU.InstanceVoidCutExists(elem, c): 35 | try: 36 | cutU.RemoveInstanceVoidCut(doc,ToBeCut[i],Cuts[j]) 37 | OUT += 1 38 | except: 39 | pass 40 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/List.ToString.py: -------------------------------------------------------------------------------- 1 | import re 2 | from itertools import izip_longest 3 | 4 | import clr 5 | clr.AddReference('DesignScriptBuiltin') 6 | from DesignScript.Builtin import Dictionary as dsDict 7 | 8 | from System import Int64 9 | 10 | def replaceDict(x): 11 | if hasattr(x,'__iter__'): return map(replaceDict, x) 12 | if isinstance(x, dsDict): return dict(zip(x.Keys, replaceDict(x.Values))) 13 | if isinstance(x, Int64): return int(x) 14 | return x 15 | 16 | def tolist(x): 17 | if hasattr(x,'__iter__'): return x 18 | else : return [x] 19 | 20 | rep = {"'" : "\"", 21 | "[" : "[\n", 22 | "]" : "\n]", 23 | "None" : "null", 24 | "True" : "true", 25 | "False" : "false", 26 | ", " : ",\n", 27 | "{" : "{\n", 28 | "}" : "\n}" 29 | } 30 | 31 | if not IN[1]: 32 | del rep["["] 33 | del rep["]"] 34 | del rep[", "] 35 | del rep["{"] 36 | del rep["}"] 37 | 38 | rep = dict((re.escape(k), v) for k, v in rep.iteritems()) 39 | pattern = re.compile("|".join(rep.keys())) 40 | s1 = str(replaceDict(tolist(IN[0]))) 41 | 42 | body, strings = re.split("'[^/']+'", s1), re.findall("'([^/']+)'", s1) 43 | body = (pattern.sub(lambda m: rep[re.escape(m.group(0))], b) for b in body) 44 | OUT = ''.join('%s"%s"' % (b, s) if s else b for b, s in izip_longest(body, strings)) -------------------------------------------------------------------------------- /py/Document.CopyFromViewToView.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | from RevitServices.Transactions import TransactionManager 6 | doc = DocumentManager.Instance.CurrentDBDocument 7 | 8 | clr.AddReference('RevitAPI') 9 | from Autodesk.Revit.DB import * 10 | 11 | from System.Collections.Generic import List 12 | 13 | clr.AddReference('RevitNodes') 14 | import Revit 15 | clr.ImportExtensions(Revit.Elements) 16 | clr.ImportExtensions(Revit.GeometryConversion) 17 | 18 | def singleton(x): 19 | if hasattr(x,'__iter__'): return x[0] 20 | else : return x 21 | 22 | def tolist(x): 23 | if hasattr(x,'__iter__'): return x 24 | else : return [x] 25 | 26 | 27 | source = UnwrapElement(singleton(IN[0]) ) 28 | dest = UnwrapElement(singleton(IN[1]) ) 29 | elements = UnwrapElement(tolist(IN[2]) ) 30 | tf1 = singleton(IN[3]) 31 | 32 | if tf1 is not None: 33 | tf1 = tf1.ToTransform(True) 34 | 35 | eId = List[ElementId](e.Id for e in elements if hasattr(e, "Id") ) 36 | 37 | TransactionManager.Instance.EnsureInTransaction(doc) 38 | copy = ElementTransformUtils.CopyElements(source, eId, dest, tf1, None) 39 | TransactionManager.Instance.TransactionTaskDone() 40 | 41 | OUT = [doc.GetElement(i).ToDSType(False) for i in copy] -------------------------------------------------------------------------------- /py/Document.CopyFromLinkInstance.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | from RevitServices.Transactions import TransactionManager 6 | doc = DocumentManager.Instance.CurrentDBDocument 7 | 8 | clr.AddReference('RevitAPI') 9 | from Autodesk.Revit.DB import * 10 | 11 | from System.Collections.Generic import List 12 | 13 | clr.AddReference('RevitNodes') 14 | import Revit 15 | clr.ImportExtensions(Revit.Elements) 16 | 17 | def singleton(x): 18 | if hasattr(x,'__iter__'): return x[0] 19 | else : return x 20 | 21 | def tolist(x): 22 | if hasattr(x,'__iter__'): return x 23 | else : return [x] 24 | 25 | 26 | linkInst = UnwrapElement(singleton(IN[0]) ) 27 | elements = UnwrapElement(tolist(IN[1]) ) 28 | 29 | linkDoc = linkInst.GetLinkDocument() 30 | tf1 = linkInst.GetTotalTransform() 31 | eId = List[ElementId]() 32 | for e in elements: 33 | try: 34 | id1 = e.Id 35 | except: 36 | continue 37 | eId.Add(id1) 38 | 39 | TransactionManager.Instance.EnsureInTransaction(doc) 40 | copy = ElementTransformUtils.CopyElements(linkDoc, eId, doc, tf1, None) 41 | TransactionManager.Instance.TransactionTaskDone() 42 | OUT = [] 43 | for i in copy: 44 | e = doc.GetElement(i) 45 | if e is not None: 46 | OUT.append(e.ToDSType(False)) -------------------------------------------------------------------------------- /py/ElementType.Instances.py: -------------------------------------------------------------------------------- 1 | import clr 2 | clr.AddReference('RevitAPI') 3 | from Autodesk.Revit.DB import * 4 | 5 | clr.AddReference("RevitServices") 6 | import RevitServices 7 | from RevitServices.Persistence import DocumentManager 8 | doc = DocumentManager.Instance.CurrentDBDocument 9 | 10 | clr.AddReference('RevitNodes') 11 | import Revit 12 | clr.ImportExtensions(Revit.Elements) 13 | 14 | from System.Collections.Generic import List 15 | 16 | def tolist(x): 17 | if hasattr(x,'__iter__'): return x 18 | else : return [x] 19 | 20 | types = UnwrapElement(tolist(IN[0]) ) 21 | catNames = set() 22 | for t in types: 23 | c1 = t.Category 24 | if c1 is not None: 25 | catNames.add(c1.Name) 26 | 27 | catId = List[ElementId]() 28 | allCats = doc.Settings.Categories 29 | for cn in catNames: 30 | if allCats.Contains(cn): 31 | catId.Add(allCats[cn].Id) 32 | 33 | type_storage = dict() 34 | fec = FilteredElementCollector(doc).WhereElementIsNotElementType() 35 | if catId: 36 | fec = fec.WherePasses(ElementMulticategoryFilter(catId) ) 37 | 38 | for e in fec: 39 | id1 = e.GetTypeId().IntegerValue 40 | if id1 in type_storage: 41 | type_storage[id1].append(e.ToDSType(True) ) 42 | else: 43 | type_storage[id1] = [e.ToDSType(True)] 44 | 45 | OUT = [type_storage.get(t.Id.IntegerValue, None) for t in types] -------------------------------------------------------------------------------- /py/Sheet.Views+.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | from RevitServices.Persistence import DocumentManager 8 | doc = DocumentManager.Instance.CurrentDBDocument 9 | 10 | clr.AddReference("RevitNodes") 11 | import Revit 12 | clr.ImportExtensions(Revit.Elements) 13 | 14 | clr.AddReference("RevitAPI") 15 | from Autodesk.Revit.DB import * 16 | 17 | def tolist(obj1): 18 | if hasattr(obj1,"__iter__"): return obj1 19 | else: return [obj1] 20 | 21 | sheets = UnwrapElement(tolist(IN[0])) 22 | sheet_views, sheets_scheds = [], [] 23 | rev_str = "" 24 | sched_dict = dict() 25 | fec1 = FilteredElementCollector(doc).OfClass(ScheduleSheetInstance) 26 | for s in fec1: 27 | if rev_str not in s.Name: 28 | key = s.OwnerViewId.IntegerValue 29 | if key not in sched_dict: 30 | sched_dict[key] = [s] 31 | else: 32 | sched_dict[key].append(s) 33 | 34 | for i in xrange(len(sheets) ): 35 | viewsid = sheets[i].GetAllPlacedViews() 36 | views = [doc.GetElement(v).ToDSType(True) for v in viewsid] 37 | sheet_views.append(views) 38 | s_id = sheets[i].Id.IntegerValue 39 | scheds = sched_dict[s_id] if s_id in sched_dict else [] 40 | sheets_scheds.append(scheds) 41 | OUT = sheet_views, sheets_scheds -------------------------------------------------------------------------------- /py/FamilyInstance.ByViewAndPoint.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | 12 | clr.AddReference("RevitAPI") 13 | import Autodesk 14 | 15 | clr.AddReference("RevitNodes") 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | view = UnwrapElement(tolist(IN[0])) 25 | ftype = UnwrapElement(tolist(IN[1])) 26 | fpts = UnwrapElement(tolist(IN[2])) 27 | persistent = not IN[3] 28 | 29 | OUT = [] 30 | ftp_len = len(ftype) == 1 31 | view_len = len(view) == 1 32 | 33 | TransactionManager.Instance.EnsureInTransaction(doc) 34 | for i in xrange(len(fpts) ): 35 | p = fpts[i].ToXyz(True) 36 | j = 0 if ftp_len else i 37 | k = 0 if view_len else i 38 | try: 39 | if not ftype[j].IsActive : ftype[j].Activate() 40 | nf = doc.Create.NewFamilyInstance(p, ftype[j], view[k]) 41 | OUT.append(nf.ToDSType(persistent) ) 42 | except: 43 | OUT.append(None) 44 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/SelectLinkedElements.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitAPIUI") 8 | from Autodesk.Revit.UI import * 9 | 10 | clr.AddReference("RevitAPI") 11 | from Autodesk.Revit.DB import RevitLinkInstance 12 | 13 | clr.AddReference("RevitServices") 14 | import RevitServices 15 | from RevitServices.Persistence import DocumentManager 16 | doc = DocumentManager.Instance.CurrentDBDocument 17 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 18 | 19 | clr.AddReference("RevitNodes") 20 | import Revit 21 | clr.ImportExtensions(Revit.Elements) 22 | clr.ImportExtensions(Revit.GeometryConversion) 23 | 24 | sel1 = uidoc.Selection 25 | ot1 = Selection.ObjectType.Element 26 | ot2 = Selection.ObjectType.LinkedElement 27 | li_ref = sel1.PickObject(ot1, "Select a link instance first.") 28 | link1 = doc.GetElement(li_ref.ElementId) 29 | if isinstance(link1, RevitLinkInstance): 30 | el_ref = sel1.PickObjects(ot2, "Select the linked elements and press Finish.") 31 | linkDoc = link1.GetLinkDocument() 32 | Lel_id = [r1.LinkedElementId for r1 in el_ref] 33 | tf1 = link1.GetTotalTransform().ToCoordinateSystem(True) 34 | OUT = [linkDoc.GetElement(id1).ToDSType(True) for id1 in Lel_id], tf1 35 | else: 36 | OUT = "Failed to pick a linked instance", None -------------------------------------------------------------------------------- /py/Beams.FixExtents.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2015, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 12 | 13 | clr.AddReference("RevitNodes") 14 | import Revit 15 | clr.ImportExtensions(Revit.Elements) 16 | 17 | clr.AddReference("RevitAPI") 18 | from Autodesk.Revit.DB import ElementId 19 | from Autodesk.Revit.DB.Structure import StructuralFramingUtils 20 | 21 | clr.AddReference("System") 22 | from System.Collections.Generic import List as cList 23 | 24 | def tolist(obj1): 25 | if hasattr(obj1,"__iter__"): 26 | return obj1 27 | else: 28 | return [obj1] 29 | 30 | beams = UnwrapElement(tolist(IN[0])) 31 | 32 | TransactionManager.Instance.EnsureInTransaction(doc) 33 | for b in beams: 34 | try: 35 | StructuralFramingUtils.DisallowJoinAtEnd(b,0) 36 | StructuralFramingUtils.DisallowJoinAtEnd(b,1) 37 | except: 38 | pass 39 | 40 | ids1 = [e.Id for e in beams] 41 | ids2 = cList[ElementId](ids1) 42 | uidoc.Selection.SetElementIds(ids2) 43 | OUT = "%s beams corrected in Revit." %ids2.Count 44 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/ElementType.Duplicate.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('RevitAPI') 7 | from Autodesk.Revit.DB import * 8 | 9 | clr.AddReference('RevitNodes') 10 | import Revit 11 | clr.ImportExtensions(Revit.Elements) 12 | 13 | clr.AddReference('RevitServices') 14 | import RevitServices 15 | from RevitServices.Persistence import DocumentManager 16 | from RevitServices.Transactions import TransactionManager 17 | doc = DocumentManager.Instance.CurrentDBDocument 18 | 19 | def tolist(x): 20 | if hasattr(x,'__iter__'): return x 21 | else : return [x] 22 | 23 | famtypes = UnwrapElement(tolist(IN[0]) ) 24 | newnames = tolist(IN[1]) 25 | 26 | OUT = [] 27 | fec = FilteredElementCollector(doc).OfClass(famtypes[0].GetType() ) 28 | type_dict = dict([(Element.Name.__get__(i), i) for i in fec]) 29 | 30 | ft_len = len(famtypes) == 1 31 | TransactionManager.Instance.EnsureInTransaction(doc) 32 | for i in xrange(len(newnames) ): 33 | j = 0 if ft_len else i 34 | n1 = unicode(newnames[i]) 35 | if n1 in type_dict: 36 | OUT.append(type_dict[n1].ToDSType(False) ) #do I want to wrap this? 37 | else: 38 | try: 39 | nt1 = famtypes[j].Duplicate(n1) 40 | type_dict[n1] = nt1 41 | OUT.append(nt1.ToDSType(True) ) 42 | except: 43 | OUT.append(None) 44 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/SelectFaces+.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitAPIUI") 7 | from Autodesk.Revit.UI import * 8 | 9 | clr.AddReference("RevitServices") 10 | import RevitServices 11 | from RevitServices.Persistence import DocumentManager 12 | doc = DocumentManager.Instance.CurrentDBDocument 13 | uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 14 | 15 | clr.AddReference("RevitNodes") 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | clr.AddReference('RevitAPI') 21 | from Autodesk.Revit.DB import * 22 | 23 | def output1(x): 24 | if len(x) == 1: return x[0] 25 | else : return x 26 | 27 | surfaces, gpoints = [], [] 28 | sel1 = uidoc.Selection 29 | ot1 = Selection.ObjectType.Face 30 | ref_list = sel1.PickObjects(ot1, "Select the faces and press Finish.") 31 | for ref in ref_list: 32 | el1 = doc.GetElement(ref.ElementId) 33 | sf0 = el1.GetGeometryObjectFromReference(ref) 34 | if isinstance(el1, FamilyInstance): 35 | tf1 = el1.GetTransform().ToCoordinateSystem() 36 | sf1 = sf0.Convert(ref, tf1) 37 | else: 38 | sf1 = sf0.ToProtoType(True) 39 | for i in sf1: i.Tags.AddTag("RevitFaceReference", ref) 40 | surfaces.append(output1(sf1) ) 41 | gpoints.append(ref.GlobalPoint.ToPoint(True) ) 42 | 43 | OUT = output1(surfaces), output1(gpoints) -------------------------------------------------------------------------------- /py/FamilyInstance.ByHostAndPoint.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | 12 | clr.AddReference("RevitAPI") 13 | import Autodesk 14 | 15 | clr.AddReference("RevitNodes") 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | host = UnwrapElement(tolist(IN[0])) 25 | ftype = UnwrapElement(tolist(IN[1])) 26 | fpts = UnwrapElement(tolist(IN[2])) 27 | 28 | OUT = [] 29 | strt = Autodesk.Revit.DB.Structure.StructuralType.NonStructural 30 | ftp_len = len(ftype) == 1 31 | hst_len = len(host) == 1 32 | 33 | TransactionManager.Instance.EnsureInTransaction(doc) 34 | for i in xrange(len(fpts) ): 35 | p = fpts[i].ToXyz(True) 36 | j = 0 if ftp_len else i 37 | k = 0 if hst_len else i 38 | try: 39 | if not ftype[j].IsActive : ftype[j].Activate() 40 | level = doc.GetElement(host[k].LevelId) 41 | nf = doc.Create.NewFamilyInstance(p,ftype[j],host[k],level,strt) 42 | OUT.append(nf.ToDSType(False)) 43 | except: 44 | OUT.append(None) 45 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/Collect.Sheets.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | app = DocumentManager.Instance.CurrentUIApplication.Application 11 | isRvt2018 = int(app.VersionNumber) < 2019 12 | 13 | clr.AddReference("RevitAPI") 14 | from Autodesk.Revit.DB import * 15 | 16 | clr.AddReference("RevitNodes") 17 | import Revit 18 | clr.ImportExtensions(Revit.Elements) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | fn = map(str,tolist(IN[0]) ) 25 | NameNumber = IN[1] 26 | result, similar, names = [], [], [] 27 | 28 | fec = FilteredElementCollector(doc).OfClass(View) 29 | ds_type = "DrawingSheet" 30 | for i in fec: 31 | if i.ViewType.ToString() == ds_type: 32 | if NameNumber: n1 = i.ViewName if isRvt2018 else i.Name 33 | else: n1 = i.SheetNumber 34 | names.append(n1) 35 | if any(fn1 == n1 for fn1 in fn): 36 | result.append(i.ToDSType(True)) 37 | elif any(fn1.lower() in n1.lower() for fn1 in fn): 38 | similar.append(i.ToDSType(True)) 39 | if len(result) > 0: 40 | OUT = result,similar 41 | if len(result) == 0 and len(similar) > 0: 42 | OUT = "No exact match found. Check partial below:",similar 43 | if len(result) == 0 and len(similar) == 0: 44 | OUT = "No match found! Check values below:", names -------------------------------------------------------------------------------- /py/Collect.Views.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | app = DocumentManager.Instance.CurrentUIApplication.Application 11 | isRvt2018 = int(app.VersionNumber) < 2019 12 | 13 | clr.AddReference("RevitAPI") 14 | from Autodesk.Revit.DB import * 15 | 16 | clr.AddReference("RevitNodes") 17 | import Revit 18 | clr.ImportExtensions(Revit.Elements) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | fn = map(str,tolist(IN[0]) ) 25 | IncSchedules = IN[1] 26 | result, similar, names = [], [], [] 27 | 28 | if IncSchedules: exclude = ("DrawingSheet") 29 | else: exclude = ("DrawingSheet", "Schedule") 30 | fec = FilteredElementCollector(doc).OfClass(View) 31 | for i in fec: 32 | if not i.IsTemplate and not i.ViewType.ToString() in exclude: 33 | n1 = i.ViewName if isRvt2018 else i.Name 34 | names.append(n1) 35 | if any(fn1 == n1 for fn1 in fn): 36 | result.append(i.ToDSType(True)) 37 | elif any(fn1.lower() in n1.lower() for fn1 in fn): 38 | similar.append(i.ToDSType(True)) 39 | if len(result) > 0: 40 | OUT = result,similar 41 | if len(result) == 0 and len(similar) > 0: 42 | OUT = "No exact match found. Check partial below:", similar 43 | if len(result) == 0 and len(similar) == 0: 44 | OUT = "No match found! Check names below:", names -------------------------------------------------------------------------------- /py/Opening.InFloorByCurves.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitAPI") 7 | from Autodesk.Revit.DB import * 8 | 9 | clr.AddReference("RevitServices") 10 | import RevitServices 11 | from RevitServices.Persistence import DocumentManager 12 | from RevitServices.Transactions import TransactionManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | 15 | clr.AddReference("RevitNodes") 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | flr = UnwrapElement(tolist(IN[0]) ) 25 | hole = UnwrapElement(IN[1]) 26 | 27 | openings = [] 28 | newhl = [] 29 | 30 | if not any(hasattr(h,"__iter__") for h in hole): 31 | hole = [hole] 32 | TransactionManager.Instance.EnsureInTransaction(doc) 33 | for i in xrange(len(hole)): 34 | z = CurveArray() 35 | [z.Append(j.ToRevitType()) for j in hole[i] ] 36 | newhl.append(z) 37 | if len(flr) == 1 : 38 | for i in xrange(len(newhl)): 39 | try: 40 | x = doc.Create.NewOpening(flr[0],newhl[i],True) 41 | openings.append(x.ToDSType(False)) 42 | except: 43 | openings.append(None) 44 | else: 45 | for f, h in zip(flr, newhl): 46 | try: 47 | x = doc.Create.NewOpening(f,h,True) 48 | openings.append(x.ToDSType(False)) 49 | except: 50 | openings.append(None) 51 | TransactionManager.Instance.TransactionTaskDone() 52 | OUT = openings -------------------------------------------------------------------------------- /py/TkMesh.Thicken.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2020, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | import Autodesk.DesignScript.Geometry as DS 8 | 9 | from itertools import izip_longest 10 | def grouper(iterable, n, fillvalue=None): 11 | args = [iter(iterable)] * n 12 | return izip_longest(fillvalue=fillvalue, *args) 13 | 14 | meshes, vecs, dists = IN 15 | 16 | def getMeshPerimeter(mesh): 17 | edge_dict = {} 18 | indices = list(mesh.VertexIndicesByTri()) 19 | tris = grouper(indices, 3) 20 | for t in tris: 21 | a, b, c = t 22 | sides = frozenset((a, b)), frozenset((b, c)), frozenset((c, a)) 23 | for s in sides: 24 | edge_dict[s] = edge_dict.get(s, 0) + 1 25 | 26 | perim = [e for e, n in edge_dict.iteritems() if n == 1] 27 | return perim 28 | 29 | def thickenMesh(mesh, vec, dist): 30 | vertices = list(mesh.Vertices()) 31 | indices = list(mesh.VertexIndicesByTri()) 32 | n = len(vertices) 33 | topMesh = mesh.Translate(vec, dist) 34 | vertices.extend(topMesh.Vertices()) 35 | indices.extend([i + n for i in topMesh.VertexIndicesByTri()]) 36 | 37 | for e in getMeshPerimeter(mesh): 38 | a, b = e 39 | c, d = a + n, b + n 40 | indices.extend([a, b, c]) 41 | indices.extend([c, d, b]) 42 | 43 | return mesh.ByVerticesAndIndices(vertices, indices) 44 | 45 | singleVec = len(vecs) == 1 46 | singleDist = len(dists) == 1 47 | OUT = [] 48 | for i in xrange(len(meshes)): 49 | j = 0 if singleVec else i 50 | k = 0 if singleDist else i 51 | OUT.append(thickenMesh(meshes[i], vecs[j], dists[k])) 52 | -------------------------------------------------------------------------------- /py/FamilyInstance.ByPointsLevelsBatch.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitAPI") 8 | #from Autodesk.Revit.DB import * 9 | from Autodesk.Revit.Creation import FamilyInstanceCreationData 10 | from Autodesk.Revit.DB.Structure import StructuralType 11 | 12 | clr.AddReference("RevitServices") 13 | import RevitServices 14 | from RevitServices.Persistence import DocumentManager 15 | from RevitServices.Transactions import TransactionManager 16 | doc = DocumentManager.Instance.CurrentDBDocument 17 | 18 | clr.AddReference("RevitNodes") 19 | import Revit 20 | clr.ImportExtensions(Revit.Elements) 21 | clr.ImportExtensions(Revit.GeometryConversion) 22 | 23 | clr.AddReference("System") 24 | from System.Collections.Generic import List 25 | 26 | def tolist(x): 27 | if hasattr(x,'__iter__'): return x 28 | else : return [x] 29 | 30 | pts, types, lvls, _track = map(tolist, UnwrapElement(IN)) 31 | trackElems = not _track[0] 32 | types_len = len(types) == 1 33 | lvl_len = len(lvls) == 1 34 | 35 | st1 = StructuralType.NonStructural 36 | FICD1 = List[FamilyInstanceCreationData]() 37 | for i, p in enumerate(pts): 38 | t1 = types[0] if types_len else types[i] 39 | lvl = lvls[0] if lvl_len else lvls[i] 40 | FICD1.Add(FamilyInstanceCreationData(p.ToXyz(True), t1, lvl, st1) ) 41 | 42 | TransactionManager.Instance.EnsureInTransaction(doc) 43 | new_inst = doc.Create.NewFamilyInstances2(FICD1) 44 | TransactionManager.Instance.TransactionTaskDone() 45 | 46 | OUT = [doc.GetElement(i).ToDSType(trackElems) for i in new_inst] -------------------------------------------------------------------------------- /py/Collect.ElementsInView.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitServices") 8 | from RevitServices.Persistence import DocumentManager 9 | doc = DocumentManager.Instance.CurrentDBDocument 10 | 11 | clr.AddReference("RevitAPI") 12 | from Autodesk.Revit.DB import FilteredElementCollector, ElementMulticategoryFilter, ElementId 13 | 14 | clr.AddReference("RevitNodes") 15 | import Revit 16 | clr.ImportExtensions(Revit.Elements) 17 | 18 | from System.Collections.Generic import List 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | views = UnwrapElement(tolist(IN[0]) ) 25 | cat = UnwrapElement(IN[1]) 26 | OUT = [] 27 | 28 | ueWrapper = None 29 | wrappers = clr.GetClrType(Revit.Elements.ElementWrapper).GetMethods() 30 | for w in wrappers: 31 | if w.ToString().startswith("Revit.Elements.UnknownElement"): 32 | ueWrapper = w 33 | break 34 | 35 | if cat is not None: 36 | catId = List[ElementId]() 37 | for c in tolist(cat): 38 | catId.Add(c.Id) 39 | catFil = ElementMulticategoryFilter(catId) 40 | else: 41 | catFil = None 42 | 43 | for v in views: 44 | fec = FilteredElementCollector(doc, v.Id).WhereElementIsNotElementType() 45 | if catFil is not None: 46 | fec = fec.WherePasses(catFil) 47 | viewEl = [] 48 | for e in fec: 49 | try: 50 | viewEl.append(e.ToDSType(True) ) 51 | except: 52 | if ueWrapper: 53 | viewEl.append(ueWrapper.Invoke(None, (e, True) ) ) 54 | OUT.append(viewEl) 55 | fec.Dispose() 56 | if catFil is not None: 57 | catFil.Dispose() -------------------------------------------------------------------------------- /py/Opening.ShaftByCurves.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitAPI") 7 | from Autodesk.Revit.DB import * 8 | 9 | clr.AddReference("RevitServices") 10 | import RevitServices 11 | from RevitServices.Persistence import DocumentManager 12 | from RevitServices.Transactions import TransactionManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | 15 | clr.AddReference("RevitNodes") 16 | import Revit 17 | clr.ImportExtensions(Revit.Elements) 18 | clr.ImportExtensions(Revit.GeometryConversion) 19 | 20 | def tolist(obj1): 21 | if hasattr(obj1,"__iter__"): return obj1 22 | else: return [obj1] 23 | 24 | hole = UnwrapElement(IN[0]) 25 | base_lvl = UnwrapElement(tolist(IN[1])) 26 | top_lvl = UnwrapElement(tolist(IN[2])) 27 | 28 | openings = [] 29 | newhl = [] 30 | 31 | if not any(hasattr(h,"__iter__") for h in hole): 32 | hole = [hole] 33 | TransactionManager.Instance.EnsureInTransaction(doc) 34 | for i in xrange(len(hole)): 35 | z = CurveArray() 36 | [z.Append(j.ToRevitType()) for j in hole[i] ] 37 | newhl.append(z) 38 | if len(base_lvl) == 1 and len(top_lvl) == 1 : 39 | for i in xrange(len(newhl)): 40 | try: 41 | x = doc.Create.NewOpening(base_lvl[0], top_lvl[0], newhl[i]) 42 | openings.append(x.ToDSType(False)) 43 | except: 44 | openings.append(None) 45 | else: 46 | for h, b, t in zip(newhl, base_lvl, top_lvl): 47 | try: 48 | x = doc.Create.NewOpening(b, t, h) 49 | openings.append(x.ToDSType(False)) 50 | except: 51 | openings.append(None) 52 | TransactionManager.Instance.TransactionTaskDone() 53 | 54 | OUT = openings -------------------------------------------------------------------------------- /py/Element.MeshGeometry.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | doc = DocumentManager.Instance.CurrentDBDocument 6 | 7 | clr.AddReference('RevitNodes') 8 | import Revit 9 | clr.ImportExtensions(Revit.GeometryConversion) 10 | 11 | clr.AddReference('RevitAPI') 12 | import Autodesk.Revit.DB as DB 13 | 14 | from System.Collections.Generic import List 15 | 16 | indices = List[int]() 17 | def toTkMesh(m, indices=indices, N=range(3)): 18 | verts = (v.ToPoint(1) for v in m.Vertices) 19 | indices.Clear() 20 | for i in xrange(m.NumTriangles): 21 | for j in N: 22 | indices.Add(m.Triangle[i].Index[j]) 23 | 24 | return mtk.Mesh.ByVerticesAndIndices(verts, indices) 25 | 26 | elems, tessFactor, asTkMesh = UnwrapElement(IN) 27 | OUT = [] 28 | opt1 = DB.Options() 29 | 30 | if asTkMesh: 31 | clr.AddReference('MeshToolkit') 32 | import Autodesk.Dynamo.MeshToolkit as mtk 33 | 34 | def getMeshGeo(rvtGeo, geoList=None, opt1=opt1): 35 | if geoList is None: 36 | geoList = [] 37 | for g in rvtGeo: 38 | if isinstance(g, DB.GeometryInstance): 39 | getMeshGeo(g.GetInstanceGeometry(), geoList) 40 | elif isinstance(g, DB.Mesh): 41 | geoList.append(g) 42 | elif isinstance(g, DB.Face): 43 | geoList.append(g.Triangulate(tessFactor)) 44 | elif isinstance(g, DB.Solid): 45 | vol = getattr(g, 'Volume', 0) 46 | if vol > 0: 47 | geoList.extend(f.Triangulate(tessFactor) for f in g.Faces) 48 | return geoList 49 | 50 | for e in elems: 51 | meshGeo = getMeshGeo(e.Geometry[opt1]) 52 | if asTkMesh: 53 | OUT.append(map(toTkMesh, meshGeo)) 54 | else: 55 | OUT.append([m.Convert() for m in meshGeo]) 56 | opt1.Dispose() -------------------------------------------------------------------------------- /py/SelectLinkedFace.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitAPIUI") 8 | from Autodesk.Revit.UI import * 9 | 10 | clr.AddReference("RevitServices") 11 | import RevitServices 12 | from RevitServices.Persistence import DocumentManager 13 | doc = DocumentManager.Instance.CurrentDBDocument 14 | uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 15 | 16 | clr.AddReference("RevitNodes") 17 | import Revit 18 | clr.ImportExtensions(Revit.Elements) 19 | clr.ImportExtensions(Revit.GeometryConversion) 20 | 21 | clr.AddReference("RevitAPI") 22 | from Autodesk.Revit.DB import RevitLinkInstance, FamilyInstance 23 | 24 | def output1(x): 25 | if len(x) == 1: return x[0] 26 | else : return x 27 | 28 | sel1 = uidoc.Selection 29 | ot1 = Selection.ObjectType.Element 30 | ot2 = Selection.ObjectType.PointOnElement 31 | li_ref = sel1.PickObject(ot1, "Select a link instance first.") 32 | link1 = doc.GetElement(li_ref.ElementId) 33 | if isinstance(link1, RevitLinkInstance): 34 | tf1 = link1.GetTotalTransform() 35 | face_ref = sel1.PickObject(ot2, "Pick a face.") 36 | linkDoc = link1.GetLinkDocument() 37 | el1 = linkDoc.GetElement(face_ref.LinkedElementId) 38 | face_ref2 = face_ref.CreateReferenceInLink() 39 | sf0 = el1.GetGeometryObjectFromReference(face_ref2) 40 | if isinstance(el1, FamilyInstance): 41 | tf1 *= el1.GetTotalTransform() 42 | sf1 = sf0.Convert(face_ref2, tf1.ToCoordinateSystem(True) ) 43 | for s in sf1: 44 | s.Tags.AddTag("RevitFaceReference", face_ref) 45 | OUT = output1(sf1), face_ref.GlobalPoint.ToPoint(True) 46 | else: 47 | OUT = "Failed to pick a link instance.", None -------------------------------------------------------------------------------- /py/Mesh.VolumeArea.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | from math import sqrt 5 | import clr 6 | clr.AddReference('ProtoGeometry') 7 | from Autodesk.DesignScript.Geometry import Vector, Point, Mesh 8 | 9 | from itertools import izip_longest 10 | 11 | def tolist(obj1): 12 | if hasattr(obj1,'__iter__'): return obj1 13 | return [obj1] 14 | 15 | def grouper(iterable, n, fillvalue=None): 16 | "Collect data into fixed-length chunks or blocks" 17 | # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx 18 | args = [iter(iterable)] * n 19 | return izip_longest(fillvalue=fillvalue, *args) 20 | 21 | def tkMeshData(m): 22 | vol, area = 0, 0 23 | tris = grouper(m.TrianglesAsNineNumbers, 9) 24 | for t in tris: 25 | a, b, c = (Vector.ByCoordinates(*c) for c in grouper(t, 3)) 26 | e1 = b - a 27 | e2 = c - a 28 | N = e1.Cross(e2) 29 | area += 0.5 * N.Length 30 | f = a.X + b.X + c.X 31 | vol += N.X * f 32 | for i in a, b, c, e1, e2, N: 33 | i.Dispose() 34 | return vol / 6.0, area 35 | 36 | def meshData(m): 37 | vol, area = 0, 0 38 | vp = m.VertexPositions 39 | ptslist = ([vp[i.A], vp[i.B], vp[i.C]] for i in m.FaceIndices) 40 | for pts in ptslist: 41 | a, b, c = map(Point.AsVector, pts) 42 | e1 = b - a 43 | e2 = c - a 44 | N = e1.Cross(e2) 45 | area += 0.5 * N.Length 46 | f = a.X + b.X + c.X 47 | vol += N.X * f 48 | for i in a, b, c, e1, e2, N: 49 | i.Dispose() 50 | return vol / 6.0, area 51 | 52 | meshes = tolist(IN[0]) 53 | volumes, areas = [], [] 54 | OUT = volumes, areas 55 | for m in meshes: 56 | f = meshData if isinstance(m, Mesh) else tkMeshData 57 | v, a = f(m) 58 | volumes.append(v) 59 | areas.append(a) -------------------------------------------------------------------------------- /py/DirectShape.Translate.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | app = DocumentManager.Instance.CurrentUIApplication.Application 12 | isRvt2017 = int(app.VersionNumber) > 2016 13 | 14 | clr.AddReference("RevitNodes") 15 | import Revit 16 | clr.ImportExtensions(Revit.Elements) 17 | clr.ImportExtensions(Revit.GeometryConversion) 18 | 19 | clr.AddReference("RevitAPI") 20 | from Autodesk.Revit.DB import * 21 | 22 | def tolist(obj1): 23 | if hasattr(obj1,"__iter__"): return obj1 24 | else: return [obj1] 25 | 26 | dsTyped, vecs = UnwrapElement(IN[0]), tolist(IN[1]) 27 | 28 | transforms = [] 29 | for i in xrange(len(vecs)): 30 | try: transforms.append(Transform.CreateTranslation(vecs[i].ToXyz(True))) 31 | except: pass 32 | cat = dsTyped.Category 33 | TypeId = dsTyped.GetTypeId() 34 | Lib_TypeId = TypeId.ToString() 35 | dsLib = DirectShapeLibrary.GetDirectShapeLibrary(doc) 36 | if not dsLib.ContainsType(Lib_TypeId): dsLib.AddDefinitionType(Lib_TypeId, TypeId) 37 | 38 | def CopyDS(transf): 39 | try: 40 | if isRvt2017: 41 | ds1 = DirectShape.CreateElementInstance(doc, TypeId, cat.Id, Lib_TypeId, transf) 42 | else: 43 | ds1 = DirectShape.CreateElementInstance(doc, TypeId, cat.Id, Lib_TypeId, transf, "Dynamo","spring nodes") 44 | ds1.SetTypeId(TypeId) 45 | return ds1.ToDSType(False) 46 | except: return None 47 | 48 | TransactionManager.Instance.EnsureInTransaction(doc) 49 | OUT = map(CopyDS, transforms) 50 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/FamilyInstance.ByFaceAndPoint.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference('ProtoGeometry') 8 | from Autodesk.DesignScript.Geometry import * 9 | 10 | clr.AddReference('RevitServices') 11 | import RevitServices 12 | from RevitServices.Persistence import DocumentManager 13 | from RevitServices.Transactions import TransactionManager 14 | doc = DocumentManager.Instance.CurrentDBDocument 15 | 16 | clr.AddReference('RevitNodes') 17 | import Revit 18 | clr.ImportExtensions(Revit.Elements) 19 | clr.ImportExtensions(Revit.GeometryConversion) 20 | 21 | clr.AddReference('RevitAPI') 22 | import Autodesk.Revit.DB as DB 23 | 24 | def tolist(x): 25 | if hasattr(x,'__iter__'): return x 26 | return [x] 27 | 28 | def first(x): 29 | if hasattr(x,'__iter__'): return x[0] 30 | return x 31 | 32 | host = first(IN[0]) 33 | ftype = UnwrapElement(tolist(IN[1])) 34 | pts = tolist(IN[2]) 35 | 36 | OUT = [] 37 | ftp_len = len(ftype) == 1 38 | ref1 = host.Tags.LookupTag("RevitFaceReference") 39 | 40 | TransactionManager.Instance.EnsureInTransaction(doc) 41 | for i, p in enumerate(pts): 42 | j = 0 if ftp_len else i 43 | if not ftype[j].IsActive: 44 | ftype[j].Activate() 45 | faceNor = host.NormalAtPoint(p) 46 | up = Vector.ZAxis() 47 | if abs(faceNor.Dot(up)) > 0.9999: #is horizontal 48 | #uv1 = host.UVParameterAtPoint(p) 49 | #dir1 = host.TangentAtUParameter(uv1.U,uv1.V).ToXyz() 50 | dir1 = DB.XYZ.BasisX 51 | else: 52 | dir1 = faceNor.Cross(up).ToXyz() 53 | try: 54 | inst1 = doc.Create.NewFamilyInstance(ref1, p.ToXyz(1), dir1, ftype[j]) 55 | OUT.append(inst1.ToDSType(False) ) 56 | except Exception as ex: OUT.append(str(ex)) 57 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/AreaPlan.ByLevelName.py: -------------------------------------------------------------------------------- 1 | import clr 2 | 3 | clr.AddReference('RevitServices') 4 | from RevitServices.Persistence import DocumentManager 5 | from RevitServices.Transactions import TransactionManager 6 | doc = DocumentManager.Instance.CurrentDBDocument 7 | 8 | clr.AddReference('RevitNodes') 9 | import Revit 10 | clr.ImportExtensions(Revit.Elements) 11 | 12 | clr.AddReference('RevitAPI') 13 | from Autodesk.Revit.DB import * 14 | 15 | def tolist(obj1): 16 | if hasattr(obj1,'__iter__') : return obj1 17 | else : return [obj1] 18 | 19 | def first(obj1): 20 | if hasattr(obj1,'__iter__'): return obj1[0] 21 | else: return obj1 22 | 23 | 24 | lvls = UnwrapElement(tolist(IN[0]) ) 25 | names = tolist(IN[1]) 26 | plan_type = str(first(IN[2]) ) 27 | 28 | #fail_str = 'view with same name exists' 29 | vt1 = None # fetch the area plan type 30 | fec1 = FilteredElementCollector(doc).OfClass(ViewFamilyType) 31 | for f in fec1: 32 | if Element.Name.__get__(f) == plan_type : 33 | vt1 = f.Id 34 | break 35 | 36 | fec2 = FilteredElementCollector(doc).OfClass(View) #get existing area plans 37 | plan_names = [f.Name for f in fec2 if f.GetTypeId().Equals(vt1)] 38 | 39 | as1 = None #get the scheme 40 | fec3 = FilteredElementCollector(doc).OfClass(AreaScheme) 41 | for f in fec3: 42 | if f.Name == plan_type : 43 | as1 = f.Id 44 | break 45 | 46 | if as1 != None: 47 | OUT = [] 48 | TransactionManager.Instance.EnsureInTransaction(doc) 49 | for l, n in zip(lvls, names): 50 | if n not in plan_names: 51 | v1 = ViewPlan.CreateAreaPlan(doc, as1, l.Id) 52 | v1.Name = n 53 | OUT.append(v1.ToDSType(False) ) 54 | else : OUT.append(None) #could use fail_str but filtering nulls is easier 55 | TransactionManager.Instance.TransactionTaskDone() 56 | 57 | else : OUT = 'Area scheme with that name not found.' -------------------------------------------------------------------------------- /py/ViewSet.ByViewsName.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2015, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | #code inspired by Harry Mattison 4 | #https://boostyourbim.wordpress.com 5 | 6 | import clr 7 | 8 | clr.AddReference("RevitServices") 9 | import RevitServices 10 | from RevitServices.Persistence import DocumentManager 11 | from RevitServices.Transactions import TransactionManager 12 | doc = DocumentManager.Instance.CurrentDBDocument 13 | 14 | clr.AddReference("RevitAPI") 15 | from Autodesk.Revit.DB import * 16 | 17 | def tolist(obj1): 18 | if hasattr(obj1,"__iter__") : return obj1 19 | else : return [obj1] 20 | 21 | def first(obj1): 22 | if hasattr(obj1,'__iter__') : return obj1[0] 23 | else : return obj1 24 | 25 | views = UnwrapElement(tolist(IN[0])) 26 | name1 = str(first(IN[1]) ) 27 | overwrite = IN[2] 28 | vs_exists = None 29 | 30 | fec = FilteredElementCollector(doc).OfClass(ViewSheetSet).GetElementIterator() 31 | fec.Reset() 32 | for f in fec: 33 | if f.Name == name1: 34 | vs_exists = f 35 | break 36 | if vs_exists != None and overwrite: 37 | TransactionManager.Instance.EnsureInTransaction(doc) 38 | doc.Delete(vs_exists.Id) 39 | TransactionManager.Instance.TransactionTaskDone() 40 | vs_exists = None 41 | elif vs_exists != None and not overwrite: 42 | OUT = "There's a ViewSet with the same name.\nSet Overwrite to true to continue." 43 | if vs_exists == None: 44 | vs1 = ViewSet() 45 | for v in views: (vs1.Insert(v)) 46 | printMan = doc.PrintManager 47 | printMan.PrintRange = PrintRange.Select 48 | viewSS = printMan.ViewSheetSetting 49 | try: 50 | TransactionManager.Instance.EnsureInTransaction(doc) 51 | viewSS.CurrentViewSheetSet.Views = vs1 52 | viewSS.SaveAs(name1) 53 | TransactionManager.Instance.TransactionTaskDone() 54 | OUT = "ViewSet created with %s views inside." %len(views) 55 | except: 56 | OUT = "The ViewSet could not be created" -------------------------------------------------------------------------------- /py/Mesh.ToPolySurface.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | from System.Threading import Thread, ThreadStart 7 | 8 | clr.AddReference('ProtoGeometry') 9 | from Autodesk.DesignScript.Geometry import PolySurface, Surface 10 | 11 | meshes, mergeAll, NUMTHREADS = IN 12 | CHOPLIMIT = 10 13 | 14 | def tolist(obj1): 15 | if hasattr(obj1,'__iter__'): return obj1 16 | return [obj1] 17 | 18 | def chop(l1, n): 19 | return [l1[x:x+n] for x in xrange(0, len(l1), n)] 20 | 21 | def ps_generator(ptslist, 22 | f_ps1=PolySurface.ByJoinedSurfaces, 23 | f_sf1=Surface.ByPerimeterPoints): 24 | 25 | sflist = map(f_sf1, ptslist) 26 | while len(sflist) > CHOPLIMIT: 27 | new_sflist = map(f_ps1, chop(sflist, CHOPLIMIT)) 28 | for s in sflist: s.Dispose() 29 | sflist = new_sflist 30 | return sflist 31 | 32 | def mesh2ps(topo): 33 | vp = topo.VertexPositions 34 | ptslist = [[vp[i.A], vp[i.B], vp[i.C]] for i in topo.FaceIndices] 35 | len1 = len(ptslist) / NUMTHREADS + 1 36 | 37 | if len(ptslist) > NUMTHREADS * 3 and NUMTHREADS > 1: 38 | ptslist = chop(ptslist, len1) 39 | 40 | class Worker(object): 41 | __slots__ = 'fn', 'args', 'result' 42 | def __init__(self, fn, args): 43 | self.fn = fn 44 | self.args = args 45 | self.result = None 46 | def __call__(self): 47 | self.result = self.fn(*self.args) 48 | 49 | workers, tasks = [], [] 50 | for p in ptslist: 51 | w = Worker(ps_generator, (p,)) 52 | t = Thread(ThreadStart(w)) 53 | workers.append(w) 54 | tasks.append(t) 55 | t.Start() 56 | 57 | for t in tasks: t.Join() 58 | return PolySurface.ByJoinedSurfaces(i for w in workers for i in w.result) 59 | else: 60 | return PolySurface.ByJoinedSurfaces(ps_generator(ptslist)) 61 | 62 | OUT = map(mesh2ps, tolist(meshes)) 63 | if mergeAll: OUT = PolySurface.ByJoinedSurfaces(OUT) -------------------------------------------------------------------------------- /py/TextNote.ByPoint.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2018, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitServices") 8 | import RevitServices 9 | from RevitServices.Persistence import DocumentManager 10 | from RevitServices.Transactions import TransactionManager 11 | doc = DocumentManager.Instance.CurrentDBDocument 12 | 13 | clr.AddReference('RevitAPI') 14 | import Autodesk.Revit.DB as DB 15 | 16 | clr.AddReference("RevitNodes") 17 | import Revit 18 | clr.ImportExtensions(Revit.Elements) 19 | clr.ImportExtensions(Revit.GeometryConversion) 20 | 21 | def tolist(x): 22 | if hasattr(x,'__iter__'): return x 23 | else : return [x] 24 | 25 | view = UnwrapElement(tolist(IN[0])) 26 | pts = tolist(IN[1]) 27 | content = map(str, tolist(IN[2])) 28 | txtType = UnwrapElement(tolist(IN[3])) 29 | _txtAlign = str(IN[4]) 30 | persistent = not IN[5] 31 | 32 | txtAlign_dict = {"Center" : DB.HorizontalTextAlignment.Center, 33 | "Left" : DB.HorizontalTextAlignment.Left, 34 | "Right" : DB.HorizontalTextAlignment.Right} 35 | txtAlign = txtAlign_dict.get(_txtAlign, None) 36 | if txtAlign is None: 37 | txtAlign = txtAlign_dict["Center"] 38 | 39 | if txtType[0] is None: 40 | txtType[0] = doc.GetElement(doc.GetDefaultElementTypeId(DB.ElementTypeGroup.TextNoteType)) 41 | 42 | OUT = [] 43 | txtType_len = len(txtType) == 1 44 | view_len = len(view) == 1 45 | content_len = len(content) == 1 46 | 47 | TransactionManager.Instance.EnsureInTransaction(doc) 48 | for i in xrange(len(pts) ): 49 | p = pts[i].ToXyz(True) 50 | j = 0 if txtType_len else i 51 | k = 0 if view_len else i 52 | m = 0 if content_len else i 53 | try: 54 | tn = DB.TextNote.Create(doc, view[k].Id, p, content[m], txtType[j].Id) 55 | tn.HorizontalAlignment = txtAlign 56 | OUT.append(tn.ToDSType(persistent) ) 57 | except: 58 | OUT.append(None) 59 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/SelectLinkedElementsInOrder.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2017, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | #inspired by Troy Gates https://forums.autodesk.com/t5/revit-api/revit-api-selected-element-set-order/td-p/5597203 6 | 7 | import clr 8 | 9 | clr.AddReference("RevitAPIUI") 10 | from Autodesk.Revit.UI import * 11 | 12 | clr.AddReference("RevitAPI") 13 | from Autodesk.Revit.DB import RevitLinkInstance 14 | 15 | clr.AddReference("RevitServices") 16 | import RevitServices 17 | from RevitServices.Persistence import DocumentManager 18 | doc = DocumentManager.Instance.CurrentDBDocument 19 | uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument 20 | 21 | clr.AddReference("RevitNodes") 22 | import Revit 23 | clr.ImportExtensions(Revit.Elements) 24 | clr.ImportExtensions(Revit.GeometryConversion) 25 | 26 | sel1 = uidoc.Selection 27 | obt1 = Selection.ObjectType.Element 28 | obt2 = Selection.ObjectType.LinkedElement 29 | picked = [] 30 | 31 | if IN[0]: 32 | TaskDialog.Show("Spring Nodes", "First select a link instance. Then pick elements from that instance in the desired order. Hit ESC to stop picking.") 33 | 34 | msg1 = 'Pick elements in the desired order, hit ESC to stop picking.' 35 | 36 | li_ref = sel1.PickObject(obt1, "Select a link instance first.") 37 | link1 = doc.GetElement(li_ref.ElementId) 38 | if isinstance(link1, RevitLinkInstance): 39 | linkDoc = link1.GetLinkDocument() 40 | 41 | flag = True 42 | while flag: 43 | try: 44 | el1 = sel1.PickObject(obt2, msg1).LinkedElementId 45 | if el1.IntegerValue != -1: 46 | picked.append(el1) 47 | except : flag = False 48 | 49 | elems = [] 50 | for p in picked: 51 | el1 = linkDoc.GetElement(p) 52 | if el1 is not None: 53 | elems.append(el1.ToDSType(True) ) 54 | 55 | tf1 = link1.GetTotalTransform().ToCoordinateSystem(True) 56 | OUT = elems, tf1 57 | 58 | else: 59 | OUT = 'Failed to pick a link instance', None -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.GetOdd.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.DropLast.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.Subpairs.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.GetEven.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /py/DirectShape.Transform.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | app = DocumentManager.Instance.CurrentUIApplication.Application 12 | isRvt2017 = int(app.VersionNumber) > 2016 13 | 14 | clr.AddReference("RevitNodes") 15 | import Revit 16 | clr.ImportExtensions(Revit.Elements) 17 | clr.ImportExtensions(Revit.GeometryConversion) 18 | 19 | clr.AddReference("RevitAPI") 20 | from Autodesk.Revit.DB import * 21 | 22 | def tolist(obj1): 23 | if hasattr(obj1,"__iter__"): return obj1 24 | else: return [obj1] 25 | 26 | units = doc.GetUnits().GetFormatOptions(UnitType.UT_Length).DisplayUnits 27 | factor = 1 / UnitUtils.ConvertToInternalUnits(1,units) 28 | 29 | def cs2Trans(cs, scale = factor): 30 | tf1 = Transform(Transform.Identity) 31 | tf1.Origin = cs.Origin.ToXyz(True) 32 | tf1.Basis[0] = cs.XAxis.ToXyz(True) 33 | tf1.Basis[1] = cs.YAxis.ToXyz(True) 34 | tf1.Basis[2] = cs.ZAxis.ToXyz(True) 35 | return tf1.ScaleBasis(scale) 36 | 37 | dsTyped = UnwrapElement(IN[0]) 38 | cs1 = tolist(IN[1]) 39 | 40 | transforms = map(cs2Trans, cs1) 41 | cat = dsTyped.Category 42 | TypeId = dsTyped.GetTypeId() 43 | Lib_TypeId = TypeId.ToString() 44 | dsLib = DirectShapeLibrary.GetDirectShapeLibrary(doc) 45 | if not dsLib.ContainsType(Lib_TypeId): dsLib.AddDefinitionType(Lib_TypeId, TypeId) 46 | 47 | def TransformDS(transf): 48 | try: 49 | if isRvt2017: 50 | ds1 = DirectShape.CreateElementInstance(doc, TypeId, cat.Id, Lib_TypeId, transf) 51 | else: 52 | ds1 = DirectShape.CreateElementInstance(doc, TypeId, cat.Id, Lib_TypeId, transf, "Dynamo","spring nodes") 53 | ds1.SetTypeId(TypeId) 54 | return ds1.ToDSType(False) 55 | except: return None 56 | 57 | TransactionManager.Instance.EnsureInTransaction(doc) 58 | OUT = map(TransformDS, transforms) 59 | TransactionManager.Instance.TransactionTaskDone() -------------------------------------------------------------------------------- /py/tkMesh.ByPolygon.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2020, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | clr.AddReference('MeshToolkit') 7 | import Autodesk.Dynamo.MeshToolkit.Mesh as tkMesh 8 | 9 | def tolist(x): 10 | if hasattr(x,'__iter__'): return x 11 | return [x] 12 | 13 | def orientation(v): 14 | area = 0.0 15 | for i in range(len(v)): 16 | area += v[i-1].X*v[i].Y - v[i-1].Y*v[i].X 17 | return area < 0.0 # if true, it is clockwise 18 | 19 | def determinant(p1, p2, p3): 20 | determ = (p2.X - p1.X) * (p3.Y - p1.Y) - (p3.X - p1.X) * (p2.Y - p1.Y) 21 | return determ >= 0 22 | 23 | def no_interior(p1, p2, p3, v, poly_or): 24 | for ip in v: 25 | p = ip[1] 26 | if p.IsAlmostEqualTo(p1) or p.IsAlmostEqualTo(p2) or p.IsAlmostEqualTo(p3): 27 | continue # Don't bother checking against yourself 28 | if determinant(p1, p2, p) == poly_or or \ 29 | determinant(p3, p1, p) == poly_or or \ 30 | determinant(p2, p3, p) == poly_or: 31 | continue # This point is outside 32 | return False # The point is inside 33 | return True # No points inside this triangle 34 | 35 | def draw_poly(poly): 36 | t1 = poly.GetType().ToString() 37 | if 'Polygon' in t1 or 'Rectangle' in t1: 38 | pts = poly.Points 39 | else: 40 | pts = [c.StartPoint for c in poly.Curves()] 41 | indices = [] 42 | poly_orientation = orientation(pts) 43 | v = list(enumerate(pts)) 44 | while len(v) > 3: 45 | for cur in range(len(v)): 46 | prev = cur - 1 47 | next = (cur + 1) % len(v) 48 | if determinant(v[cur][1], v[prev][1], v[next][1]) == poly_orientation and \ 49 | no_interior(v[prev][1], v[cur][1], v[next][1], v, poly_orientation): 50 | indices.extend((v[prev][0], v[cur][0], v[next][0])) 51 | del(v[cur]) 52 | break 53 | else: 54 | raise('Error: Didn\'t find a triangle.\n') 55 | 56 | # Output the final triangle 57 | indices.extend([i[0] for i in v]) 58 | return tkMesh.ByVerticesAndIndices(pts, indices) 59 | 60 | OUT = map(draw_poly, tolist(IN[0])) -------------------------------------------------------------------------------- /py/Parse.ErrorReport.py: -------------------------------------------------------------------------------- 1 | import clr 2 | import System 3 | pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86) 4 | import sys 5 | sys.path.append("%s\IronPython 2.7\Lib" %pf_path) 6 | 7 | from sgmllib import SGMLParser 8 | from collections import Counter 9 | 10 | class ReportParser(SGMLParser): 11 | def __init__(self, verbose=0): 12 | SGMLParser.__init__(self, verbose) 13 | self.data1 = [] 14 | self.temp_data = [] 15 | def handle_data(self, data): 16 | if data != "\n" and data not in known_errors: 17 | self.temp_data.append(data) 18 | def unknown_starttag(self, tag, attrs): 19 | if tag == "tr": 20 | self.data1.append(self.temp_data) 21 | self.temp_data = [] 22 | 23 | def getElement(i): 24 | try: return doc.GetElement(ElementId(i)).ToDSType(1) 25 | except: return i 26 | 27 | report1, fetch_elements = IN 28 | 29 | if fetch_elements: #imports moved here to be able to process externally 30 | clr.AddReference("RevitServices") 31 | from RevitServices.Persistence import DocumentManager 32 | doc = DocumentManager.Instance.CurrentDBDocument 33 | clr.AddReference("RevitAPI") 34 | from Autodesk.Revit.DB import ElementId 35 | clr.AddReference('RevitNodes') 36 | import Revit 37 | clr.ImportExtensions(Revit.Elements) 38 | 39 | known_errors = {" ", "td> "} 40 | parser = ReportParser() 41 | with System.IO.File.OpenText(report1) as f: 42 | while not f.EndOfStream: 43 | parser.feed(f.ReadLine().replace("&", "")) 44 | 45 | parser.data1.append(parser.temp_data) 46 | report_data = parser.data1[1:] 47 | parser.close() 48 | errors, elements = [], [] 49 | for data in report_data: 50 | isError = True 51 | ids = [] 52 | for d in data: 53 | if isError: 54 | errors.append(d.strip()) 55 | isError = False 56 | continue 57 | id = filter(str.isdigit, d.rsplit(" : ", 1)[-1]) 58 | if id.isdigit(): 59 | id = int(id) 60 | else: 61 | continue 62 | if fetch_elements: 63 | id = getElement(id) 64 | ids.append(id) 65 | elements.append(ids) 66 | 67 | group_errors = Counter(errors).most_common() 68 | unique_errors, sum_errors = zip(*group_errors) 69 | sum_errors = list(sum_errors) 70 | sum_errors.append("Total errors : %d" % sum(sum_errors) ) 71 | OUT = errors, elements, unique_errors, sum_errors -------------------------------------------------------------------------------- /py/LineLoop.Merge.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference('ProtoGeometry') 7 | from Autodesk.DesignScript.Geometry import * 8 | 9 | curves = IN[0] 10 | margin = IN[1] 11 | original = curves[:] 12 | 13 | def OrderCurves(cl0,cl1): 14 | def switch1(i, j, cl0 = cl0, cl1 = cl1): 15 | cl0[i],cl0[j] = cl0[j],cl0[i] 16 | cl1[i],cl1[j] = cl1[j],cl1[i] 17 | 18 | _ln = len(cl1) 19 | xr1 = xrange(_ln) 20 | int_test = [[cl1[i].DoesIntersect(cl1[j])\ 21 | for j in xr1 if j != i] for i in xr1] 22 | countT = map(sum, int_test) 23 | if 0 not in countT: 24 | if 1 in countT and countT[0] != 1 : 25 | switch1(0, countT.index(1) ) 26 | for i in xrange(_ln - 1): 27 | k = i + 1 28 | if cl1[i].DoesIntersect(cl1[k]) : pass 29 | else : 30 | try: 31 | int_test = [cl1[i].DoesIntersect(cl1[j])\ 32 | for j in xrange(k, _ln)] 33 | switch1(k, k + int_test.index(True) ) 34 | except : pass 35 | return cl0, cl1 36 | 37 | def ClosedCase(cl0,cl1): 38 | pts = [cl1[i-1].Intersect(cl1[i])[0] for i in xrange(len(cl1) )] 39 | return PolyCurve.ByPoints(pts,True).Curves() 40 | 41 | def OpenCase(cl0,cl1): 42 | def FarPt(l1, p1): 43 | pts = (l1.StartPoint,l1.EndPoint) 44 | return max(pts, key = p1.DistanceTo) 45 | 46 | pts = [cl1[i].Intersect(cl1[i+1])[0] for i in xrange(len(cl1) -1)] 47 | pts.append(FarPt(cl0[-1],pts[-1])) 48 | pts.insert(0,FarPt(cl0[0],pts[0])) 49 | return PolyCurve.ByPoints(pts).Curves() 50 | 51 | def joinCurves(cl0,th1): 52 | len1 = len(cl0) 53 | if len1 < 2 : return cl0, False 54 | else: 55 | cl1 = [c.ExtendStart(th1).ExtendEnd(th1) for c in cl0] 56 | cl0, cl1 = OrderCurves(cl0,cl1) 57 | _fn = ClosedCase if cl1[0].DoesIntersect(cl1[-1]) and len1 > 2 else OpenCase 58 | try : return _fn(cl0,cl1), True 59 | except : return cl0, False 60 | 61 | def ReorderCurves(orig, new): 62 | reordered, new = [], list(new) 63 | app1, pop1, PaP = reordered.append, new.pop, Curve.PointAtParameter 64 | for i in xrange(len(orig) ): 65 | p1 = PaP(orig[i],0.5) 66 | p2 = [PaP(new[j],0.5) for j in xrange(len(new) )] 67 | ind1 = p2.index(min(p2, key = p1.DistanceTo) ) 68 | app1(pop1(ind1) ) 69 | return reordered 70 | 71 | out1 = joinCurves(curves, margin) 72 | OUT = out1[0], ReorderCurves(original,out1[0]), out1[1] -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/PlanarFace.FixDomain.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Number.ToString.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /py/Collect.LinkedInstanceElements.py: -------------------------------------------------------------------------------- 1 | # Copyright(c) 2019, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | # www.badmonkeys.net 4 | 5 | import clr 6 | 7 | clr.AddReference("RevitNodes") 8 | import Revit 9 | clr.ImportExtensions(Revit.Elements) 10 | clr.ImportExtensions(Revit.GeometryConversion) 11 | 12 | clr.AddReference('RevitServices') 13 | from RevitServices.Persistence import DocumentManager 14 | doc = DocumentManager.Instance.CurrentDBDocument 15 | 16 | clr.AddReference("RevitAPI") 17 | from Autodesk.Revit.DB import FilteredElementCollector, RevitLinkType, ElementMulticategoryFilter, ElementId 18 | import Autodesk.Revit.DB as DB 19 | 20 | from System.Collections.Generic import List 21 | import System 22 | 23 | def tolist(obj1): 24 | if hasattr(obj1,"__iter__"): return obj1 25 | else: return [obj1] 26 | 27 | links = UnwrapElement(tolist(IN[0]) ) 28 | cats = UnwrapElement(tolist(IN[1]) ) 29 | elements, transforms = [], [] 30 | OUT = elements, transforms 31 | 32 | ueWrapper = None 33 | wrappers = clr.GetClrType(Revit.Elements.ElementWrapper).GetMethods() 34 | for w in wrappers: 35 | if w.ToString().startswith("Revit.Elements.UnknownElement"): 36 | ueWrapper = w 37 | break 38 | 39 | for link in links: 40 | try: 41 | if RevitLinkType.IsLoaded(doc, link.GetTypeId() ): 42 | linkDoc = link.GetLinkDocument() 43 | 44 | if isinstance(cats[0], DB.Category): 45 | catId = List[DB.ElementId](c.Id for c in cats) 46 | filter = DB.ElementMulticategoryFilter(catId) 47 | elif isinstance(cats[0], DB.ElementType): 48 | types = List[System.Type](t.GetType() for t in cats) 49 | filter = DB.ElementMulticlassFilter(types) 50 | else: 51 | types = List[System.Type](cats) 52 | filter = DB.ElementMulticlassFilter(types) 53 | 54 | fec = FilteredElementCollector(linkDoc).WhereElementIsNotElementType().WherePasses(filter) 55 | linkEls = [] 56 | for e in fec: 57 | try: 58 | linkEls.append(e.ToDSType(True) ) 59 | except: 60 | if ueWrapper: 61 | linkEls.append(ueWrapper.Invoke(None, (e, True) ) ) 62 | elements.append(linkEls) 63 | transforms.append(link.GetTotalTransform().ToCoordinateSystem(1) ) 64 | fec.Dispose() 65 | filter.Dispose() 66 | else: 67 | elements.append('Linked document is unloaded') 68 | transforms.append(None) 69 | except Exception, ex: 70 | elements.append(str(ex) ) 71 | transforms.append(None) -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Fn.ElementsOfCategory.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Wall.WallType.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Active View.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /py/Element.SetLocation.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | 6 | clr.AddReference("RevitServices") 7 | import RevitServices 8 | from RevitServices.Persistence import DocumentManager 9 | from RevitServices.Transactions import TransactionManager 10 | doc = DocumentManager.Instance.CurrentDBDocument 11 | 12 | clr.AddReference("RevitNodes") 13 | import Revit 14 | clr.ImportExtensions(Revit.Elements) 15 | clr.ImportExtensions(Revit.GeometryConversion) 16 | 17 | clr.AddReference("RevitAPI") 18 | from Autodesk.Revit.DB import * 19 | from Autodesk.Revit.DB.Structure import StructuralFramingUtils, StructuralType 20 | FrU = StructuralFramingUtils 21 | 22 | def tolist(obj1): 23 | if hasattr(obj1,"__iter__"): return obj1 24 | else: return [obj1] 25 | 26 | elements = UnwrapElement(tolist(IN[0])) 27 | newloc = UnwrapElement(tolist(IN[1])) 28 | out1 = [] 29 | framing = ("Beam", "Brace") 30 | 31 | TransactionManager.Instance.EnsureInTransaction(doc) 32 | for i in xrange(len(elements)): 33 | try: 34 | el_typ = elements[i].GetType().ToString() 35 | isWall, isBeam = False, False 36 | if el_typ == "Autodesk.Revit.DB.Wall": 37 | w_start = WallUtils.IsWallJoinAllowedAtEnd(elements[i],0) 38 | w_end = WallUtils.IsWallJoinAllowedAtEnd(elements[i],1) 39 | WallUtils.DisallowWallJoinAtEnd(elements[i],0) 40 | WallUtils.DisallowWallJoinAtEnd(elements[i],1) 41 | isWall = True 42 | elif el_typ == "Autodesk.Revit.DB.FamilyInstance": 43 | if elements[i].StructuralType.ToString() in framing: 44 | b_start = FrU.IsJoinAllowedAtEnd(elements[i],0) 45 | b_end = FrU.IsJoinAllowedAtEnd(elements[i],1) 46 | FrU.DisallowJoinAtEnd(elements[i],0) 47 | FrU.DisallowJoinAtEnd(elements[i],1) 48 | isBeam = True 49 | newloc1 = newloc[i].ToRevitType() 50 | oldloc = elements[i].Location 51 | loc_typ = oldloc.GetType().ToString() 52 | if loc_typ == "Autodesk.Revit.DB.LocationCurve": 53 | oldloc.Curve = newloc1 54 | elif loc_typ == "Autodesk.Revit.DB.LocationPoint": 55 | oldloc.Point = newloc1 56 | if isWall: 57 | if w_start: WallUtils.AllowWallJoinAtEnd(elements[i],0) 58 | if w_end: WallUtils.AllowWallJoinAtEnd(elements[i],1) 59 | if isBeam: 60 | if b_start: FrU.AllowJoinAtEnd(elements[i],0) 61 | if b_end: FrU.AllowJoinAtEnd(elements[i],1) 62 | out1.append(elements[i].ToDSType(True)) 63 | except: 64 | out1.append(None) 65 | TransactionManager.Instance.TransactionTaskDone() 66 | 67 | OUT = out1 -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/NullGetParameter.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/FamilyInstance.Rotation.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Input.Wait.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.ShiftIndices+.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Color2Decimal.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.DropFirstLast.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/NullAllIndicesOf.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Samples/Beams.FixExtents.dyn: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Decimal2Color.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /py/Collect.ElementSketch.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | import math 6 | 7 | clr.AddReference("RevitServices") 8 | import RevitServices 9 | from RevitServices.Persistence import DocumentManager 10 | from RevitServices.Transactions import TransactionManager 11 | doc = DocumentManager.Instance.CurrentDBDocument 12 | 13 | clr.AddReference("RevitNodes") 14 | import Revit 15 | clr.ImportExtensions(Revit.Elements) 16 | clr.ImportExtensions(Revit.GeometryConversion) 17 | 18 | clr.AddReference("RevitAPI") 19 | from Autodesk.Revit.DB import * 20 | 21 | def tolist(obj1): 22 | if hasattr(obj1,"__iter__"): return obj1 23 | else: return [obj1] 24 | 25 | elements = UnwrapElement(tolist(IN[0])) 26 | getModel = IN[1] 27 | 28 | accepted_mc = "Autodesk.Revit.DB.ModelLine, Autodesk.Revit.DB.ModelArc, Autodesk.Revit.DB.ModelEllipse, Autodesk.Revit.DB.ModelHermiteSpline, Autodesk.Revit.DB.ModelNurbSpline" 29 | 30 | def almost_eq(line, mc): 31 | line2 = mc.Location.Curve 32 | xyz1 = line.Evaluate(0.5, True) 33 | if not line2.IsBound: 34 | xyz2 = line2.Center 35 | try: xyz1 = line.Center 36 | except: pass 37 | else: 38 | xyz2 = line2.Evaluate(0.5, True) 39 | if xyz1.DistanceTo(xyz2) <= 0.0001: 40 | return True 41 | else: 42 | return False 43 | 44 | def clean1(l1): 45 | for i in xrange(len(l1) ): 46 | l1[i] = [x for x in l1[i] if x != None] 47 | return l1 48 | 49 | def getSketch(el1): 50 | try: 51 | sk1 = doc.GetElement(ElementId(el1.Id.IntegerValue - 1) ) 52 | except: 53 | sk1 = None 54 | if not getModel and sk1 is not None and sk1.GetType().ToString() == 'Autodesk.Revit.DB.Sketch': 55 | profile = sk1.Profile 56 | else: 57 | t1 = SubTransaction(doc) 58 | t1.Start() 59 | deleted = doc.Delete(el1.Id) 60 | t1.RollBack() 61 | 62 | profile, mc = CurveArrArray(), [] 63 | for d in deleted: 64 | test_el = doc.GetElement(d) 65 | el_type = test_el.GetType().ToString() 66 | if el_type == "Autodesk.Revit.DB.Sketch": 67 | profile = test_el.Profile 68 | if not getModel: 69 | break 70 | elif getModel and el_type in accepted_mc : 71 | mc.append(test_el) 72 | 73 | ordered_mc = [ [None] * i.Size for i in profile] if getModel else [] 74 | curves = [ [None] * i.Size for i in profile] 75 | for i in xrange(profile.Size): 76 | for j in xrange(profile[i].Size): 77 | curves[i][j] = profile[i][j].ToProtoType() 78 | if getModel: 79 | for k in xrange(len(mc)): 80 | if almost_eq(profile[i][j], mc[k]): 81 | ordered_mc[i][j] = mc[k].ToDSType(True) 82 | del mc[k] 83 | break 84 | 85 | return curves, clean1(ordered_mc) 86 | 87 | TransactionManager.Instance.EnsureInTransaction(doc) 88 | result = map(getSketch, elements) 89 | TransactionManager.Instance.TransactionTaskDone() 90 | OUT = [r[0] for r in result], [r[1] for r in result] -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/List.EveryOther.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Select Edges.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Collector.CurrentSelection.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Select Linked Element.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/PolyCurve.Chamfer.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /py/List.DropDown.py: -------------------------------------------------------------------------------- 1 | #Copyright(c) 2016, Dimitar Venkov 2 | # @5devene, dimitar.ven@gmail.com 3 | 4 | import clr 5 | clr.AddReference('System.Windows.Forms') 6 | clr.AddReference('System.Drawing') 7 | 8 | from System.Drawing import Point, Color, Font 9 | from System.Windows.Forms import * 10 | from System import Array, Object 11 | 12 | def tolist(obj1): 13 | if hasattr(obj1,"__iter__"): return obj1 14 | else: return [obj1] 15 | 16 | def hasInd(l1, i): 17 | try: l1[i] ; return True 18 | except: return False 19 | 20 | class NameWrap(Object): 21 | def __init__(self, obj1, name1 = None): 22 | self.obj = obj1 23 | if obj1 == None: name1 = "null" 24 | if name1 == None and obj1 != None: self.name = obj1.ToString() 25 | else: self.name = name1 26 | def ToString(self): 27 | return self.name 28 | 29 | class DropDownForm(Form): 30 | def __init__(self, cm1): 31 | self.Text = "SpringNodes: Drop-Down Selection" 32 | self.Width = 368 33 | self.Height = 142 34 | self.BackColor = Color.FromArgb(40,40,40) 35 | self.ControlBox = False 36 | self.TopMost = True 37 | self.FormBorderStyle = FormBorderStyle.FixedDialog 38 | self.StartPosition = FormStartPosition.CenterScreen 39 | 40 | self.label = Label() 41 | self.label.Text = cm1 42 | self.label.Location = Point(5, 5) 43 | self.label.ForeColor = Color.FromArgb(234,234,234) 44 | self.label.Font = Font("Calibri", 10) 45 | self.label.AutoSize = True 46 | self.Controls.Add(self.label) 47 | 48 | self.combo1 = ComboBox() 49 | self.combo1.Location = Point(5, 31) 50 | self.combo1.Width = 350 51 | self.combo1.BackColor = Color.FromArgb(53,53,53) 52 | self.combo1.ForeColor = Color.FromArgb(234,234,234) 53 | self.combo1.Font = Font("Calibri", 11) 54 | self.combo1.MouseClick += self.expand 55 | self.Controls.Add(self.combo1) 56 | 57 | self.button1 = Button() 58 | self.button1.Text = 'Select' 59 | self.button1.AutoSize = True 60 | self.button1.Width = 350 61 | self.button1.Location = Point(6, 72) 62 | self.button1.ForeColor = Color.FromArgb(234,234,234) 63 | self.button1.Font = Font("Calibri", 10) 64 | self.button1.Click += self.save 65 | self.Controls.Add(self.button1) 66 | 67 | def expand(self, sender, event): 68 | self.combo1.DroppedDown = True 69 | def add_range(self,l1): 70 | self.combo1.Items.AddRange(l1) 71 | if l1.Length >= 1: 72 | self.combo1.SelectedIndex = 0 73 | def save(self, sender, event): 74 | self.output1 = self.combo1.SelectedItem 75 | self.Close() 76 | #safety measure due to automatic mode 77 | if IN[0] == None: l1 = [] 78 | else: l1 = tolist(IN[0]) 79 | if IN[1] == None: names = None 80 | else: names = tolist(IN[1]) 81 | 82 | for i in xrange(len(l1)): 83 | name1 = None 84 | if hasInd(names, i): name1 = names[i] 85 | l1[i] = NameWrap(l1[i], name1) 86 | l1_arr = Array[Object](l1) 87 | form = DropDownForm(IN[2]) 88 | form.add_range(l1_arr) 89 | Application.Run(form) 90 | if l1: OUT = form.output1.obj 91 | else: OUT = [] 92 | Application.Exit() -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/File.Size.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /_outdated/Excel.ImportFirstWorksheet.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /_outdated/LevelAbove.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Select Linked Elements.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Select Elements (ordered).dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Select Linked Face.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Line.StraightenZ.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Pt2Str.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Str2Pt.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Ln2Str.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Math.AlmostEqual.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Str2Ln.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Line.StraightenXY.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /_outdated/090716_last 0.82 compatible/Collector.ElementsInView.dyf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /py/Points.MinAreaRectangle.py: -------------------------------------------------------------------------------- 1 | import clr 2 | clr.AddReference('ProtoGeometry') 3 | from Autodesk.DesignScript.Geometry import Point, Vector, Rectangle 4 | from math import sqrt 5 | from operator import itemgetter 6 | 7 | _pts, elev = IN 8 | 9 | def hull(_pts): 10 | def pCrs(o, a, b): 11 | return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]) 12 | 13 | pts = sorted( (p.X, p.Y) for p in _pts) 14 | pLen = len(pts) 15 | if pLen < 4 : return pts 16 | else: 17 | lower, upper = [], [] 18 | 19 | for i in xrange(pLen): 20 | j = pLen - 1 - i 21 | while len(lower) >= 2 and pCrs(lower[-2], lower[-1], pts[i]) <= 0.000001: 22 | lower.pop() 23 | lower.append(pts[i]) 24 | while len(upper) >= 2 and pCrs(upper[-2], upper[-1], pts[j]) <= 0.000001: 25 | upper.pop() 26 | upper.append(pts[j]) 27 | 28 | lower.pop() 29 | upper.pop() 30 | lower.extend(upper) 31 | return lower 32 | 33 | # http://eprints.cs.vt.edu/archive/00000869/01/CS81017-R.pdf 34 | 35 | def scalar(k, i, j): 36 | return k[0] * (i[1] - j[1]) + k[1] * (j[0] - i[0]) + j[1] * i[0] - i[1] * j[0] 37 | 38 | def pDist(a, b, sqrt=sqrt): 39 | return sqrt( (a[0] - b[0])**2 + (a[1] - b[1])**2) 40 | 41 | def linDist(a, b, p): 42 | line_dist = pDist(a, b) 43 | if line_dist == 0: 44 | return a, pDist(p, a) 45 | 46 | t = ( (p[0] - a[0]) * (b[0] - a[0]) + (p[1] - a[1]) * (b[1] - a[1]) ) / line_dist**2 47 | 48 | cp = ( (b[0] - a[0]) * t + a[0], (b[1] - a[1]) * t + a[1]) 49 | d1 = pDist(p, cp) 50 | return cp, d1 51 | 52 | def indexer(end, position=0, start=0, step=1): 53 | i = position - step 54 | while True: 55 | i += step 56 | if i >= end: 57 | i = start 58 | yield i 59 | 60 | def highSearch(pts, iPt, jPt, j, it1=None, k=None, m=None, 61 | indexer=indexer, scalar=scalar): 62 | if it1 is None: 63 | it1 = indexer(len(pts), j) 64 | k, m = it1.next(), it1.next() 65 | Sa = scalar(pts[k], iPt, jPt) 66 | Sb = scalar(pts[m], iPt, jPt) 67 | while Sa < Sb: 68 | k, m = m, it1.next() 69 | Sa = scalar(pts[k], iPt, jPt) 70 | Sb = scalar(pts[m], iPt, jPt) 71 | return k, m 72 | 73 | pts = hull(_pts) 74 | 75 | OUT = [] 76 | highPts, closePts, areas, dists = [], [], [], [] 77 | lnPts = len(pts) 78 | 79 | it1 = indexer(lnPts, 2) 80 | k, m = it1.next(), it1.next() 81 | 82 | for i in xrange(lnPts): 83 | j = (i + 1) % lnPts 84 | 85 | k, m = highSearch(pts, pts[i], pts[j], j+1, it1, k, m) 86 | 87 | highPts.append(pts[k]) 88 | cp, l1 = linDist(pts[i], pts[j], pts[k]) 89 | closePts.append(cp) 90 | 91 | n, _ = highSearch(pts, pts[k], cp, j) 92 | _, l2a = linDist(pts[k], cp, pts[n]) 93 | 94 | q, _ = highSearch(pts, cp, pts[k], m) 95 | _, l2b = linDist(cp, pts[k], pts[q]) 96 | 97 | areas.append(l1 * (l2a + l2b) ) 98 | dists.append( (l2a, l2b) ) 99 | 100 | ix, _ = min(enumerate(areas), key=itemgetter(1) ) 101 | d1, d2 = dists[ix] 102 | _a, _b = closePts[ix], highPts[ix] 103 | a = Point.ByCoordinates(_a[0], _a[1], elev) 104 | b = Point.ByCoordinates(_b[0], _b[1], elev) 105 | 106 | _v = Vector.ByTwoPoints(a, b) 107 | v = Vector.ByCoordinates(-_v.Y, _v.X, 0).Normalized() 108 | p1 = a.Add(v.Scale(d2) ) 109 | p2 = a.Subtract(v.Scale(d1) ) 110 | p3 = b.Subtract(v.Scale(d1) ) 111 | p4 = b.Add(v.Scale(d2) ) 112 | 113 | OUT = (Rectangle.ByCornerPoints(p1, p2, p3, p4), 114 | 90 - v.AngleAboutAxis(Vector.XAxis(), Vector.ZAxis() ), 115 | [Point.ByCoordinates(p[0], p[1], elev) for p in pts]) --------------------------------------------------------------------------------