Copy and Place Light Fixtures

Copy and Place Light Fixtures

sragan
Collaborator Collaborator
2,846 Views
7 Replies
Message 1 of 8

Copy and Place Light Fixtures

sragan
Collaborator
Collaborator

I have a macro that places copies of a light fixture on a lighting plan.  It works great if the light to be copied is a face based light that is placed on a ceiling grid using the "Place on Face" option.  The copies are placed on the same ceiling grid.  

 

However, it doesn't work if the original light fixture is placed on a level using the "Place on Work Plane" option.   I know I need to use a different overload for placing these lights, but I have tried multiple times, and I can't figure out how to get this to work.  Can anyone help?

 

For the lights placed on a ceiling grid, I use this to get the host face:

Reference hostFace = lightFamilyInstance.HostFace;

Then to place the lights I use this overload:

FamilyInstance lightFamilyInstance2 = doc.Create.NewFamilyInstance(hostFace, pointtoplace, rotation,lightFamilySymbol );

 

How do I modify these two lines to make then work for a light fixture placed on a level?  I know from stepping through the code that for the lights placed on a level, hostFace remains null.  I've tried changing that line to 

Element host = lightFamilyInstance.Host;

but I can't find any way to insert a light using the host, and I can't figure out how to get a hostFace from that element.

0 Likes
2,847 Views
7 Replies
Replies (7)
Message 2 of 8

Sean_Page
Collaborator
Collaborator

You can get the Reference of the plane.

ReferencePlane plane1 = **get plane;
FamilyInstance fi = Doc.Create.NewFamilyInstance(plane1.Reference, XYZ.Zero, refDir, fs);

 

https://forums.autodesk.com/t5/revit-api-forum/family-instance-on-reference-plane-with-api/td-p/4962...

Sean Page, AIA, NCARB, LEED AP
Senionr Partner, Computational Designer, Architect
0 Likes
Message 3 of 8

stever66
Advisor
Advisor

I assume “** get plane” is shorthand for whatever code I am using to get the reference plane?

 

That seems to be the part I’m having trouble with.  The light to be copied is placed on a level, not a reference plane.   

I think I’ve finally found a way to get this level using get built up in parameter, but any attempt to cast the level to a reference plane fails.

 

 

0 Likes
Message 4 of 8

Sean_Page
Collaborator
Collaborator

If the "host" isn't a plane or a face, then why not use one of the other overloads for placing family instances?

 

Inserts a new instance of a family into the document, using a location, type/symbol and a base level.

NewFamilyInstance Method (XYZ, FamilySymbol, Level, StructuralType) 

 

Inserts a new instance of a family into the document, using a location, type/symbol, the host element and a base level.

NewFamilyInstance Method (XYZ, FamilySymbol, Element, Level, StructuralType)

 

Sean Page, AIA, NCARB, LEED AP
Senionr Partner, Computational Designer, Architect
0 Likes
Message 5 of 8

sragan
Collaborator
Collaborator

I have tried.  In fact, I've spent hours trying every combination under the sun.  Nothing I've tired works.

 

Now I realize there are actually 3 different situations;   A light fixture hosted to a face (a ceiling grid, for example), a light fixture hosted to a level, or a light fixture hosted to a reference plane.  See the attached image for examples.

 

As I've mentioned, I've got the first case working using some example code I found, but the last two cases completely escape me.   I'm sure other people would also be interested in seeing a example of how to do this.

 

I'm using Revit 2021, by the way.

 

0 Likes
Message 6 of 8

timlove
Advocate
Advocate

For what we do I don't care much for the host of the family, we just need it to be the right location in 3d. (not having a way to copy monitor ceilings has driven this problem too)  For that I grab the origin point, then place a family on the current level with it's origin at the same point.  None of our light fixtures are surface based.  Through some fun trickery you can also get the rotation and get them to align as well.  

0 Likes
Message 7 of 8

sragan
Collaborator
Collaborator

Still no luck using NewFamilyInstance to copy a light fixture and having the copy hosted to a level or a reference plane. 

 

However, I did manage to copy a light to a specific location using:

 

doc.Create.NewFamilyInstance(XYZ point, lightFamilySymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural)

 

I also found I could get the result I wanted by using the ElementTransformUtils.CopyElements(doc, selectedIds, point).   

 

That will copy a light hosted to either a level or a reference plane, and will make the copy hosted to the same level or reference plane.  That's exactly what I was trying to do.

 

 

0 Likes
Message 8 of 8

sragan
Collaborator
Collaborator

Apparently the "PointToPlace" parameter works different for the NewFamilyInstance then it does for the CopyElement routine. 

 

No big deal, for the CopyElement case I just need to subtract the Elements LocationPoint from the point I want the lights.   

 

However, I can't get the elevation to work right for all cases.   It works fine for the NewFamilyInstance method.  But for a  level based light and the CopyElement method, I have to also subtract the "BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM" from the point I want the lights,  or my copied lights wind up at twice the height as the original.


But even that doesn't work for lights hosted to a reference plane.   I can't seem to figure out how to keep them from winding up at twice the height as their original.

0 Likes