Hi,
I am using the PromptForFamilyInstancePlacement to place a light fixture and the placement method is set to "Place on Vertical Face" by default always and cannot find any way to change it.
Is it possible to change it, programatically or not?
I can create a new command to place a 'work plane based' family, but by default the placement mode is set to 'face', meaning there is no way to actually place the family instance on the work plane. For example, when working with Linked Autocad files on a work plane (level), everything works from the menu's but since there doesn't seem to be any way to change the placement mode to 'Work Plane", it seems like you can't use the SDK for family placement of 'work plane' based families.
I'm using PromptForFamilyInstancePlacement(symbol).
http://thebuildingcoder.typepad.com/blog/2010/06/place-family-instance.html
If anyone has a work around, I woud really appreciate it.
As a work around, to insert an instance on a work-plane, I've had some mild success with the following approach:
XYZ pickPoint = rvtUiDoc.Selection.PickPoint("Click to specify instance location"); Level lvl = m_rvtDoc.ActiveView.GenLevel; FamilyInstance familyInstance = null; using (Transaction t = new Transaction(m_rvtDoc, "Place Instance")) { t.Start(); familyInstance = m_rvtDoc.Create.NewFamilyInstance(pickPoint, familySymbol, lvl, lvl, StructuralType.NonStructural); t.Commit(); }
The inserted instances act differently than instances placed from the UI. You can't rehost the new API instance, or change the workplane like you can with UI inserted family items.
This also isn't near as nice as the PromptForFamilyInstancePlacement, since you can't see the item until it is placed or align the item to a line/wall with the spacebar like you can with the PromptForFamilyInstancePlacement method.
Hi Skootamota,
Have you tried this with work planes at arbitrary inclinations (ie not horizontal). I can't get the orientation to work, the instance remains with a horizontal alignment.
Being able to create instances on a work plane from the API (as you can with the User Interface) is something I would also really like Autodesk to enable.
Cheers,
Jon
HI Guys.
I did stumble on a nasty work around hack that let you chose through the UI what work plane to host your family on. The trick to it is to run "PromptForFamilyInstancePlacement" outside of the current API command context. I do this by setting up a timer and running it from within that.
Its nasty but that is the only way I have found to do it. Its also a wonder it works and no doubt it will be shut down in the future. Just hopefully they provide a solution to this before they do it.
Here is a short video of it working - https://dl.dropboxusercontent.com/u/7827802/bike.wmv
Cheers
Phillip
Hi
I notice this post is quite old, I too have recently hit a brick wall with the same problem, wanting to insert a face based family on a horizontal face using the API. (it seems ridiculous that there is no method to do this, even the latest 2015 API only introduces an override for placing an air terminal on a duct)
has anyone ever anyone ever solved this?
I would also be interested in how you go about coding the "nasty" work around posted by PhillipM (would it be possible for you to post a code example)
rergards
Paul M
HI Paul M.
If you are working in Revit 2015, the Revit 2015 API does actually allow you to do just what you want, although not using "PromptForFamilyInstancePlacement".
Look into
It is very powerfull.
Regards Phillip
Dear Phillip,
Thank you very much for pointing that out.
Are you aware of any samples using it anywhere?
If you have any, or know of any, I would love to publish them to enhance their visibility.
Thank you!
Cheers,
Jeremy
Hi Jeremy.
I do have a small sample lying around here somewhere that it tested last year during beta testing. I will see if I can dig it up over the weekend.
Cheers
Phillip
Thanks Phillip
I have looked up UIDocument.PostRequestForElementTypePlacement but without an example (as Jeremey has requested) it is difficult to know how this command is implemented
This command does not actually have arguments for placing a family instance, and the documentation states that it differs to PromptForFamilyInstancePlacement() so I assume its not some sort of modifier for the UI behaviour that can be used in conjunction with PromptForFamilyInstancePlacement() . My best guess is that you would have to call an inbuilt command with UIApplication.PostCommand() and somehow pass an argument to that (in my case the family type).
I eagerly look forward to seeing an example of how this could be used.
regards
Paul Marsland
Sorry I'm not in front of VS to test this but from memory you have to set the default Family ID first using "SetDefaultFamilyTypeId" before you call "PostRequestForElementTypePlacement".
Its late Friday night now but I will look into this more during the weekend.
Cheers
Phillip
HI.
I have just had a real quick play with this.
Belows code get the elementType for a Face BAsed family that is know to be in the current project - ("SE-Exercise-Elliptical Machine-UH") and then inserts it with the ability to choose the workplane etc.
The code could be shortened with the remaoval of the for loop and a better filter, but it does show this works pretty well.
Cheers
Phillip
Imports Autodesk Imports Autodesk.Revit.DB Imports Autodesk.Revit.UI Imports Autodesk.Revit.ApplicationServices Imports System.IO <Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)> _ <Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)> _ <Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)> _ Public Class extCmd Implements IExternalCommand Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute Dim app As Autodesk.Revit.UI.UIApplication = commandData.Application Dim typeCol As FilteredElementCollector = New FilteredElementCollector(app.ActiveUIDocument.Document).OfClass(GetType(ElementType)) Dim eleType As ElementType = Nothing For Each eleT As ElementType In typeCol If eleT.Name = "SE-Exercise-Elliptical Machine-UH" Then eleType = eleT Exit For End If Next app.ActiveUIDocument.PostRequestForElementTypePlacement(eleType) Return Result.Succeeded End Function End Class
Phillip
Many Many Thanks for all your help on this I have incorporated this into my application and it works a treat.
Whilst I was playing around with alternative ways of inserting families I came up with a method that uses 'NewFamilyInstance' I was able to code this so I can automatically move and rotate families into the centre of a ceiling tiles if the families have been defined with a central insert point. (I have also got this working on rotated ceiling grids)
I am keeping both methods in my app (I have an xml file that configures the libraries displayed and have added an attribute that can be used to select the insert method that best suits the family), What I cannot work out is how to select the nearest face using one of the selected points on the ceiling grid. I have to pick the grid and then two points that represent the tile intersections, this requires 3 clicks.
I don't suppose you (or any other readers) have any ideas as to how the nearest face could be selected from a point selection (using pickpoint). It seems such a simple thing to want to do but I have searched the API help files and web but found nothing.
regards
Paul Marsland
HI Paul.
Great that it works for you. It is very powerful, as it not only works for rfa families but system families and everything else, which is awesome for our apps.
I'm not sure I totally understand your requirements, but can you not.
I haven't looked through Revit lookup to see the properties of the ceiling grid but surly the panels are accessible? I'm assuming that is the issue you are having?
Regards
Phillip
Phillip,
If you could provide some code as to how you got the Timer to work that would be fantastic. I've tried moving the ActiveUIDocument and Symbol to class variables and then setting a timer to run 1 second later, but that just does nothing. Perhaps it no longer works in Revit 2014?
EDIT: I actually noticed that in your video you used 2014, so I know it must be possible. I realize that the 2015 way is better, but unfortunately the company I'm working with is stuck with '14 for the time being.
HI.
Yes it still defiantly works in Revit 2014.
Basically I start the timer before the dragDrop event and then once I find an existing symbol in the current document or have to load a family I set a global Boolean var to true which in turn cranks in the timer code.
I hope it makes sense?
If Tmr_FamdroppedWorkaround.Enabled = True Then Tmr_FamdroppedWorkaround.Stop() End If
Tmr_FamdroppedWorkaround.Start() Autodesk.Revit.UI.UIApplication.DoDragDrop(mod_Vars.selectedNodeVar, iDropevent)
Private Sub Tmr_FamdroppedWorkaround_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Tmr_FamdroppedWorkaround.Tick
If famDropped2014 = True Then
famDropped2014 = False
Tmr_FamdroppedWorkaround.Stop()
Try
currentApp.ActiveUIDocument.PromptForFamilyInstancePlacement(fs)
Catch ex As Exception
End Try
End If
End Sub
The new 2015 PostRequestForElementTypePlacement() may work, but it is still a pain to have to select the ribbon menu every time you pick a new family (to select the workplane option).
If a user creates shortcuts to place families (for instance a receptacle, or fire alarm device), they may switch back/forth between families, but they still have to select the ribbon 'Workplane' option every single time a new family is chosen, which is a total pain.
Am I missing something, or is there a way to do this without having to go to the ribbon to change the placement option to 'Place On Work Plane' for every new family selection? On a large project, this could result in hundreds, if not 1000's of extra selections up to the ribbon, just to select an option that I may always want (ie: wireframe model with CAD, makes sense to always use 'Work Plane' with a work plane based family).
Dear Phillip,
Thank you for the nice and succinct sample code!
Since it was lacking, I added it to The Building Coder and its GitHub samples as well:
http://thebuildingcoder.typepad.com/blog/2015/03/postrequestforelementtypeplacement.html
Cheers,
Jeremy
Just wondering if you ever solve the problem with having user to select different ribbon in order to place element in model?