Quantcast
Channel: All Revit API Forum posts
Viewing all 66664 articles
Browse latest View live

revit crash - need help

$
0
0

Hello,

 

while using my revit 2018 plugin with a large model, revit crash at the end of execution

the plugin create templates and many viewplan, 3dview, and  textnotes, filledregions on them

at end of execution, (after 8 hours with this model), a control process verify each created viewplan (for example, verify if textnotes are accessible in viewplan while using scopebox)

during this control, revit crash with an error (log extraction)
' 5:< ;PERF;MISC;FullUpdateGraphicCacheUpdater::updateAll() DBViewPlan id=31766357: 497 elements need cache update
' 2.799139 5:<<updateGReps 2528 elements/ALL_GAPS 2.299871/TurnOff_GAPs 57%
' 2.808059 4:<<B3.1.000-2.XX B3_CARPARK 1 (HELIX RAMP)-23015579: ;PERF;MISC;generating greps
' 1:< ;PERF;MISC;FullUpdateGraphicCacheUpdater::updateAll() DBViewPlan id=31766357 (in RvtLinkInstance id=22961020): 497 elements need cache update
' 1:< ;PERF;MISC;FullUpdateGraphicCacheUpdater::updateAll() DBViewPlan id=23015579: 897 elements need cache update
' 5:< A MemoryException is raised on line 196 of Arr.cpp
' 5:< System exception in generateViewSpecificGRep
' 5:< for element 23007029 of class ModelClipBox
' 5:< in dbview 23015925 of class DBViewPlan
' 5:< System exception in generateViewSpecificGRep
' 5:< for element 23007029 of class ModelClipBox
' 5:< in dbview 23015925 of class DBViewPlan
' 5:< TaskDialog "A serious error has occurred. It is strongly recommended that you save your work in a new file before continuing.

while executing an instruction like
 filteredElementCollector = new filteredElementCollector(document, viewId)
.OfCategory(BuiltInCategory.OST_DetailComponents)
.WhereElementIsNotElementType();

so,
is it a revit bug, or is it another problem ?

 

can you help me ?

 

thanks in advance

 

Luc

 

attached is the full log file


Re: Only one instance addin plugin

$
0
0

You can easily support multiple versions of Revit with one single add-in.

 

If the Revit API calls you make have not changed between Revit 2018 and Revit 2019, simply use the same add-in for both, compiled for Revit 2018.

 

If the API calls that you use have changed, you can handle that using .NET Reflection:

 

 

transaction usage, need best practice advice

$
0
0

Hello,

 

I'm working on a big plugin, it create many viewplan,3dview,textnotes,filledregions, ...,
reread them, export them, and so...
it work on very large models

 

and I need your advice


what are the best practices (in term of revit efficacity) ?

 

have one big transaction and all of the code inside ?

have one transaction per creation/modification functions (actually 1 function per object) ?

have some well chosen transactions (for update grouping) ?

have one transaction and many subtransactions ?

other solution ?

 

thanks in advance

 

Luc

Re: Duct system

$
0
0

Hey,
If it is not possible via this path
I can always create a group with my SystemType and load it, it's primitive but it also works

Re: transaction usage, need best practice advice

$
0
0

Hi  ,

I would suggest you go for one transaction and many subtransactions.

Subtransaction is to control a set of modifications done in a transaction, meaning that the modification enclosed in a sub-transaction can be rolled back as if they have not happened. In a sense, it allows an application to go back to a certain point (the start of the sub-transaction) in a sequence of model changes.

 

Re: Is a model Workshared without opening the file

$
0
0

Perfect thank you,

I still need to dig through the Revit.ini file for the local folder. But I don't think there is currently any API for that.

 

Kind Regards

David

 

Re: Only one instance addin plugin

$
0
0

thx...But I think you talking about compiling plugin for multi version of revit.

 

I mean allow run only one instance of plugin.

 

Re: Is the first Edgeloop still the outer loop?

$
0
0

Hi I would like to toss this in for discussion, 
It should be able to seperate all curve loops of a faceinto interior / exterior curves...
It needs some adaptation for non planar faces...


