check if linepattern is in use

check if linepattern is in use

dante.van.wettum
Advocate Advocate
3,290 Views
16 Replies
Message 1 of 17

check if linepattern is in use

dante.van.wettum
Advocate
Advocate

Is there a way to check if an given linepattern is in use ?

i couldnt find any method or member for the LinePatternElement class.

 

The only thing i can really think of now is to make a filteredelementcollector of LinePatternElements, and make another collector of all Lines within the model, and for each line check the pattern that is beeing used.

Then i can crosscheck these 2 lists and purge all unused  linepatterns from my project (in one of my projects i have 964 linepatterns now dus to all kind of imports).

 

Only problem i see here is that i think it will not check the linepatterns used by linked (dwg) files...

 

Any thoughts on this ?

0 Likes
Accepted solutions (1)
3,291 Views
16 Replies
Replies (16)
Message 2 of 17

hugha
Collaborator
Collaborator

Much of what you ask appears  to be handled by this Exchange Add-In that you may be able to coax into action for later Revit versions (in-link comments hint at being able to address this) which may solve your problem directly.

 

Another Add-in addressing much the same function.

 

hope this helps,

 

Hugh Adamson

www.hatchkit.com.au

 

 

 

 

 

 

 

 

 

0 Likes
Message 3 of 17

Revitalizer
Advisor
Advisor

Hi,

 

what about just trying to delete each of your LinePatternElements?

 

If an Element is referenced and still needed, i would assume it cannot be deleted at all.

 

The brute force approach...

 

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 4 of 17

dante.van.wettum
Advocate
Advocate

@hughaFor my company we have our own ribbon with many tools, therefore i rather code it into our own toolbar instead of using third party addins.

 As you can see with many of these addins (including the ones you linked) is the support for future versions is lacking, and they dont get updated anymore.

Furthermore, both of those tools only delete all the patterns that start with "IMPORT-" instead of purging unused.

Just deleting based on a string starting with a value isnt the problem and is coded in 5 minutes.

 

@Revitalizer If you delete a linepattern that is in use, it will end up using the Continues line pattern type instead of the one that was in use.

0 Likes
Message 5 of 17

Revitalizer
Advisor
Advisor

Ah, I feared that.




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 6 of 17

FAIR59
Advisor
Advisor

Also this method ( collect lines )  will not find the patterns used in Visibility / Graphics overrides.

 

I think you need a ttt (temporary transaction trick). If deleting in use linepatterns alters patterns to continuous, then in a DocumentChangedEvent this should be reported.

 

workflow:

subscribe to DocumentChangedEvent

start transactiongroup

 

foreach linepattern

    start transaction

    delete linepattern

    check DocumentChangedEventArgs.GetModifiedIds().Count==0

           if TRUE  linepattern is not in use

 

rollback transactiongroup

 

 

 

Message 7 of 17

dante.van.wettum
Advocate
Advocate

@FAIR59

I really like that way of thinking! Will give it a go 🙂 than you a lot for sharing your thoughts on this.

0 Likes
Message 8 of 17

aignatovich
Advisor
Advisor

It could be achieved a little bit easier

 

foreach linepattern

    start transaction

    delete linepattern -> document.Delete method returns the Ids of deleted elements. Put it to the ids list

    rollback transaction
    
    get elements from database (some elements are internal, and document.GetElement method will return null)

Message 9 of 17

dante.van.wettum
Advocate
Advocate

@aignatovich

But lines are not getting deleted, only the property changes when its associated linepattern is deleted.

The element you delete is the DB.LinePatternElement

 

i'll give it a try, but i doubt if that will work as intended. I think it will give the ID's back from the LinePatternElement, so this is no guarantee if its is in use by the project or not.

0 Likes
Message 10 of 17

so-chong
Advocate
Advocate
Accepted solution

Hi, i'm not sure if this macro is what your looking for....it will delete unused line patterns.

It can take a while before the macro have completed the action.

 

Good luck!

 

