you have to use IronPython inside Dynamo, which has access to the .Net Framework.
you have to use IronPython inside Dynamo, which has access to the .Net Framework.
Dear Sam,
Thank you for your patience.
The development team replied:
It looks as if that currently it is not possible. The method exists internally, but it's not exposed to the public API. We compute an appropriate group when you create a global parameter based on the input ParameterType::Enum datatype.
It would not be a large effort to expose this for the next major release of Revit. However, the managers have to approve this modification first.
Best regards,
Jeremy
I discussed this with the development team, and they are asking me to file a development issue for this.
That requires a minimal reproducible case, including a minimal sample model, minimal sample code, and exact steps for reproducing the issue:
https://thebuildingcoder.typepad.com/blog/about-the-author.html#1b
Can you please provide that so I can share it with them for analysis, fix and verification?
Thank you!
I can't get it to work either and its driving me crazy.
I threw in some task dialog boxes so we can follow the program as it runs. (I'm not very good with the debugger.)
I also believe the
if (!wkset.IsOpen)
should be
if (wkset.IsOpen)
Otherwise, 1stWkSet_Close becomes a list of the worksets that are already closed.
I also simplified your compare where it looks for certain worksets. The program seems to do everything right, but the one line
wk.Close(lstWkSet_Close);
just doesn't seem to do anything. I also tried it inside a transaction.
The odd thing is that this line of code actually opens a closed workset. That doesn't make sense because it is not even including that workset name in the list of worksets. Seems like a big clue, but I don't get it.
Here is what I have, and its still driving me crazy;
List<Element> lstRvtLinkType = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkType)).ToList(); //foreach (Document _linkdoc in app.Documents) foreach (Document _linkdoc in doc.Application.Documents) { TaskDialog.Show("Starting to check Document:", _linkdoc.PathName.ToString()); if (!_linkdoc.IsLinked) { TaskDialog.Show("Revit","Continue"); continue; } TaskDialog.Show("Revit", "setting Linked type to null"); RevitLinkType _RvtLinkType = null; foreach (Element elmnt in lstRvtLinkType) { TaskDialog.Show("Starting to Check Revit Link:", elmnt.Name.ToString()); _RvtLinkType = elmnt as RevitLinkType; if (_RvtLinkType.Name != _linkdoc.Title) continue; else break; } TaskDialog.Show("Revit","Start processing linked workset"); List<WorksetId> lstWkSet_Close = new List<WorksetId>(); WorksetConfiguration wk = new WorksetConfiguration(); ModelPath _modelpath = _linkdoc.GetWorksharingCentralModelPath(); WorksetTable _worksetTable = _linkdoc.GetWorksetTable(); IList<WorksetPreview> lstPreview = WorksharingUtils.GetUserWorksetInfo(_modelpath); TaskDialog.Show("Revit","Start processing worksets in 1st preview"); foreach (WorksetPreview item in lstPreview) { Workset wkset = _worksetTable.GetWorkset(item.Id); //if (!wkset.IsOpen) if (wkset.IsOpen) { TaskDialog.Show("Testing",wkset.Name.ToString()); //if ((item.Name.CompareTo("Shared Levels and Grids") == 0) || (item.Name.CompareTo("Workset2") == 0) || (item.Name.CompareTo("Workset3") == 0)) if ((item.Name.ToString() == "Workset3") || (item.Name.ToString() == "Workset4")) { TaskDialog.Show("Added Workset",wkset.Name.ToString()); lstWkSet_Close.Add(item.Id); continue; } } } String mycount = lstWkSet_Close.Count.ToString(); TaskDialog.Show("Ready to close this many worksets", mycount); wk.Close(lstWkSet_Close); _RvtLinkType.LoadFrom(_modelpath, wk); } } catch (Exception e) { TaskDialog.Show("dd", e.Message); return; } return;
Thank you for you help. I didn't get a chance to use your simplified if statement yet but I was able to figure out that I was missing workset configuration options. I set it to OpenLastViewed so that i could have it remember what was previously open/closed.
WorksetConfiguration wk = new WorksetConfiguration(WorksetConfigurationOption.OpenLastViewed);
As i was running the routine I found that running the wk.Close() would only close the ones that i asked it to close and would reopen others that I had previously closed. I had my worksetlist include the ones that were already closed and then add the ones that i needed to also be closed.
WorksetConfiguration wk = new WorksetConfiguration(WorksetConfigurationOption.OpenLastViewed); ModelPath _modelpath = _linkdoc.GetWorksharingCentralModelPath(); WorksetTable _worksetTable = _linkdoc.GetWorksetTable(); IList<WorksetPreview> lstPreview = WorksharingUtils.GetUserWorksetInfo(_modelpath); foreach (WorksetPreview item in lstPreview) { Workset wkset = _worksetTable.GetWorkset(item.Id); if (!wkset.IsOpen) { lstWkSet_Close.Add(item.Id); } else { if ((item.Name.CompareTo("Shared Levels and Grids") == 0) || (item.Name.CompareTo("1/4 SCOPEBOX AND MATCHLINE") == 0) || (item.Name.CompareTo("1/8 SCOPEBOX AND MATCHLINE") == 0)) { lstWkSet_Close.Add(item.Id); continue; } } } wk.Close(lstWkSet_Close); _RvtLinkType.LoadFrom(_modelpath, wk);
That's great!I'll try it.
Well that explains it. Seems to make sense now.
Glad you figured it out.
Dear all,
I am working at a function that replace the material appearance by local imported image. While I using the AppearnceAssetEditScope to change the image scaleX and scaleY, there is an exception throws "The input value is invalid for this AssetPropertyDistance property".
Here are the codes:
double width=3000;
using(AppearanceAssetEditScope editScope=new AppearanceEditScope(assetElem.Document))
{
Asset editAsset=editScope.Start(assetElem.Id);
Asset unifiedBitmapAsset=editAsset.FindByName(Generic.GenericDiffuse).GetSingleConnectedAsset();
AssetPropertyDistance scaleX=unfiedBitmapAsset.FindByName("texture_RealWorldScaleX") as AssetPropertyDistance;
scaleX.Value=Math.Round(UnitUtils.Convert(width, DisplayUnit.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_INCHES),2); //thorws an exception with message " The input value is invalid for this AssetPropertyDistance property"
editScope.Commit(true);
}
More details:
The AssetPropertyBoolean [UnifiedBitmap.TextureScaleLock] can't be set value too, throws the same exception.
However, only the AssetPropertyString [UnifiedBitmap.UnifiedbitmapBitmap] can be set value success.
Now I found more Information:
The asset element I want to edit is created in the same Transaction by loading a new family in the project. So if it's the first time to execute my function, it will have the problems like above description. But if this function is called for the second time, because the element is exists in the project, everything is fine, all the asset property can be set perfectly.
I have call the Document.Regenerate() method in the transaction of loading a new family into my project. But it seems not work to the next transaction(Main task is editing some of the asset properties) which in the same TranactionGroup of the same externalcomand.
So what api methods should I call if I want to edit the asset properties after I load it's belong family at the same time(Same externalcommand, different transaction).
> Where to find the sample? I am using Revit 2019 and have installed Revit SDK 2019. But there is no sample named "ElementViewer".
SDK/Samples/Viewers/ElementViewer
Sometimes, a call to regenerate is insufficient, and you really have to close and commit the transaction before you can proceed with the next step:
https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.33
In this case, you can start a second transaction for that. If you like, you can package the two into one single transaction group:
https://thebuildingcoder.typepad.com/blog/about-the-author.html#5.53
I integrated your two updated code versions into the repository:
https://github.com/jeremytammik/CropViewToRoom
It would be easier and cleaner if you forked the repository and created a pull request for them instead.
That would make it easier to follow what you did step by step.
Unfortunately, it has now reached a state that I do not quite understand.
What are these two passes about?
Why is there so much code duplication?
Why do you have an if statement excluding room separators by saying
if( elem != null ) //The elem == null is due to room separators.
... and yet, inside that if-block of code, you have a statement checking for room separators, with quite a lot of code in it?
//Are there any other situations need taking account off? else if( (BuiltInCategory) elem.Category.Id.IntegerValue == BuiltInCategory.OST_RoomSeparationLines )
This same paradoxical construct is repeated again further on, with quite a lot of code once again.
Sorry, that is too confusing for my poor human brain.
Hello!
Thanks for your reply, Jeremy.
The minimal reproducible case is:
1. Create an empty project in Revit, create one pipe in it.
2. Set the pipe property "Mark" this value (without quotes): "Труба напорная раструбная ВЧШГ Ду 150 мм"
3. Create an empty External Command.
4. Add this code there:
using System.Diagnostics;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB.Plumbing;
namespace Example
{
[Transaction(TransactionMode.Manual)]
public class Command : IExternalCommand
{
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements)
{
UIApplication uiapp = commandData.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
FilteredElementCollector col = new FilteredElementCollector(doc);
Element elem = col.OfClass(typeof(Pipe)).FirstElement();
Parameter p = elem.get_Parameter(BuiltInParameter.ALL_MODEL_MARK);
ParameterValueProvider pvp = new ParameterValueProvider(p.Id);
FilterStringRule rule = new FilterStringRule(pvp, new FilterStringContains(), "вчшг", caseSensitive: false);
Debug.Print($"parameter value: '{p.AsString()}'");
Debug.Print($"check: {rule.ElementPasses(elem)}");
return Result.Succeeded;
}
}
}
5. Add an External Command to Revit.
6. Open the created project, run an External Command.
7. In the Output appears:
parameter value: 'Труба напорная раструбная ВЧШГ Ду 150 мм'
check: False
Perhaps, the problem is in cyrillic?
Best regards
My apologies for the late response, replies didn't seem to come through at all.
I will be preparing a sample today.
Hello,
I want to insert a button in an existing panel but I have a problem.
I have 2 addins that share the same panel.
I get the ribbontab and the ribbonPanel.
1st addin (loaded first)
RibbonTab: MicroMéthodes
ribbonPanel: MicroCyclePlus
pushbutton: Cahier de cycle
SlideOut
pushbutton: A propos Cahier de cycle
2nd addin (loaded second)
RibbonTab: MicroMéthodes
ribbonPanel: MicroCyclePlus
pushbutton: Histogramme
SlideOut
pushbutton: A propos Histogramme
The result is not the one I want.
RibbonTab: MicroMéthodes
ribbonPanel: MicroCyclePlus
pushbutton: Cahier de cycle
SlideOut
pushbutton: A propos Cahier de cycle
pushbutton: Histogramme
Desired result:
Here is an archive with a project to run in Revit 2019. Please, refer to the README.md within this attached archive for reproduction steps.
The reason we're currently limited to Revit 2019 is because the majority of our clients don't jump the gun on transitioning to newer Revit versions, and most are currently working with 2019.
Hi, I want to modiy the thickness of an object so naturally I need to do it with a Transaction and so on, so I need to do an External Command which I have defined here:
using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using Toolbar.Commands.Base; using Toolbar.UI; using Autodesk.Revit; using Autodesk.Revit.ApplicationServices; using Application = Autodesk.Revit.ApplicationServices.Application; namespace Toolbar.Commands { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] class ExternalCommandFloorThickness : ExternalCommandBase, IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; InitializeMembers(commandData); FloorThickness formFloor = new FloorThickness(revitApplication, revitActiveDocument); // Retrieve elements from database FilteredElementCollector collector = new FilteredElementCollector(doc).WhereElementIsElementType().OfClass(typeof(FloorType)); var query = from element in collector where element.Name == "Generic 150mm" select element; // Modify document within a transaction using (Transaction tx = new Transaction(doc)) { tx.Start("Transaction ModifyFloorThickness"); double width = UnitUtils.ConvertToInternalUnits(100, DisplayUnitType.DUT_MILLIMETERS); foreach (Element e in query) { FloorType floorType = e as FloorType; CompoundStructure compoundStructure = floorType.GetCompoundStructure(); compoundStructure.SetLayerWidth(0, width); floorType.SetCompoundStructure(compoundStructure); } tx.Commit(); } return Result.Succeeded; } } }
But now the problem is that I want to run/execute this code from the click of a button in a Form. My best idea so far is doing this:
private void button2_Click(object sender, EventArgs e) { ExternalCommandFloorThickness extCommFT = new ExternalCommandFloorThickness(); extCommFT.Execute(); }
But obviously this doesn't work because I will need to pass the parameters to the .Execute() function, but I cannot pass it a commandData because I'm inside the code of a Form not an External Command and so on.
So any ideas are highly appreciated it!
Many thanks in advance!
Dear all,
I am currently trying to automaticly generate a new wall layer based upon rooms, defining the finishing (paint, tiles...).
And basically it works like a charme.
I am trying to to this from a set of solids optained by starting from the room solids and cutting out the intrsecting geometry. However one downside that happens is that the resulting solid is composed of more planarFaces than needed. So some planar face of the solid could be joined into one planar face.
has anyone touch solid simplification in revit api?
Hi all,
I've changed the Revit language from English to other before opening Revit by right click Revit application and change language in properties.
But, if I'm opening any Revit file, the annotation texts and dimensions are still in English.
Please help me to change the language for the dimensions and annotations in the Revit file using api.