|
1 |
| -from pyrevit import HOST_APP |
2 | 1 | from pyrevit import revit, DB, UI
|
3 | 2 | from pyrevit import forms
|
4 | 3 |
|
| 4 | +from Autodesk.Revit.UI.Selection import ObjectType |
| 5 | +from Autodesk.Revit.Exceptions import OperationCanceledException |
5 | 6 |
|
6 |
| -def reorient(): |
7 |
| - face = revit.pick_face() |
8 |
| - |
9 |
| - if face: |
10 |
| - with revit.Transaction('Orient to Selected Face'): |
11 |
| - # calculate normal |
12 |
| - if HOST_APP.is_newer_than(2015): |
13 |
| - normal_vec = face.ComputeNormal(DB.UV(0, 0)) |
14 |
| - else: |
15 |
| - normal_vec = face.Normal |
| 7 | +curview = revit.active_view |
16 | 8 |
|
17 |
| - # create base plane for sketchplane |
18 |
| - if HOST_APP.is_newer_than(2016): |
19 |
| - base_plane = \ |
20 |
| - DB.Plane.CreateByNormalAndOrigin(normal_vec, face.Origin) |
21 |
| - else: |
22 |
| - base_plane = DB.Plane(normal_vec, face.Origin) |
23 | 9 |
|
24 |
| - # now that we have the base_plane and normal_vec |
25 |
| - # let's create the sketchplane |
| 10 | +def reorient(view): |
| 11 | + try: |
| 12 | + # Pick face to align to using uidoc.Selection instead of revit.pick_face to get the reference instead of the face |
| 13 | + face_ref = revit.uidoc.Selection.PickObject( |
| 14 | + UI.Selection.ObjectType.Face, "Pick a face to align to:" |
| 15 | + ) |
| 16 | + |
| 17 | + # Get the geometry object of the reference |
| 18 | + element = revit.doc.GetElement(face_ref) |
| 19 | + geometry_object = element.GetGeometryObjectFromReference(face_ref) |
| 20 | + |
| 21 | + # Check if the object might have a Transformation (by checking if it's Non-Instance) |
| 22 | + if isinstance(element, DB.FamilyInstance): |
| 23 | + # Get the transform of the family instance (converts local to world coordinates) |
| 24 | + transform = element.GetTransform() |
| 25 | + # Get the face normal in local coordinates |
| 26 | + local_normal = geometry_object.ComputeNormal(DB.UV(0, 0)).Normalize() |
| 27 | + # Apply the transform to convert normal to world coordinates |
| 28 | + world_normal = transform.OfVector(local_normal).Normalize() |
| 29 | + norm = world_normal |
| 30 | + else: |
| 31 | + norm = geometry_object.ComputeNormal(DB.UV(0, 0)).Normalize() |
| 32 | + |
| 33 | + # since we're working with a reference instead of the face, we can't use face.origin |
| 34 | + if isinstance(geometry_object, DB.Face): |
| 35 | + centroid = geometry_object.Evaluate(DB.UV(0.5, 0.5)) |
| 36 | + else: |
| 37 | + raise Exception("The geometry object is not a face.") |
| 38 | + |
| 39 | + base_plane = DB.Plane.CreateByNormalAndOrigin(norm, centroid) |
| 40 | + # now that we have the base_plane and normal_vec |
| 41 | + # let's create the sketchplane |
| 42 | + with revit.Transaction("Orient to Selected Face"): |
26 | 43 | sp = DB.SketchPlane.Create(revit.doc, base_plane)
|
27 | 44 |
|
28 | 45 | # orient the 3D view looking at the sketchplane
|
29 |
| - revit.active_view.OrientTo(normal_vec.Negate()) |
| 46 | + view.OrientTo(norm.Negate()) |
30 | 47 | # set the sketchplane to active
|
31 |
| - revit.uidoc.ActiveView.SketchPlane = sp |
| 48 | + view.SketchPlane = sp |
32 | 49 |
|
33 | 50 | revit.uidoc.RefreshActiveView()
|
34 | 51 |
|
| 52 | + except OperationCanceledException: |
| 53 | + pass |
| 54 | + |
| 55 | + except Exception as ex: |
| 56 | + forms.alert("Error: {0}".format(str(ex))) |
35 | 57 |
|
36 |
| -curview = revit.active_view |
37 | 58 |
|
| 59 | +# This check could be skipped, as there is a context file in the bundle.yaml |
38 | 60 | if isinstance(curview, DB.View3D):
|
39 |
| - reorient() |
| 61 | + reorient(curview) |
40 | 62 | else:
|
41 |
| - forms.alert('You must be on a 3D view for this tool to work.') |
| 63 | + forms.alert("You must be on a 3D view for this tool to work.") |
0 commit comments