/*
 * Created by SharpDevelop.
 * User: S. Li
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Collections.Generic;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.ApplicationServices;

namespace MacroFromInternet
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("CBE2490D-447D-4713-9EA4-789F888A1672")]
	public partial class ThisApplication
	{
		private void Module_Startup(object sender, EventArgs e)
		{

		}

		private void Module_Shutdown(object sender, EventArgs e)
		{

		}

		#region Revit Macros generated code
		private void InternalStartup()
		{
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
		}
		#endregion
 
		public static int modifiedByDeleteLinePattern = 0;
		public static bool checkForPurgeLinePatterns = false;
		public static Document _doc = null;
		public static string LinePatternName = "";
		public void purgeUnusedLinePatterns()
		{
		    Document doc = this.ActiveUIDocument.Document;
		    _doc = doc;
		    Application app = doc.Application;
		    app.DocumentChanged += documentChanged_PurgeLinePatterns;
		    List<Element> LinePatterns = new FilteredElementCollector(doc).OfClass(typeof(LinePatternElement)).ToList();
		    string deletedLinePatterns = "";
		    int unusedLinePatternCount = 0;
		    foreach (Element LinePattern in LinePatterns)
		    {
		        modifiedByDeleteLinePattern = 0;
		        LinePatternName = LinePattern.Name + " (id " + LinePattern.Id + ")";
		        using (TransactionGroup tg = new TransactionGroup(doc, "Delete LinePattern: " + LinePatternName))
		        {
		            tg.Start();
		            using (Transaction t = new Transaction(doc, "delete LinePattern"))
		            {
		                t.Start();
		                checkForPurgeLinePatterns = true;
		                doc.Delete(LinePattern.Id);
		                
		                // commit the transaction to trigger the DocumentChanged event
		                t.Commit();
		            }
		            checkForPurgeLinePatterns = false;
		            
		            if (modifiedByDeleteLinePattern == 1)
		            {
		                unusedLinePatternCount++;
		                deletedLinePatterns += LinePatternName + Environment.NewLine;
		                tg.Assimilate();
		            }
		            else // rollback the transaction group to undo the deletion
		                tg.RollBack();
		        }
		    }
		    
		    TaskDialog td = new TaskDialog("Info");
		    td.MainInstruction = "Deleted " + unusedLinePatternCount + " LinePatterns";
		    td.MainContent = deletedLinePatterns;
		    td.Show();
		
		    app.DocumentChanged -= documentChanged_PurgeLinePatterns;
		}
		
		private static void documentChanged_PurgeLinePatterns(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
		{
		    // do not check when rolling back the transaction group
		    if (!checkForPurgeLinePatterns)
		    {
		        return;
		    }
		    
		    List<ElementId> deleted = e.GetDeletedElementIds().ToList();
		    List<ElementId> modified = e.GetModifiedElementIds().ToList();
		    
		    // for debugging
		    string s = "";
		    foreach (ElementId id in modified)
		    {
		        Element modifiedElement = _doc.GetElement(id);
		        s += modifiedElement.Category.Name + " " + modifiedElement.Name + " (" +  id.IntegerValue + ")" + Environment.NewLine;
		    }
		    //TaskDialog.Show("d", LinePatternName + Environment.NewLine + "Deleted = " + deleted.Count + ", Modified = " + modified.Count + Environment.NewLine + s);
		    
		    // how many elements were modified and deleted when this LinePattern was deleted?
		    // if 1, then the LinePattern is unused and should be deleted
		    modifiedByDeleteLinePattern = deleted.Count + modified.Count;
		}
	}
}
Message 11 of 17

jeremytammik
Autodesk
Autodesk

Thank you guys for the great topic and interesting suggestions!

 

I will certainly add this to the blog asap. 

 

It fits in well with previous discussions on purging things, cf. the links provided here:

 

http://thebuildingcoder.typepad.com/blog/2017/04/forgefader-ui-lookup-builds-purge-and-room-instance...

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 12 of 17

stingers80-cgarchitect
Advocate
Advocate

Hi!

I was wondering if you could find a solution to this. I am trying to do the same thing with purging Line patterns...

 

Thanks

0 Likes
Message 13 of 17

jeremytammik
Autodesk
Autodesk

The solution is described above, and code is provided. 

 

Have you tried that out?

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 14 of 17

stingers80-cgarchitect
Advocate
Advocate

I tried it yesterday. It works!

It wasn't marked as solution that's why I hadn't tried it.

Message 15 of 17

c_galue
Explorer
Explorer

Hi! I was wondering if someone could guide me towards a way to run this macro, I've being trying to run it but it give me 2 errors when I try to build it.

2023-02-02_15h14_24.png

'GestionBIM.ThisDocument' ne contient pas une définition pour 'ActiveUIDocument' et aucune méthode d'extension 'ActiveUIDocument' acceptant un premier argument de type 'GestionBIM.ThisDocument' n'a été trouvée (une directive using ou une référence d'assembly est-elle manquante ?) (CS1061) - C:\Users\c.galue\AppData\Local\Temp\48587f00-66a5-4c4b-a02e-41d94d3abf41\Revit\DocHookups88568\2740154955264\GestionBIM\Source\GestionBIM\ThisDocument.cs:46,27

 

Learing the ropes here, so I'm sorry if my question is a bit amateur. Also, I'm in Quebec, that might be why my error is biligual.

 

Thanks,

0 Likes
Message 16 of 17

jeremy_tammik
Alumni
Alumni

Congratulations on giving it a go and learning the ropes. I think the most effective way forward in your situation might be to take a quick look and work through a short tutorial or video on getting started with Revit macros. There are lots of them on YouTube and elsewhere in the web. Every such tutorial will explain exactly what things like ThisDocument and ActiveUIDocument are, their purpose, and how to access and use them. With that knowledge and understanding, you will easily be able to grok and solve the task you face. Good luck and have fun!

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 17 of 17

frankloftus
Contributor
Contributor

@c_galue, I think you need to create the macro as an application-level macro. If you create it as a document-level macro, it will give you an error about 'ActiveUIDocument' not having a definition.

 

Also, in my experience, this macro works well to delete line patterns that are not used by any linetypes, but in my testing, it deleted line patterns that were in use as pipe system overrides. I'm guessing that changing a pipe system override does not trigger a DocumentChanged event?

 

This could be solved by checking against a list of line patterns used as pipe system graphic overrides, but there are many different overrides in a document. How do you check all overrides without tracking down every single type of override available through the API? Even if you successfully handled each override, there would still be the question of RVT link overrides, which are not accessible through the API.

 

In the end, I settled for deleting all line patterns containing "IMPORT". This was good enough for me. I am mostly certain these are not used in my project, but I cannot be sure.

0 Likes