The idea is quite simple:
The face has an area which can be computed, The area of each curve can be computed (https://en.wikipedia.org/wiki/Shoelace_formula)... 

So the only issues is to find a combination of + / - so that the resulting sum equals the area of the initial face...
This will work just fine if the face has a limited number since it uses a branch and bound approch for itterating through the possibilities...

 public static CurveLoop[] GetOuterBoundaries(Autodesk.Revit.DB.Face source)
        {
            List<CurveLoop> allBounds = new List<CurveLoop>();
            int totalArea = (int)(source.Area * 100);

            allBounds.AddRange(GeometryHelper.GetBoundaries(source));
            List<int> boundAreas = new List<int>();
            for (int i = 0; i < allBounds.Count; i++)
            {
                boundAreas.Add( (int)(GeometryHelper.Area(allBounds[i], out XYZ currentCenter) * 100) );
            }

            if (boundAreas.Sum() > totalArea)
            {
                List<int[]> results = SumUpRecursivly(boundAreas, totalArea, new List<int>());
                for (int i = 0; i < results.Count; i++)
                {

                    if (results[i].Length == 0)
                        continue;

                    int[] r = results[i];
                    for (int ii = 0; ii < r.Length; ii++)
                    {
                        int index = boundAreas.IndexOf(r[ii]);
                        boundAreas.RemoveAt(index);
                        allBounds.RemoveAt(index);

                    }
                    return allBounds.ToArray();
                }

            }

            return allBounds.ToArray();
        }

/// adaptiation of: https://stackoverflow.com/questions/4632322/finding-all-possible-combinations-of-numbers-to-reach-a-given-sum
        private static List<int[]> SumUpRecursivly(List<int> numbers, int target, List<int> partial)
        {
            int s = 0;
            foreach (int x in numbers) s += x;
            foreach (int x in partial) s -= x;

            int diff = Math.Abs(s - target);

            if (Math.Abs(s - target) < 10 )
            {
                return new List<int[]> { partial.ToArray() };
            }

            if (numbers.Count == 0 || s < target)
            {
                return new List<int[]> { new int[0] };
            }

            List<int[]> results = new List<int[]>();
            for (int i = 0; i < numbers.Count; i++)
            {
                List<int> remaining = new List<int>();
                int n = numbers[i];
                for (int j = 0; j < numbers.Count; j++)
                {
                    if (j != i) remaining.Add(numbers[j]);
                }

                List<int> partial_rec = new List<int>(partial) { n };
                results.AddRange(SumUpRecursivly(remaining, target, partial_rec));

            }
            return results;
        }

Re: Is the first Edgeloop still the outer loop?

$
0
0

Thank you for the nice idea.

 

However, I am not immediately convinced...

 

Imagine a situation with many rooms, many of which have holes.

 

Imagine that many of the holes are the exact same size as many of the other rooms.

 

How do you tell them apart, if all you consider is their area?

 

Re: Is the first Edgeloop still the outer loop?

Re: room boundingbox and offset problem

Re: Is the first Edgeloop still the outer loop?

$
0
0

Search the Revit API DLLs for something named IFC. I think the namespace is

 

using Autodesk.Revit.DB.IFC;

 

Re: Problems setting all family instance symbols to another family symbol

$
0
0

I'm not sure you are going to be able to do what you want to do without some extra work. 

 

I think Jeremy's usual quote probably applies here:  If you can't do it with the Revit User Interface, you probably can't do it with the API.

 

So for example, the Revit user interface will allow us to change one electrical device family to another electrical device family.  However, it will not allow me to change an electrical device to another type of family, like a light switch family, for example.  

 


So it seems the Revit API is the same way:  I can use the code below to change one electrical device family to another device family, but I cannot change the family types with the code below - I get an error message.

 

(Changing one device family to another seems kind of trivial, since we can also do this with the user interface by picking one element, choosing "Select All Instances", or "Select All Instances in Current View", and just using the family properties window to select another family.)

 

// to keep things simple, this code just takes all the selected elements and changes them to the same ID as
//the first selected element. It assumes that at least 2 elements are selected before running this code.
// Get the element selection of current document Selection selection = uidoc.Selection; //store element id's ICollection<ElementId> selectedIds = uidoc.Selection.GetElementIds(); ElementId id1 = selectedIds.First(); Element e1 = doc.GetElement(id1); ElementId myid1 = e1.GetTypeId(); TaskDialog.Show("The Type ID to Change Everthing to is;", myid1.ToString ()); foreach (ElementId id in selectedIds) { Element e = doc.GetElement(id); Transaction trans = new Transaction(doc, "Change Element" ); trans.Start(); e.ChangeTypeId (myid1); trans.Commit (); }// end foreach

 

However, I haven't tried this with the API, but it seems like we can work around the limitation in the following way:

 

1.  Select an element to change.

2. Edit the family and save as a new temporary family name (so we don't mess up the existing family).

3.  Change all the elements to the new temporary family.

4.  Edit the temp. family again, and change the family type to the new type.  (For example, change from electrical devices to lighting devices.)

5.  Load the new changed family into the project, overwriting all the existing element parameters.

6. Now we have all the elements of the right type, so we can use ChangeTypeId to change all the elements to the desired family type or symbol.

7.  Clean up the file by deleting the temporary family we made.

 

I'm going to try this when I have time.  Hopefully, all the required steps are available via the API.

 

 

Efficient way to check if an element exists in a view

$
0
0

I'm creating a list of views that contain .dwg ImportInstance(s). For each view in the document, I'm using a FilteredElementCollector to get a list of elements meeting the criteria; if the list of elements meeting the criteria is not empty, then the view is added to the list:

foreach (Element viewElement in viewElements)
            {
                View view = (View)viewElement;
var stopwatch = new Stopwatch(); stopwatch.Start(); List<Element> elementsInView = new FilteredElementCollector(doc, view.Id).OfClass(typeof(ImportInstance)).Where(e => e.Category.Name.EndsWith(".dwg")).OfType<Element>().ToList(); stopwatch.Stop(); Debug.WriteLine(view.Name + ": " + stopwatch.ElapsedMilliseconds + "ms"); if(elementsInView.Count > 0) //if the current view contains at least 1 DWG ImportInstance, then the view is added to the list { viewsWithCAD.Add(view); continue; } }

The FilteredElementCollector can understandably take an upwards of 4000ms to collect elements from a view containing many elements. My goal is only to see if a single element exists in a view--not to collect all of the elements meeting the criteria; if I could make the FilteredElementCollector stop immediately after finding an element meeting the criteria, that would be helpful. 

 

I would appreciate any advice on how to achieve this more efficiently.

 

Thank you.

PostableCommand issues

$
0
0

 

The following code creates exceptions in 2018, 2019, and 2020

foreach (var command in (PostableCommand[])Enum.GetValues(typeof(PostableCommand)))
            {
                var commandId = RevitCommandId.LookupPostableCommandId(command);
            }

These are the PostableCommands that fail

 

2018:
PostableCommand.ViewRange

2019:
PostableCommand.PublishDGNToAutodeskBuzzsaw
PostableCommand.PublishDWFToAutodeskBuzzsaw
PostableCommand.PublishDWGToAutodeskBuzzsaw
PostableCommand.PublishDXFToAutodeskBuzzsaw
PostableCommand.PublishSATToAutodeskBuzzsaw
PostableCommand.ViewRange

2020:
PostableCommand.DrawOnFace
PostableCommand.DrawOnWorkPlane
PostableCommand.PublishDGNToAutodeskBuzzsaw
PostableCommand.PublishDWFToAutodeskBuzzsaw
PostableCommand.PublishDWGToAutodeskBuzzsaw
PostableCommand.PublishDXFToAutodeskBuzzsaw
PostableCommand.PublishSATToAutodeskBuzzsaw
PostableCommand.ViewRange

 

Also, the static method RevitCommandId.LookupCommandId returns null for every command

foreach (var command in Enum.GetNames(typeof(PostableCommand)))
            {
                var commandId = RevitCommandId.LookupCommandId(command);
                if (commandId != null)
                    Debugger.Break();  //This line is never reached
            }

Re: Problems setting all family instance symbols to another family symbol

$
0
0

Thanks for the replies folks, I am going to switch to changing the element id and set the types. For those families with different categories I may try that temporary family solution you mentioned Steve, thanks for the tip. I will post back once Ive updated and tested my code. Appreciate it y'all, you guys rock!

Simple user input

$
0
0

Hi there. I got this plugin that needs a simple string input by the user. I thought this was gonna be an easy task using something like TaskDialog but I haven´t found anything on the API or this forum to make this. I know that I can use windows form but I was wondering if there is something in the Revit API that I can use for this task so I can avoid using windows form and also be able to use this as a macro.

Thanks you. Regards.

Re: PostableCommand issues

$
0
0

I can replicate the exceptions you are getting from the first portion of code that you posted. 

 

  • The exceptions from Revit 2019 and Revit 2020 regarding Buzzsaw makes sense to me, as the  Buzzsaw service is no longer active. It has been replaced by BIM360 docs, and the "Publish" feature has been removed from these versions of Revit. Perhaps  could ask the development team if there are plans to remove these values from the PostableCommand enumeration in the future.
  • I can replicate the exceptions regarding DrawOnFace, DrawOnWorkPlane, and ViewRange, but do not have an explanation to offer you.

 

Regarding the second portion of your post, I believe the null values you are getting are the expected and correct outcome of the code you posted. The RevitCommandId.LookupCommandId() method does not take in the names of PostableCommands, but rather the string values of the names of the internal commands that Revit uses, i.e. the output of the LookupPostableCommandId method, the names of which look like this:

 

ID_CREATE_GUIDE_GRID
ID_CREATE_ASSEMBLY
ID_STAIRS_TRISER_NUMBER
ID_MANAGE_CONNECTION_TO_A_REVIT_SERVER_ACCELERATOR
ID_PHOTO_RENDER_IN_CLOUD
ID_PHOTO_RENDER_GALLERY
ID_ENABLE_ENERGY_ANALYSIS
ID_DISPLACEMENT_CREATE
ID_SETTINGS_ASSEMBLY_CODE
ID_TOGGLE_FABPART_BROWSER
ID_PLAYLIST_DYNAMO

Per the RevitAPI documentation, you can get these string values from Revit Journal files, or, if they pertain to a PostableCommand, you can output them with an augmentation to your own code:

 

foreach (var command in (PostableCommand[])Enum.GetValues(typeof(PostableCommand)))
     {
          var commandId = RevitCommandId.LookupPostableCommandId(command);

          Debug.Log(commandId.Name)
          //or whichever way you prefer to collect and display these names
     }

Hope this helps!

 

 

Re: Simple user input

$
0
0

Hi  ,

 

I guess the simplest way is to create a WinForm with textbox for users to input.

But if you really try to avoid using WinForm as much as possible, there is a workaround, you can try to add a textbox in your ribbon panel by adding code below:

TextBoxData itemData1 = new TextBoxData("itemName1");
Autodesk.Revit.UI.TextBox item1 = ribbonPanel.AddItem(itemData1) as Autodesk.Revit.UI.TextBox;
item1.Value = "Input something here...";
item1.ToolTip = itemData1.Name; // Can be changed to a more descriptive text.
Uri uriImage = new Uri(@"path of the image");
BitmapImage Image1 = new BitmapImage(uriImage);
item1.Image = Image1;
item1.ShowImageAsButton = true;
item1.EnterPressed += CallbackOfTextBox;

And your event:

public void CallbackOfTextBox(object sender, Autodesk.Revit.UI.Events.TextBoxEnterPressedEventArgs args)
{
	Autodesk.Revit.UI.TextBox textBox = sender as Autodesk.Revit.UI.TextBox;

	TaskDialog.Show(textBox.Value.ToString(), textBox.Value.ToString());
}

 

2019-12-07_12-39-31.png

 

Though I don't think it's a good way, and maybe there are some more ways to do but right now I can only think of this.

Hope this helps.

 

Re: Sometimes  Use Rebar API SetHookOritentation methond is invalid

Viewing all 66664 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>