Here are two recent questions on electrical settings of distribution systems and family instances for lighting fixtures handled by Saikat Bhattacharya and Joe Ye, respectively.
By the way, this is a special occasion, namely the 200th post to The Building Coder. I will resist the temptation to declare this as a birthday post like I did post number 100, because the first real annual birthday of The Building Coder is coming up quite soon now anyway, and we don't want to exaggerate, do we?
Reading and Writing the Electrical Settings of Distribution Systems
Question: Is there any way to use the Revit API to read and write the data under Electrical Settings, e.g. the Distribution System rows?
Answer: To do a quick check, I used the RvtMgdDbg tool and found out that the active document contains a DistributionSysType container which lists all the distribution systems available from the user interface. Here are the electrical settings displayed in the user interface:
Here, we have selected the DistributionSysType instance using RvtMgdDbg to show the same information as the user interface as accessed through the API:
Thus, the DistributionSysType class might be what you looking for.
Creating Hosted Family Instances for Lighting Fixtures
Question: I am loading a batch of lighting fixtures using .NET but I am having some issues. I programmatically set the host to be the ceiling by using parameters showing that the host is the ceiling when the fixture is loaded. However, the properties of the resulting fixture do not reflect this. Also, the fixture created cannot be copied. In sum, the properties of the fixtures are not the same as the properties of a fixture created manually and inserted by Revit itself. I used the following code to load the fixture:
FamilyInstance inst = doc.Create.NewFamilyInstance( location, symbol, ceil, StructuralType.NonStructural );
In this call, location is the location of the fixture. I set its Z coordinate to zero in order to inherit the host elevation, but this does not work. Symbol is the family symbol to be inserted, and ceil the selected host ceiling.
Answer: I reproduced the issue. Using your method, I found the created light fixture is located above the ceiling, although the Z elevation is the same. The host property is null, as is the parameter value of HOST_ID_PARAM. So I think the issue is caused by the level setting.
I changed the code to use another override of NewFamilyInstance, which takes the level as an argument:Document.NewFamilyInstance( XYZ, FamilySymbol, Element, Level, StructuralType )
The lighting fixture now has a valid host property. Here is the updated code for the Execute method of the external command:
Application app = commandData.Application; Document doc = app.ActiveDocument; Autodesk.Revit.Creation.Filter cf = app.Create.Filter; // get a lighting fixture family symbol: Filter f1 = cf.NewTypeFilter( typeof( FamilySymbol ) ); Filter f2 = cf.NewCategoryFilter( BuiltInCategory.OST_LightingFixtures ); Filter f = cf.NewLogicAndFilter( f1, f2 ); List<Element> symbols = new List<Element>(); doc.get_Elements( f, symbols ); FamilySymbol sym = null; foreach( Element elem in symbols ) { sym = elem as FamilySymbol; // get the first one. break; } if( null == sym ) { message = "No lighting fixture symbol found."; return CmdResult.Failed; } // pick the ceiling: doc.Selection.StatusbarTip = "Please select ceiling to host lighting fixture"; doc.Selection.PickOne(); Element ceiling = null; foreach( Element elem in doc.Selection.Elements ) { ceiling = elem as Element; break; } // get the level 1: ElementIterator it = doc.get_Elements( typeof( Level ) ); Level level = null; while( it.MoveNext() ) { level = it.Current as Level; if( level.Name.Equals( "Level 1" ) ) break; } if( null == level ) { message = "Level 1 not found."; return CmdResult.Failed; } // create the family instance: XYZ p = app.Create.NewXYZ( -43, 28, 0 ); FamilyInstance instLight = doc.Create.NewFamilyInstance( p, sym, ceiling, level, StructuralType.NonStructural ); return CmdResult.Succeeded;
Thank you very much Joe and Saikat for these answers!
Hi Jeremy,
this is a very usueful code if you want to create a new instance and pick a host for it.
however, i am not finding a way to re-host a given fixture through code.
Is there is a way to call the command "Pick new host" (Vertical face, reference plane..)via API?
Please advise as soon as possible on the way to rehost a fixture through code. (to nearest element that intersects it)
Regards
Posted by: Mira Saad | October 11, 2011 at 05:15
Dear Mira,
Thank you, glad you like it.
Unfortunately, I do not see a direct way to programmatically rehost a family instance such as an electrical fixture to a given host, e.g. a wall element.
The only workaround I can think of would be to note the location and family symbol of the family instance, delete it, and create a new one by calling the NewFamilyInstance method with the overload taking the host element argument, using the location and the symbol information extracted from the existing instance before its deletion.
This will create an identical fixture with the host information included.
Cheers, Jeremy.
Posted by: Jeremy Tammik | October 11, 2011 at 06:27
Hi Jeremy,
I tried this workaround & it works great if the host element is in the same file as the lighting fixture.
On the other hand, if the host element which is a wall in my case, is in a linked revit document, then am not able to host the new family instance on the wall's face.
I tried to retrieve the wall's faces, but the faces array returned zero elements as the wall is in a linked file.
Please can you advise on how to create a new family instance hosted on the face of a wall found in a linked document..
Thanks a lot.
Posted by: Mona Akkoush | October 15, 2011 at 05:02
Dear Mona,
Oh dear, with linked files it is a lot trickier. I don't even know if you can host the fixture at all on a wall in a linked file. Is that possible even through the user interface? If not, then it will probably not be possible through the API either.
Cheers, Jeremy.
Posted by: Jeremy Tammik | October 16, 2011 at 08:10
Hi Jeremy,
In Revit, you can host a fixture on the face of a wall in a Revit architectural linked file. Kindly note that I was able to get the side face of the wall where the fixture will be hosted using "HostObjectUtils.GetSideFaces(wall element, ShellLayerType.Exterior)".
Yet, when using the method "NewFamilyInstance(wall element side face as FACE, wall element location curve as Line, fixture symbol as FamilySymbol)" to host the new fixture on the face of the wall element, I get the following error "The Reference of the input face is null.If the face was obtained from Element.Geometry, make sure to turn on the option ComputeReferences". I have checked the reference object in the code & it was not null & the ComputeReferences was set to true.
Please advise..
Best Regards,
Posted by: Mona Akkoush | October 17, 2011 at 04:59
Dear Mona,
I am sorry to say I cannot do much more off-hand since this will probably require some research to answer. Please submit an ADN DevHelp Online case for this. Thank you!
Cheers, Jeremy.
Posted by: Jeremy Tammik | October 17, 2011 at 06:32
Hi Jeremy,
Thanks a lot, I submitted my case to DevHelp.
An aside question, any idea why the retrieved Face object might have a null Reference, taking into consideration that the face is a side-face of a wall found in a linked file.
Thanks in advance,
Best Regards,
Posted by: Mona Akkoush | October 17, 2011 at 08:04
Dear Mona,
Thank you for submitting the case!
I would say that the problem may be that it is in a linked file :-)
Sorry.
Cheers, Jeremy.
Posted by: Jeremy Tammik | October 20, 2011 at 08:08
hi jeremy i tried this code and i can't seem
to make it work
can u send it to me in c# project format
thanks
[email protected]
Posted by: ahmed attia | December 31, 2011 at 06:13
Autodesk.Revit.Creation.Filter
is not recognized by vc#
?????????????
Posted by: ahmed attia | December 31, 2011 at 09:25
sorry for too many posts but i noticed
that some of this functions are not in revit
2010 api can't you update the example to revit 2011 api
thanks
Posted by: ahmed attia | December 31, 2011 at 09:56
after some work i realized this is not exactly
what i want my project was to copy
an ( already loaded lighting fixture) by selecting it
and then selecting the point where it will
be copied and develop it later to lighting distribution plugin
the problem is i can't find a function of copy or anything similar and i don't know if i must provide a host programatically or not but your code for selecting ceiling will work i guess n
now if u can help i'll greatly appreciate it
thanx a lot
[email protected]
Posted by: ahmed attia | December 31, 2011 at 13:13