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: 

Change the placement option for PromptForFamilyInstancePlacement

20 REPLIES 20
Reply
Message 1 of 21
trilulilu
6260 Views, 20 Replies

Change the placement option for PromptForFamilyInstancePlacement

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?

20 REPLIES 20
Message 2 of 21
skootamota
in reply to: trilulilu

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.

 

Message 3 of 21
skootamota
in reply to: skootamota

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.

 

Message 4 of 21
GeomGym
in reply to: skootamota

 

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

Message 5 of 21
PhillipM
in reply to: trilulilu

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

Message 6 of 21
tagbagz
in reply to: PhillipM

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

Message 7 of 21
PhillipM
in reply to: tagbagz

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 

  • UIDocument.PostRequestForElementTypePlacement()

It is very powerfull.

 

Regards  Phillip

Message 8 of 21
jeremytammik
in reply to: PhillipM

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



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

Message 9 of 21
PhillipM
in reply to: jeremytammik

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

Message 10 of 21
tagbagz
in reply to: PhillipM

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

Message 11 of 21
PhillipM
in reply to: tagbagz

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

Message 12 of 21
PhillipM
in reply to: PhillipM

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

 

Message 13 of 21
tagbagz
in reply to: PhillipM

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

 

 

Message 14 of 21
PhillipM
in reply to: tagbagz

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.

  1. Subscribe to the doc changed event.
  2. use PostRequestForElementTypePlacement to place your hosted family to the ceiling grid.
  3. once finshed get the added families from the doc changed event.
  4. Then move them to the centre of the panels.

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

Message 15 of 21
tagbagz
in reply to: PhillipM

Hi Phillip

What I have developed is a dialog interface that presents libraries of families (there will be hundreds of families on different tiles with icons and listbox to allow selection). The tiles are configured via an xml file that specifies the families and other settings.

The families are made up of items that all have different hosting. The 'PostRequestForElementTypePlacement' has now been set as a default method to insert the families and this works fine. Some families however are intended to be inserted on ceiling grids, and depending on the size, shape and insert position of these families it may be preferable to use 'NewFamilyInsert' and calculate the angle of the ceiling grid and tile size so the family can be dropped perfectly into position. I currently have this method working well but it requires the user to make 3 clicks,
1. to select the ceiling grid ( so i can extract the face for hosting)
2. to select the upper left ceiling tile intersection
3. to select the upper right ceiling tile selection ( I am still working on this to reduce to one click by extracting the ceiling tile grid size and orientation so click 3 is not necessary)

What I would really like to be able to do when opting to use 'NewFamilyInsert' is prompt the user to pick the top left intersection of the ceiling tile and have the item dropped into the centre and rotated completely automatically in just one click (user selection). To achieve this I would need to detect the face of the ceiling using only the point returned from a select point request, this is just a 3D coordinate (selecting the face is a separate function that requires another input selection from the user)

My question is this, does anyone know if its possible to select the face closest to point returned from a get point request ( to avoid having to prompt the user again to select the face). I thought I had found a method using a function that detects the first surface in a given direction from a point but this only works in a 3D view. ( I need it to work in a 2D plan/ceiling view)

The standard revit method of inserting families does have 'shortcuts' for aligning families to ceiling grids but depending on the family and its insert position it can't always centre on tile, also using the shortcuts results in several clicks, space bar presses, and panning to pick up alignment.

any help, ideas greatly appreciated.

regards
Paul M
Message 16 of 21
drdanielfc
in reply to: PhillipM

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.

Message 17 of 21
PhillipM
in reply to: drdanielfc

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

 

 

Message 18 of 21
skootamota
in reply to: PhillipM

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

Message 19 of 21
jeremytammik
in reply to: PhillipM

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



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

Message 20 of 21
taksau
in reply to: skootamota

Just wondering if you ever solve the problem with having user to select different ribbon in order to place element in model?

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