Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Copying and overwriting types between projects

25 REPLIES 25
SOLVED
Reply
Message 1 of 26
JonSmith
9477 Views, 25 Replies

Copying and overwriting types between projects

Is there a way to copy wall types from one model to another - overwriting any duplicates? I'm sure this must have been asked before, but I cannot find anything.

 

 - The built-in Transfer Project Standards has this functionality but no direct API.
 - ElementTransformUtils.CopyElements works great but does not allow overwriting existing types - if the type already exists it renames it.
 - LoadFamily does allow overwriting types, but only applies to family documents.

 

Is there another way that combines the best of those methods (or something I'm missing on one of the above methods)?

 

Thanks

Jon Smith

25 REPLIES 25
Message 2 of 26
Scott_Wilson
in reply to: JonSmith

You could probably try reading off the data from the existing wall type and recreate in new project. I think I've done it with roof types before.
Message 3 of 26
JonSmith
in reply to: Scott_Wilson

That would work for given types, but I really need it to work for any family or type - be it a wall, door, furniture, etc. As the UI allows for it in Transfer Project Standards, I'm hoping there is some way to replicate in the API.

Message 4 of 26
akira.kudo
in reply to: JonSmith

Hi,

 

Unfortunately there is no API that can copy elements or types directly from one document to another at this time.
We can only duplicate new types within the same document. We cannot insert types from one document to another document.

As a workaround, we can create corresponding elements in another document, then copy the parameters or properties one by one via API. For instance, when copy a wall type, we need to use WallType.Duplicate() to create a new wall type with the same name, then set each parameter's value the same as the original wall type.

For example, there are two documents,
docActive: The document that is active
docHide: The document that is created by opening a rvt file or NewProjectDocument() method. It is invisible and cannot be switched to active.

We will to copy one wall type in docHide to docActive. Here is the steps to copy value.
Get one of wall type in docActive, assign to wt1,
Duplicate this type using the target name by wt1.Duplicate(TargetName), and assign to wtExternal,
Retrieve the properties and parameter values from target wall type in docHide, and assign the values to wtExternal in docActive. We can use the reflector mechanism to retrieve and assign property values without knowing the property name. Also we can iterate all parameters in a loop without knowing each parameter name.

Here is an example of the code that is used for same question:

Document doc = _commandData.Application.OpenDocumentFile(fileName);
Document docActive = _commandData.Application.ActiveDocument;

doc.BeginTransaction();

Autodesk.Revit.Symbols.WallType dupWT = null;
foreach (Autodesk.Revit.Symbols.WallType wt in docActive.WallTypes)
{
    dupWT = (Autodesk.Revit.Symbols.WallType)wt.Duplicate(wt.Name + "Dup");
    break; //break here, for we only copy one type.
}

//get the target wall type in doc.
Autodesk.Revit.Symbols.WallType wtTarget = null;
foreach (Autodesk.Revit.Symbols.WallType wt in docActive.WallTypes)
{
    wtTarget = wt
    break; //break here, for we find the target.
}

//copy properties from wtTarget to dupWT.
//We can also assign values via .NET reflector. So we can do this for FloorType, or other any types via the same code.
//For simplicity, I assign two properties here line by line. This requires we know the property name. This is not flexible.
dupWT.Width = wtTarget.Width;
dupWT.Kind = wtTarget.Kind;
...

//copy parameter values from wtTarget to dupWT.
Parameter para= null;
For Each( para in wtTarget.Parameters)
{
    Switch(para.StorageType)
    Case StorageType.Double:
    dupWT.get_Parameter(para.Name).Set(wt.AsDouble);
    Case storageType.ElementId:
    dupWT.get_Parameter(para.Name).Set(wt.AsElementId);
    //and so on for other storage types.
    ...
}

doc.EndTransaction();

I hope this helps.






Akira Kudo

Developer Technical Services

Autodesk Developer Network


Message 5 of 26
R.van.den.Bor
in reply to: akira.kudo

I don't understand Akira's workaround. You are still making a new wall type. That's not what John (and I) want, see post

same kind of question

 

The nice feature of transfer project standards by hand ia you can change a walltype in doc A to the wall type in doc B. That's the ulimate goal, no duplicate, an overwrite. I think Arnošt Löbels workaround is the closest to what we want. This is one feature I hope is high on the wishlist 🙂 

Kind regards,
Remy van den Bor
ICN Solutions B.V.
Liked this post or found it usefull, don't forget the Kudo It won't hurt (at least not me).
Message 6 of 26
Joe.Ye
in reply to: JonSmith

Hi Jon, Revit provides the ElementTransformUtils.CopyElements() method, that can be used to copy types between documents. See this override. public static ICollection CopyElements( Document sourceDocument, ICollection elementsToCopy, Document destinationDocument, Transform transform, CopyPasteOptions options ) Type: Autodesk.Revit.DB..::..Document The document that contains the elements to copy. elementsToCopy Type: System.Collections.Generic..::..ICollection<(Of <(<'ElementId>)>)> The set of elements to copy. destinationDocument Type: Autodesk.Revit.DB..::..Document The destination document to paste the elements into. transform Type: Autodesk.Revit.DB..::..Transform The transform for the new elements. Can be nullNothingnullptra null reference (Nothing in Visual Basic) if no transform is required. options Type: Autodesk.Revit.DB..::..CopyPasteOptions Optional settings. Can be nullNothingnullptra null reference (Nothing in Visual Basic) if default settings should be used.


Joe Ye
Contractor
Developer Technical Services
Autodesk Developer Network
Message 7 of 26
R.van.den.Bor
in reply to: Joe.Ye

We know the APi has ElementTransformUtils.CopyElements() , but the problem is, this will always make a duplicate and what we want is an overwrite. Like your collegue Arnošt Löbel explained, this method doesn't have the option to overwrite.
Kind regards,
Remy van den Bor
ICN Solutions B.V.
Liked this post or found it usefull, don't forget the Kudo It won't hurt (at least not me).
Message 8 of 26
JonSmith
in reply to: JonSmith

@Akira - thanks, but probably not feasible across any given type so the source and destination types are identical (including shared parameters and entities). 

 

@Joe - sorry, while CopyElements is a great step forwards in the API, it does not provide the solution in this case where there are duplicates.

 

@Remy - thanks for linking to your post. It looks like if it has to be a workaround then Arnost's workaround is it.

 

+1 for the wishlist please! It would open up a lot of opportunity for managing standards.

 

Jon

Message 9 of 26
Joe.Ye
in reply to: JonSmith


Hi Jon

There is a workround, I think. After calling CopyElement() method, you can delete the existing type elements, and rename the newly copied type to the name of the just deleted type.

If the duplicate type is used by instance in the model, after call CopyElement() method, assign the newly copied types to instance which used the duplicate type, and then delete the origin type. Finally rename the type back to the origin name.


Joe Ye
Contractor
Developer Technical Services
Autodesk Developer Network
Message 10 of 26
JonSmith
in reply to: JonSmith

Thanks Joe. I've done some experimenting and that does work for simple cases where elements have a given type and you swap its type for another. However, when you start looking at swapping materials, or even wall types where they could be used in legend schedules, it starts getting very brittle. I cannot see a clean way to swap one element type for another.

Message 11 of 26
Joe.Ye
in reply to: JonSmith

Hi Jon, I see the inconvenience and workload of examining so many types, and also the situations of the type referenced by instance objects in the model, and also the legend in the legend view. I just logged an API wish to support the overwrite duplicate types. The ticket number is CF-882. BTW, when a wall type is referenced by a legend, you can also change that legend's referencing type by changing the legend's "Component type" parameter value to the newly copied wall type.


Joe Ye
Contractor
Developer Technical Services
Autodesk Developer Network
Message 12 of 26
JonSmith
in reply to: Joe.Ye

Thanks Joe
Message 13 of 26
markstrom.martin
in reply to: JonSmith

Has there been any update on this? It is now two years later and I haven't been able to find anything about API access to transfer project standards...

Message 14 of 26

Dear Martin,

 

Thank you for raising this issue once again, and for your new thread

 

http://forums.autodesk.com/t5/revit-api/api-access-to-transfer-project-standards-and-overwrite/m-p/6...

 

I am very sorry to say that nothing at all has happened so far with the wish list item CF-882 [Overwrite duplicate types when calling CopyElements() between documents] that you refer to.

 

I created a new, more general wish list item CF-4242 [API wish: transfer project standards] and prompted the development team for some kind of response.

 

I will let you know what I hear back from them.

 

Thank you for your patience and persistence.

 

Best regards,

 

Jeremy



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

Message 15 of 26

Hi Jeremy,

 

Did you ever hear back from the dev team i would also be very interested in this feature.

 

Thanks

Chris

Message 16 of 26
cptdunsail
in reply to: ChrisFraserNBS

Hi,

Can this also be achieved for copy and paste elements, so duplicate types dont appear in the project with a 1 after their name? Users tend to use both and this scrambles the logic of an FFE schedule as they will use a fifty split of the say medical_ref and mnedical_ref1, leading to erroneous schedules.

cheers,

Bren

Message 17 of 26
phil.milecracken
in reply to: Joe.Ye

hi,

What is the best method for collection the types that will need to be swapped, say for eg walls. do you do a comparison between files before copying the elements over as they will be renamed and do the copied types retain their elementid?

Message 18 of 26
jeremytammik
in reply to: cptdunsail

Dear Bren,

 

To handle problems like this, I would suggest enforcing the use of a model checker and adding a test to it that warns users about similar names differing only in trailing numerals.

 

Cheers,

 

Jeremy



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

Message 19 of 26

Dear Phil,

 

The element id is specific to the document.

 

Elements copied from one document to another will definitely not retain their element id.

 

Cheers,

 

Jeremy



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

Message 20 of 26

thanx Jeremmy you are correct,

I had some incomplete method working where i searched on the elementType name +2 and it works for most types except where you get name +1, name + 2, name + 3 and then it appends the names to name + 4, name +5, name +6. So this is no good, i might have to add the source elementype name in the comments and after copying to destination collect on those and match with a dictionary.

if there is a tried and tested robust method please let me know!

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community