Copying and overwriting types between projects

Copying and overwriting types between projects

JonSmith
Advocate Advocate
11,891 Views
27 Replies
Message 1 of 28

Copying and overwriting types between projects

JonSmith
Advocate
Advocate

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

0 Likes
Accepted solutions (1)
11,892 Views
27 Replies
Replies (27)
Message 2 of 28

Anonymous
Not applicable
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.
0 Likes
Message 3 of 28

JonSmith
Advocate
Advocate

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.

0 Likes
Message 4 of 28

akira.kudo
Alumni
Alumni

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


0 Likes
Message 5 of 28

Anonymous
Not applicable

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 🙂 

Message 6 of 28

Joe.Ye
Alumni
Alumni
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
0 Likes
Message 7 of 28

Anonymous
Not applicable
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.
0 Likes
Message 8 of 28

JonSmith
Advocate
Advocate

@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

0 Likes
Message 9 of 28

Joe.Ye
Alumni
Alumni

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
0 Likes
Message 10 of 28

JonSmith
Advocate
Advocate

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.

0 Likes
Message 11 of 28

Joe.Ye
Alumni
Alumni
Accepted solution
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
0 Likes
Message 12 of 28

JonSmith
Advocate
Advocate
Thanks Joe
0 Likes
Message 13 of 28

Anonymous
Not applicable

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...

0 Likes
Message 14 of 28

jeremytammik
Autodesk
Autodesk

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

0 Likes
Message 15 of 28

ChrisFraserNBS
Explorer
Explorer

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 28

Anonymous
Not applicable

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

0 Likes
Message 17 of 28

Anonymous
Not applicable

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?

0 Likes
Message 18 of 28

jeremytammik
Autodesk
Autodesk

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

0 Likes
Message 19 of 28

jeremytammik
Autodesk
Autodesk

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 28

Anonymous
Not applicable

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!

 

0 Likes