Dear Dynamo specialists,
I would like to have the newest version of a node (of packages) in my graph.
.
Is there a simpeler way to change the version of the node instead of remove older version and set the lines again (time extensive)?
Dear Dynamo specialists,
I would like to have the newest version of a node (of packages) in my graph.
.
Is there a simpeler way to change the version of the node instead of remove older version and set the lines again (time extensive)?
is this your won costumnode?
you can extract the pythoncode and you can maintain it.
KR
Andreas
Thanks for the response!
No, it is the node of Data-Shapes. I would like to use original packages instead of experimentation to extract codes. But I would like to replace for example version Clockwork for Dynamo node 2.3.0 for the 2.6.0 because of the cleaning of my codes.
How can I replace a 2.3.0. node, when package 2.6.0 for example is loaded, for the newest 2.6.0. node? While I dont want to remove the nodes and replace it and combine the lines of the nodes.
in our office we avoid packages ⌠instead we maintain our code
#Copyright (c) Data Shapes, 2020
#Data-Shapes www.data-shapes.io , elayoubi.mostafa@data-shapes.io @data_shapes
import clr
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import os
import webbrowser
import unicodedata
import io
import tempfile
import System
try:
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms.DataVisualization')
clr.AddReference("PresentationCore")
clr.AddReference("WindowsBase")
from System.Windows.Input import Key, Keyboard
from System.Drawing import Point , Size , Graphics, Bitmap, Image, Font, FontStyle, Icon, Color, Region , Rectangle , ContentAlignment , SystemFonts, FontFamily
from System.Windows.Forms import Application, DockStyle,MouseButtons , Button, Form, Label, TrackBar , ToolTip, ColumnHeader, TextBox, CheckBox, FolderBrowserDialog, OpenFileDialog, DialogResult, ComboBox, FormBorderStyle, FormStartPosition, ListView, ListViewItem , SortOrder, Panel, ImageLayout, GroupBox, RadioButton, BorderStyle, PictureBox, PictureBoxSizeMode, LinkLabel, CheckState, ColumnHeaderStyle , ImageList, VScrollBar, DataGridView, DataGridViewSelectionMode, DataGridViewAutoSizeColumnsMode , DataGridViewClipboardCopyMode , TreeView , TreeNode , TreeNodeCollection , AutoScaleMode , Screen, Padding, NativeWindow
from System.Windows.Forms.DataVisualization.Charting import *#Chart , SeriesChartType
from System.Collections.Generic import *
from System.Collections.Generic import List as iList
from System.Windows.Forms import View as vi
clr.AddReference('System')
from System import IntPtr , Char
from System import Type as SType, IO
from System import Array
from System.ComponentModel import Container
clr.AddReference('System.Data')
from System.Data import DataTable , DataView
try: #try to import All Revit dependencies
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import Selection , TaskDialog
from Autodesk.Revit.UI.Selection import ISelectionFilter
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument
clr.AddReference('RevitAPI')
try:
from Autodesk.Revit.DB import ImageImportOptions
except:
from Autodesk.Revit.DB import ImageTypeOptions , ImageType, ImagePlacementOptions , ImageInstance
from Autodesk.Revit.DB import FilteredElementCollector , Transaction, View , ViewType , ViewFamily, ViewDrafting, ViewFamilyType, Element, ElementId , FamilyInstance , Document , XYZ, BoxPlacement, UnitUtils
try:
from Autodesk.Revit.DB import UnitType
except:
from Autodesk.Revit.DB import SpecTypeId
dbviews = [v for v in FilteredElementCollector(doc).OfClass(View).ToElements() if (v.ViewType == ViewType.FloorPlan or v.ViewType == ViewType.CeilingPlan or v.ViewType == ViewType.Section or v.ViewType == ViewType.Elevation or v.ViewType == ViewType.ThreeD)]
viewindex = 0
try:
UIunit = Document.GetUnits(doc).GetFormatOptions(UnitType.UT_Length).DisplayUnits
except:
UIunit = Document.GetUnits(doc).GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()
class selectionfilter(ISelectionFilter):
def __init__(self,category):
self.category = category
def AllowElement(self,element):
if element.Category.Name in [c.Name for c in self.category]:
return True
else:
return False
def AllowReference(reference,point):
return False
except: #in case we are in the Sandbox, Formit or Civil 3D environment
pass
importcolorselection = 0
try:
from Autodesk.Revit.UI import ColorSelectionDialog
except:
importcolorselection = 1
try:
from Autodesk.Revit.DB import ImageTypeSource
except:
pass
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import Point as dsPoint
from System.Reflection import Assembly
import xml.etree.ElementTree as et
import re
def regexEndNum(input):
try:
return re.search('(\d+)$', input).group(0)
except:
return ""
def iterateThroughNodes(collection,li):
if hasattr(collection,'Nodes'):
ntest = collection.Nodes
if len(ntest) > 0:
for i in ntest:
iterateThroughNodes(i,li)
else:
if collection.Checked:
li.append(collection.Tag)
return li
class CustomMessageLoop(NativeWindow):
def __init__(self, form):
self.form = form
self.AssignHandle(form.Handle)
self.run_loop()
def run_loop(self):
while self.form.Visible:
Application.DoEvents()
class MultiTextBoxForm(Form):
def __init__(self):
self.Text = 'Data-Shapes | Multi Input UI ++'
self.output = []
self.values = []
self.cancelled = True
self.lastMouseLocation = 0
self.startNode = None
def setclose(self, sender, event):
cbindexread = 0
if sender.Name != "Cancel":
self.cancelled = False
for f in self.output:
if f.GetType() == myTextBox:
if f._isNum :
val = float(f.Text)
else:
val = f.Text
self.values.append(val)
if f.GetType() == CheckBox:
self.values.append(f.Checked)
if f.GetType() == Button:
if isinstance(f.Tag ,list):
try:
self.values.append([e for e in f.Tag if e.__class__.__name__ != "Category"])
except:
self.values.append(f.Tag)
else:
try:
if f.Tag.__class__.__name__ != "Category":
self.values.append(f.Tag)
else:
self.values.append([])
except:
self.values.append(f.Tag)
if f.GetType() == ComboBox:
try:
key = f.Text
self.values.append(f.Tag[key])
except:
self.values.append(None)
if f.GetType() == mylistview:
self.values.append([f.Values[i.Text] for i in f.CheckedItems])
if f.GetType() == mytrackbar:
self.values.append(f.startval+f.Value*f.step)
if f.GetType() == mygroupbox:
try:
key = [j.Text for j in f.Controls if j.Checked == True][0]
self.values.append(f.Tag[key])
except:
self.values.append(None)
if f.GetType() == myDataGridView:
f.EndEdit()
dsrc = f.DataSource
out = []
colcount = f.ColumnCount
rowcount = f.RowCount - 1
if f.Tag:
l = []
for i in range(colcount):
l.append(dsrc.Columns[i].ColumnName)
out.append(l)
for r in range(rowcount):
l = []
for i in range(colcount):
l.append(dsrc.DefaultView[r].Row[i])
out.append(l)
else:
for r in range(rowcount):
l = []
for i in range(colcount):
l.append(dsrc.DefaultView[r].Row[i])
out.append(l)
self.values.append(out)
if f.GetType() == TreeView:
ls = []
nds = f.Nodes[0]
iterateThroughNodes(nds,ls)
self.values.append(ls)
if f.GetType() == GroupBox:
rb = [c for c in f.Controls if c.GetType() == RadioButton and c.Checked][0]
self.values.append(rb.Text)
f.Controls.Remove(rb)
else:
self.values = None
self.cancelled = True
try:
self.Close()
except:
Console.WriteLine("error")
def reset(self, sender, event):
pass
def openfile(self, sender, event):
ofd = OpenFileDialog()
dr = ofd.ShowDialog()
if dr == DialogResult.OK:
sender.Text = ofd.FileName
sender.Tag = ofd.FileName
def exportToExcel(self, sender, event):
#importing Excel IronPython libraries
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')
from Microsoft.Office.Interop import Excel
ex = Excel.ApplicationClass()
ex.Visible = sender.Tag[1]
ex.DisplayAlerts = False
fbd = FolderBrowserDialog()
fbd.SelectedPath = sender.Text
parent = sender.Parent
fptextbox = parent.GetChildAtPoint(Point(parent.Location.X,sender.Location.Y+5*yRatio))
dataGrid = parent.GetChildAtPoint(Point(parent.Location.X,parent.Location.Y+23*xRatio))
dataTable = dataGrid.DataSource
fptext = fptextbox.Text
titletext = parent.GetChildAtPoint(Point(0,0)).Text
dr = fbd.ShowDialog()
frstRwTtle = sender.Tag[0]
if frstRwTtle:
_header = Excel.XlYesNoGuess.xlYes
else:
_header = Excel.XlYesNoGuess.xlNo
if dr == DialogResult.OK:
workbk = ex.Workbooks.Add()
worksheet = workbk.Worksheets.Add()
#Writing title and doc info
if sender.Tag[2]:
titleCell = worksheet.Cells[1,1]
worksheet.Cells[2,1].Value2 = sender.Tag[3]
titleCell.Value2 = titletext
titleCell.Font.Size = 18
titleCell.Font.Bold = True
startR = 3
endR = 3
else:
startR = 1
endR = 0
if frstRwTtle:
for j in range(0,dataTable.Columns.Count):
worksheet.Cells[startR,j+1] = dataTable.Columns[j].ColumnName
for i in range(0,dataTable.Rows.Count):
for j in range(0,dataTable.Columns.Count):
worksheet.Cells[i+startR+1,j+1] = dataTable.DefaultView[i].Row[j].ToString()
xlrange = ex.get_Range(worksheet.Cells[startR,1],worksheet.Cells[dataTable.Rows.Count+endR+1,dataTable.Columns.Count])
else :
for i in range(0,dataTable.Rows.Count):
for j in range(0,dataTable.Columns.Count):
worksheet.Cells[i+startR,j+1] = dataTable.DefaultView[i].Row[j].ToString()
xlrange = ex.get_Range(worksheet.Cells[startR,1],worksheet.Cells[dataTable.Rows.Count+endR,dataTable.Columns.Count])
xlrange.Columns.AutoFit()
worksheet.ListObjects.Add(Excel.XlListObjectSourceType.xlSrcRange, xlrange, SType.Missing, _header, SType.Missing).Name = "DataShapesTable"
worksheet.ListObjects["DataShapesTable"].TableStyle = "TableStyleMedium16"
workbk.SaveAs(fbd.SelectedPath + "\\" + fptext)
if not sender.Tag[1]:
workbk.Close()
ex.Quit()
def startCell(self, sender, event ):
sender.startcell["X"] = event.ColumnIndex
sender.startcell["Y"] = event.RowIndex
def endCell(self, sender, event ):
try:
sender.endcell["X"] = event.ColumnIndex
sender.endcell["Y"] = event.RowIndex
startval = sender.Rows[sender.startcell["Y"]].Cells[sender.startcell["X"]].Value
endNum = regexEndNum(startval)
if endNum != "":
if sender.endcell["Y"] == sender.startcell["Y"]:
for e,i in enumerate(range(sender.startcell["X"],sender.endcell["X"] + 1)):
sender.Rows[sender.startcell["Y"]].Cells[i].Value = startval[:-len(endNum)] + str(int(endNum) + e)
elif sender.endcell["X"] == sender.startcell["X"]:
for e,i in enumerate(range(sender.startcell["Y"],sender.endcell["Y"] + 1)):
sender.Rows[i].Cells[sender.endcell["X"]].Value = startval[:-len(endNum)] + str(int(endNum) + e)
else:
if sender.endcell["Y"] == sender.startcell["Y"]:
for i in range(sender.startcell["X"],sender.endcell["X"] + 1):
sender.Rows[sender.startcell["Y"]].Cells[i].Value = startval
elif sender.endcell["X"] == sender.startcell["X"]:
for i in range(sender.startcell["Y"],sender.endcell["Y"] + 1):
sender.Rows[i].Cells[sender.endcell["X"]].Value = startval
except:
pass
def startRowDrag(self, sender, event ):
shmak
def opendirectory(self, sender, event):
fbd = FolderBrowserDialog()
fbd.SelectedPath = sender.Text
dr = fbd.ShowDialog()
if dr == DialogResult.OK:
sender.Text = fbd.SelectedPath
sender.Tag = fbd.SelectedPath
def pickobjects(self, sender, event):
for c in self.Controls:
c.Enabled = False
try:
sel = uidoc.Selection.PickObjects(Selection.ObjectType.Element,'')
selelem = [doc.GetElement(s.ElementId) for s in sel]
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
#THIS METHOD IS FOR CIVIL 3D EVIRONMENT
def pickautocadobjects(self, sender, event):
selelem = []
for c in self.Controls:
c.Enabled = False
try:
acadDoc = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application").ActiveDocument
acadDoc.Activate()
acadUser = acadDoc.GetVariable("users5")
acadDoc.SendCommand("(and(princ\042"+ sender.Text + "\042)(setq ss(ssget))(setvar\042users5\042\042LinkDWGUIOK\042)(command\042_.Select\042ss\042\042)) ")
selection_ = acadDoc.ActiveSelectionSet
acadDoc.SendCommand("(setq ss nil) ")
if acadDoc.GetVariable("users5") == "LinkDWGUIOK" and selection_ != None:
for sel in selection_:
selelem.append(sel)
acadDoc.SetVariable("users5", acadUser)
sender.Tag = list(selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def pickautocadobject(self, sender, event):
selelem = None
for c in self.Controls:
c.Enabled = False
try:
acadDoc = System.Runtime.InteropServices.Marshal.GetActiveObject("Autocad.Application").ActiveDocument
acadUser = acadDoc.GetVariable("users5")
acadPickBox = acadDoc.GetVariable("pickbox")
acadDoc.SetVariable("pickbox", 5)
acadDoc.Activate()
acadDoc.SendCommand("(setq obj(car(entsel\042" + sender.Text + "\042))) ")
acadDoc.SendCommand("(and obj(setvar\042users5\042(cdr(assoc 5(entget obj))))(setq obj nil)) ")
selection_ = acadDoc.GetVariable("users5")
acadDoc.SetVariable("pickbox", acadPickBox)
acadDoc.SetVariable("users5", acadUser)
selelem = acadDoc.HandleToObject(selection_)
sender.Tag = selelem
except:
pass
for c in self.Controls:
c.Enabled = True
def pickobjectsordered(self, sender, event):
for c in self.Controls:
c.Enabled = False
output = []
test = True
TaskDialog.Show("Data|Shapes", 'Pick elements in order, then hit ESC to exit.')
while test:
try:
sel = doc.GetElement(uidoc.Selection.PickObject(Selection.ObjectType.Element, 'Pick elements in order').ElementId)
output.append(sel.ToDSType(True))
except :
test = False
sender.Tag = output
for c in self.Controls:
c.Enabled = True
def pickobjectsofcatordered(self, sender, event):
for c in self.Controls:
c.Enabled = False
output = []
test = True
if isinstance(sender.Tag,list):
category = UnwrapElement(sender.Tag)
else:
category = [UnwrapElement(sender.Tag)]
TaskDialog.Show("Data|Shapes", 'Select %s in order, then press ESC to exit.' %(', '.join([c.Name for c in category])))
while test:
try:
selfilt = selectionfilter(category)
sel = doc.GetElement(uidoc.Selection.PickObject(Selection.ObjectType.Element,selfilt, 'Select %s' %(', '.join([c.Name for c in category]))).ElementId)
output.append(sel.ToDSType(True))
except :
test = False
sender.Tag = (output)
for c in self.Controls:
c.Enabled = True
def picklinkedobjects(self, sender, event):
#This part was made easier by Dimitar Venkov's work
for c in self.Controls:
c.Enabled = False
try:
linkref = uidoc.Selection.PickObject(Selection.ObjectType.Element,'Select the link instance.')
link = doc.GetElement(linkref.ElementId).GetLinkDocument()
td = TaskDialog.Show('Data-Shapes','Select the linked elements and press Finish.')
sel = uidoc.Selection.PickObjects(Selection.ObjectType.LinkedElement,'Select the linked elements and press Finish.')
selelem = [link.GetElement(s.LinkedElementId) for s in sel]
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def pickobject(self, sender, event):
for c in self.Controls:
c.Enabled = False
try:
sel = uidoc.Selection.PickObject(Selection.ObjectType.Element,'')
selelem = doc.GetElement(sel.ElementId)
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def picklinkedobject(self, sender, event):
#This part was made easier by Dimitar Venkov's work
for c in self.Controls:
c.Enabled = False
try:
linkref = uidoc.Selection.PickObject(Selection.ObjectType.Element,'Select the link instance.')
link = doc.GetElement(linkref.ElementId).GetLinkDocument()
td = TaskDialog.Show('Data-Shapes','Select the linked element.')
sel = uidoc.Selection.PickObject(Selection.ObjectType.LinkedElement,'Select the linked element.')
selelem = link.GetElement(sel.LinkedElementId)
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def pickobjectsofcat(self, sender, event):
for c in self.Controls:
c.Enabled = False
if isinstance(sender.Tag,list):
category = UnwrapElement(sender.Tag)
else:
category = [UnwrapElement(sender.Tag)]
try:
selfilt = selectionfilter(category)
sel = uidoc.Selection.PickObjects(Selection.ObjectType.Element,selfilt,'Select %s' %(', '.join([c.Name for c in category])))
selelem = [doc.GetElement(s.ElementId) for s in sel]
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def pickobjectofcat(self, sender, event):
for c in self.Controls:
c.Enabled = False
if isinstance(sender.Tag,list):
category = UnwrapElement(sender.Tag)
else:
category = [UnwrapElement(sender.Tag)]
try:
selfilt = selectionfilter(category)
sel = uidoc.Selection.PickObject(Selection.ObjectType.Element,selfilt,'Select %s' %(', '.join([c.Name for c in category])))
selelem = doc.GetElement(sel.ElementId)
sender.Tag = (selelem)
except:
pass
for c in self.Controls:
c.Enabled = True
def treeNodeMouseDown(self, sender, event):
if Keyboard.IsKeyDown(Key.LeftShift) and event.Button == MouseButtons.Left:
tv = sender
endNode = tv.GetNodeAt(0, event.Y)
#If both nodes exist and are in the same parent node
if self.startNode != None and endNode != None and self.startNode.Parent == endNode.Parent:
startIndex = self.startNode.Index
endIndex = endNode.Index
#Swap the indexes if the starting index is greater than the ending index
if startIndex > endIndex:
temp = startIndex
startIndex = endIndex
endIndex = temp
for i in range(startIndex,endIndex+1):
self.startNode.Parent.Nodes[i].Checked = not self.startNode.Parent.Nodes[i].Checked
self.lastMouseLocation = event.Y
else:
tv = sender
self.startNode = tv.GetNodeAt(0, event.Y)
def pickfaces(self, sender, event):
faces = []
for c in self.Controls:
c.Enabled = False
try:
selface = uidoc.Selection.PickObjects(Selection.ObjectType.Face,'')
for s in selface:
elemid = s.ElementId
elem = doc.GetElement(elemid)
if isinstance(elem,FamilyInstance):
transf = elem.GetTransform().ToCoordinateSystem()
geom = elem.GetGeometryObjectFromReference(s)
convertedGeom = geom.Convert(s, transf)
faces.append(convertedGeom)
else:
f = uidoc.Document.GetElement(s).GetGeometryObjectFromReference(s).ToProtoType(True)
[i.Tags.AddTag("RevitFaceReference", s) for i in f]
faces.append(f)
sender.Tag = [i for j in faces for i in j]
except:
pass
for c in self.Controls:
c.Enabled = True
def pickpointsonface(self, sender, event):
faces = []
for c in self.Controls:
c.Enabled = False
selpoints = uidoc.Selection.PickObjects(Selection.ObjectType.PointOnElement,'')
points = []
for s in selpoints:
pt = s.GlobalPoint
points.append(dsPoint.ByCoordinates(UnitUtils.ConvertFromInternalUnits(pt.X,UIunit),UnitUtils.ConvertFromInternalUnits(pt.Y,UIunit),UnitUtils.ConvertFromInternalUnits(pt.Z,UIunit)))
sender.Tag = points
for c in self.Controls:
c.Enabled = True
def pickedges(self, sender, event):
edges = []
for c in self.Controls:
c.Enabled = False
try:
seledge = uidoc.Selection.PickObjects(Selection.ObjectType.Edge,'')
for s in seledge:
elemid = s.ElementId
elem = doc.GetElement(elemid)
if isinstance(elem,FamilyInstance):
transf = elem.GetTransform().ToCoordinateSystem()
geom = elem.GetGeometryObjectFromReference(s)
convertedGeom = geom.Convert(s, transf)
convertedGeom.Tags.AddTag("RevitFaceReference", s)
edges.append(convertedGeom)
else:
e = uidoc.Document.GetElement(s).GetGeometryObjectFromReference(s).AsCurve().ToProtoType(True)
e.Tags.AddTag("RevitFaceReference", s)
edges.append(e)
sender.Tag = edges
except:
pass
for c in self.Controls:
c.Enabled = True
def colorpicker(self, sender, event):
dialog = ColorSelectionDialog()
selection = ColorSelectionDialog.Show(dialog)
selected = dialog.SelectedColor
sender.Tag = selected
sender.BackColor = Color.FromArgb(selected.Red,selected.Green,selected.Blue)
sender.ForeColor = Color.FromArgb(selected.Red,selected.Green,selected.Blue)
def topmost(self):
self.TopMost = True
def lvadd(self, sender, event):
sender.Tag = [i for i in sender.CheckedItems]
def scroll(self, sender, event):
parent = sender.Parent
child = parent.GetChildAtPoint(Point(0,5*yRatio))
child.Text = str(sender.startval+sender.Value*sender.step)
def openurl(self, sender, event):
webbrowser.open(sender.Tag)
def selectall(self, sender, event):
if sender.Checked:
parent = sender.Parent
listview = parent.GetChildAtPoint(Point(0,0))
for i in listview.Items:
i.Checked = True
else:
pass
def selectnone(self, sender, event):
if sender.Checked:
parent = sender.Parent
listview = parent.GetChildAtPoint(Point(0,0))
for i in listview.Items:
i.Checked = False
else:
pass
def updateallnone(self, sender, event):
try:
parent = sender.Parent
rball = parent.GetChildAtPoint(Point(0,sender.Height + 5*yRatio))
rbnone = parent.GetChildAtPoint(Point(80 * xRatio,sender.Height + 5*yRatio))
if sender.CheckedItems.Count == 0 and event.NewValue == CheckState.Unchecked:
rbnone.Checked = False
rball.Checked = False
elif sender.CheckedItems.Count == sender.Items.Count and event.NewValue == CheckState.Unchecked:
rball.Checked = False
rbnone.Checked = False
elif sender.CheckedItems.Count == sender.Items.Count-1 and event.NewValue == CheckState.Checked:
rball.Checked = True
rbnone.Checked = False
elif sender.CheckedItems.Count == 1 and event.NewValue == CheckState.Unchecked:
rball.Checked = False
rbnone.Checked = True
else :
rball.Checked = False
rbnone.Checked = False
except:
pass
def zoomcenter(self, sender, event ):
if event.X > 15:
try:
element = doc.GetElement(uidoc.Selection.GetElementIds()[0])
uidoc.ShowElements(element)
except:
pass
else:
pass
def setviewforelement(self, sender, event ):
if event.X > 15*xRatio:
try:
item = sender.GetItemAt(event.X,event.Y).Text
element = UnwrapElement(sender.Values[item])
try:
viewsforelement = [v for v in dbviews if (not v.IsTemplate) and (element.Id in [e.Id for e in FilteredElementCollector(doc,v.Id).OfClass(element.__class__).ToElements()])]
except:
viewsforelement = [v for v in dbviews if (not v.IsTemplate) and (element.Id in [e.Id for e in FilteredElementCollector(doc,v.Id).OfClass(FamilyInstance).ToElements()])]
global viewindex
dbView = viewsforelement[viewindex]
id = [element.Id]
icollection = iList[ElementId](id)
uidoc.Selection.SetElementIds(icollection)
except:
pass
else:
pass
def CheckChildren(self, sender, event ):
evNode = event.Node
checkState = evNode.Checked
for n in event.Node.Nodes:
n.Checked = checkState
def ActivateOption(self, sender, event ):
parent = sender.Parent
associatedControls = [p for p in parent.Controls if p.Name == sender.Text and p.GetType() == Panel][0]
restofcontrols = [p for p in parent.Controls if p.Name != sender.Text and p.GetType() == Panel]
if sender.Checked:
associatedControls.Enabled = True
for c in restofcontrols:
c.Enabled = False
parent.Tag = sender.Text
def showtooltip(self, sender, event ):
ttp = ToolTip()
ttp.AutoPopDelay = 10000
ttp.SetToolTip(sender , sender.Tag)
def numsOnly(self, sender, event ):
if Char.IsDigit(event.KeyChar)==False and event.KeyChar != "." and Char.IsControl(event.KeyChar)==False:
event.Handled = True
def chart_showLabels(self, sender, event):
cb = sender
panelcht = sender.Parent
chart1 = panelcht.GetChildAtPoint(Point(0,0))
for s in chart1.Series:
if s.ChartType == SeriesChartType.Pie:
if cb.Checked:
s["PieLabelStyle"] = "Inside"
else:
s["PieLabelStyle"] = "Disabled"
else:
if cb.Checked:
s.IsValueShownAsLabel = True
else:
s.IsValueShownAsLabel = False
def imageexport(self, sender, event):
import datetime
from datetime import datetime
from RevitServices.Transactions import TransactionManager
#Modify resolution before the render
fontFam = FontFamily("Segoe UI Symbol")
originalFont = Font(fontFam,8)
panelcht = sender.Parent
chart1 = panelcht.GetChildAtPoint(Point(0,0))
originalTitleFont = chart1.Titles[0].Font
originalWidth = chart1.Width
originalHeight = chart1.Height
chart1.Visible = False
chart1.Dock = DockStyle.None
chart1.Width = 2100 * 0.8
chart1.Height = 1500 * 0.8
chart1.ChartAreas[0].AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None
chart1.ChartAreas[0].AxisY.LabelAutoFitStyle = LabelAutoFitStyles.None
chart1.ChartAreas[0].AxisX.LabelStyle.Font = Font(fontFam, 30)
chart1.ChartAreas[0].AxisY.LabelStyle.Font = Font(fontFam, 30)
chart1.ChartAreas[0].AxisX.TitleFont = Font(fontFam, 30)
chart1.ChartAreas[0].AxisY.TitleFont = Font(fontFam, 30)
chart1.TextAntiAliasingQuality = TextAntiAliasingQuality.High
chart1.BackColor = Color.White
chart1.Titles[0].Font = Font(fontFam, 32, FontStyle.Bold)
chart1.ChartAreas[0].BackColor = Color.White
for serie in chart1.Series:
serie.Font = Font(fontFam, 30)
for p in serie.Points:
p.Font = Font(fontFam, 30)
p.MarkerSize = 15
for legend in chart1.Legends:
legend.Font = Font(fontFam, 30)
legend.BackColor = Color.White
chart1.Invalidate()
chart1.SaveImage(tempfile.gettempdir() + "\\chartImage.bmp", ChartImageFormat.Bmp)
#Get back to original settings
chart1.Width = originalWidth
chart1.Height = originalHeight
chart1.BackColor = Color.Transparent
chart1.ChartAreas[0].BackColor = Color.Transparent
chart1.ChartAreas[0].AxisX.LabelStyle.Font = originalFont
chart1.ChartAreas[0].AxisY.LabelStyle.Font = originalFont
chart1.ChartAreas[0].AxisX.TitleFont = originalFont
chart1.ChartAreas[0].AxisY.TitleFont = originalFont
chart1.Titles[0].Font = originalTitleFont
for serie in chart1.Series:
serie.Font = originalFont
for p in serie.Points:
p.Font = originalFont
p.MarkerSize = 8
for legend in chart1.Legends:
legend.Font = originalFont
legend.BackColor = Color.Transparent
chart1.Invalidate()
chart1.Visible = True
#Import the picture in a Drafting View
#Import the picture in a Drafting View // The try catch if for handling the fact that ImageImportOptions was deprecated in 2020 and is obsolete in 2021
collector = FilteredElementCollector(doc).OfClass(ViewFamilyType)
viewFamilyTypes = []
for c in collector:
if c.ViewFamily == ViewFamily.Drafting:
viewFamilyTypes.append(c)
viewFamilyType = viewFamilyTypes[0]
TransactionManager.Instance.EnsureInTransaction(doc)
draftView = ViewDrafting.Create(doc,viewFamilyType.Id)
draftView.Name = chart1.Titles[0].Text + datetime.now().strftime(" (%m/%d/%Y, %H.%M.%S)")
imagePath = tempfile.gettempdir() + "\\chartImage.bmp"
newElement = clr.StrongBox[Element]()
try:
importOptions = ImageImportOptions()
importOptions.Resolution = 72
importOptions.Placement = BoxPlacement.TopLeft
doc.Import(imagePath,importOptions,draftView,newElement)
except:
try:
imageTypeOption = ImageTypeOptions()
imageTypeOption.SetPath(imagePath)
except:
imageTypeOption = ImageTypeOptions(imagePath,False,ImageTypeSource.Import)
imageTypeOption.Resolution = 72
imageType = ImageType.Create(doc,imageTypeOption)
placementOptions = ImagePlacementOptions(XYZ(0,0,0),BoxPlacement.TopLeft)
ImageInstance.Create(doc,draftView,imageType.Id,placementOptions)
TransactionManager.Instance.TransactionTaskDone()
def chart_showLegend(self, sender, event ):
cb = sender
panelcht = sender.Parent
chart1 = panelcht.GetChildAtPoint(Point(0,0))
if len(chart1.Legends) <= 1:
for legend in chart1.Legends:
if cb.Checked:
legend.Enabled = True
else:
legend.Enabled = False
else:
if cb.Checked:
chart1.Legends[1].Enabled = True
else:
chart1.Legends[1].Enabled = False
class mylistview(ListView):
def __init__(self):
self.Values = []
class mytrackbar(TrackBar):
def __init__(self,startval,step):
self.startval = startval
self.step = step
class myDataGridView(DataGridView):
def __init__(self):
self.startcell = {}
self.endcell = {}
class mygroupbox(GroupBox):
def __init__(self):
self.Values = []
class myTextBox(TextBox):
def __init__(self):
self._isNum = False
#Form initialization
form = MultiTextBoxForm()
xRatio = Screen.PrimaryScreen.Bounds.Width/1920
if xRatio == 0:
xRatio = 1
yRatio = Screen.PrimaryScreen.Bounds.Height/1080
if yRatio == 0:
yRatio = 1
form.topmost()
form.ControlBox = True
xlabel = 25 * xRatio
xinput = 150 * xRatio
formy = 10 * yRatio
if IN[8] * xRatio > (350 * xRatio): formwidth = IN[8] * xRatio
else: formwidth = 350 * xRatio
fields = []
error = 0
#Description
if IN[3] != "":
des = Label()
des.Location = Point(xlabel,formy)
des.Font = Font("Arial", 15,FontStyle.Bold)
des.AutoSize = True
des.MaximumSize = Size(formwidth - (2 * xlabel)*xRatio,0)
des.Text = IN[3]
form.Controls.Add(des)
formy = des.Bottom + (15*xRatio)
formheaderheight = formy
#Input form
# Create a container panel for all inputs
body = Panel()
body.Location = Point(0,formy)
body.Width = formwidth - 15*xRatio
# Process form inputs
if isinstance(IN[0],list):
inputtypes = IN[0]
else:
inputtypes = [IN[0]]
# This definition is to handle the sorting of special characters
def remove_accents(input_str):
nfkd_form = unicodedata.normalize('NFKD', input_str)
only_ascii = nfkd_form.encode('ASCII', 'ignore')
return only_ascii
#Adding Logo
#a.s.o.
⌠the code is realy long!
i can just recomment it.
KR
Andreas
Itâs unclear what youâre actually asking for as these two statements seem to be mutually exclusive.
You can only load one version of a package at a time, so thereâs no way to have a node in a previous version when using an updated package unless you specifically copied that node outside of the package to maintain manually.
Creating a graph with the 2.3 version of a node will save the reference to that node via the package and the version that was used, but when opened with the 3.6 version of the package will load the 2.6 version of the node as long as it still exists. The warnings you get from Dynamo about nodes using different package versions is only to notify you that the functionality of the node may have changed. The current (package) version is still used.
That is a LOT more work and may run afoul of some licensing for packages. Best to maintain the packages and go from there.
Agreed on the licensing issue- but making sure everyone has the all the same packages and setup can also be a maintenance headache in itâs own right.
Having a central location of non-package-dependent (Dynamo Player) scripts can be one way to handle it- and itâs what I have done in my office.
The issue with this is you wind up doing the same work repeatedly.
Letâs think of this in the context of a Revit model. You have a bathroom layout which will be used in multiple times, in multiple projects, spanning multiple Revit versions. How would you go about this?
Maybe model it once and then copy it around the project, and then copy/paste to the next rvt. What about when you move into the next Revit build and the previous layout needs to change because the Revit file structure doesnât permit hosting one of the families in the same way? And what happens when 6 months later the owner comes back and says you need to change the layout?
Utilizing groups can reduce this in the context of a single model, and if you arenât going to reuse it content in another project it is generally recognized as a good practice, but they donât scale to other jobs.
Utilizing an xref reduces the bulk of the rework and duplication of work issues which are prevented by the âcopy paste instances though and across projectsâ method, and is generally accepted as a best practice for reusing work at scale. However it does require updating the xref to each version, and potentially making changes in each supported project version, so maybe 4 tasks which is worse than once. But it is much better than once per instance per project (1000âs of tasks), and better than once for the group type per project (100âs of tasks).
Now letâs reframe this in the context of Dynamo.
You can copy/paste your Python into new copies of a node to make many instances of the text. And when you want to improve it or update it or alter it you have to chase them all down. Then in the next release when Revit makes a change that means you have to update the Python, that means you need to update every instance of the code. Maybe you only have one Python node per graph, but that graph has been copied and saved to multiple locations and now you need to track all of those down. And a user opening a graph with the previous version of the Python node wonât execute you have a âhey your dynamo thing brokeâ issue to deal with, so you have to manage your .dyn versions to prevent that. Oh and you have to deal with multiple versions of the Python by managing your list structures for each.
Or you could wrap your Python in a custom node. This means you can make a change once for each Revit build, and pass that change into a new version of the package which means any .dyn with your node will work. Breaking changes mean you make one change, and updates mean you make at most 4 changes. Then deploy those to your users just like you had to with the version specific .dyn files.
Now there is an argument to say âone dyn version per Revit versionâ consisting of a single Python node where needed, and centrally managed and deployed is easier. Iâll admit this can work for âone offâ tasks which wonât be replicated in other graphs, but I am not sold on you that for code which is reused. Further, if itâs one off and repeated use a full add-in is likely even easier to scale and less work than most think once you have a Python POC.
Overall we have options for âgetting out content to usersâ, which is really good. However there isnât an âeasy buttonâ for management at this time. And deploying anything (.dyn or packages) at scale isnât easy even with the package manager (warts and all Iâll take it). However in my opinion you can make your future selfâs life easier by moving to packages instead of in canvas nodes.
Two approaches Iâve experimented with (with mixed results), develop an inhouse company package and robocopy it out. You abandon using most other packages and develop your own code (I agree itâs not good to copy other package code insitu).
The other interesting approach Iâve played with is storing libraries on the server full of functions that in effect do all the work. The python code just appends them in to sys path and from there you control the function in one place. Speed hits for server storage of course though which is always rough. I used that for my logging system though, and built in a basic safeguard in the event the server could not be found using os and checking for directory path prior to appending.
One benefit was users needed to be on company system for code to function, and if they try to yoink the code itâs useless without the core libraries. Huge effort to set up and educate others in though.
Great discussion, thank you. I know we have gotten a bit away from the original topicâŚ
Not sure if the OP got the answer he needed from @Nick_Boyts, but the more information about pros and cons of âinternalâ development management out there, the better.