Skip to content

Instantly share code, notes, and snippets.

@giobel
Last active November 4, 2021 19:10
Show Gist options
  • Save giobel/eb02ba24a945ff07e03391351fef7f49 to your computer and use it in GitHub Desktop.
Save giobel/eb02ba24a945ff07e03391351fef7f49 to your computer and use it in GitHub Desktop.
Viewport To CAD
Helpers to export sheets from Revit to Autocad in shared coordinates
public void DrawRectangle(Document doc, View vpPlan, XYZ _max, XYZ _min){
XYZ min = new XYZ(_min.X, _min.Y,0);
XYZ max = new XYZ(_max.X, _max.Y,0);
Line l1 = Line.CreateBound(min, new XYZ(max.X, min.Y,0));
Line l2 = Line.CreateBound(min, new XYZ(min.X, max.Y,0));
Line l3 = Line.CreateBound(new XYZ(min.X,max.Y,0), max);
Line l4 = Line.CreateBound(max,new XYZ(max.X,min.Y,0));
Line l5 = Line.CreateBound(min,max);
doc.Create.NewDetailCurve(vpPlan,l1);
doc.Create.NewDetailCurve(vpPlan,l2);
doc.Create.NewDetailCurve(vpPlan,l3);
doc.Create.NewDetailCurve(vpPlan,l4);
doc.Create.NewDetailCurve(vpPlan,l5);
}
// Scope:
// 1. Find the Viewport center
// 2. Find the Viewport's view center
public void FindViewportCenterOnSheet(){
//represents a document opened in the user interface
UIDocument uidoc = this.ActiveUIDocument;
//obtain the database level Document (which contains interfaces not related to the UI)
Document doc = uidoc.Document;
//***1***
//a stable reference to a geometric object in a Revit model (?)
//https://www.revitapidocs.com/2015/d28155ae-817b-1f31-9c3f-c9c6a28acc0d.htm
Reference viewportRef = uidoc.Selection.PickObject(ObjectType.Element,"Select a Viewport");
//The data in a Revit document consists primarily of a collection of elements. An element usually
//corresponds to a single component of a building or drawing, such as a wall, door, or dimension,
//but it can also be something more abstract, like a wall type or a view. Every element in a document has a unique ID,
//represented by the ElementId class.
Element viewportElement = doc.GetElement(viewportRef);
//Cast the Element to a Viewport
//https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions
Viewport viewport = viewportElement as Viewport;
//Find the Viewport center
XYZ vpMax = viewport.GetBoxOutline().MaximumPoint;
XYZ vpMin = viewport.GetBoxOutline().MinimumPoint;
XYZ vpCen = vpMax - vpMin;
double vpX = Convert.ToInt16(viewport.GetBoxCenter().X * 304.8);
double vpY = Convert.ToInt16(viewport.GetBoxCenter().Y * 304.8);
double vpZ = Convert.ToInt16(viewport.GetBoxCenter().Z * 304.8);
TaskDialog.Show("Viewport Center", String.Format("{0}, {1}, {2}", vpX, vpY, vpZ ));
//Draw a rectangle. For the using statement see: https://thebuildingcoder.typepad.com/blog/2012/04/scope-and-dispose-transactions.html
//in short: is the safest way to guarantee that scoped objects are destroyed in the proper order.
using (Transaction t = new Transaction(doc, "Draw Rectangle")){
t.Start();
DrawRectangle(doc, doc.ActiveView, vpMax,vpMin);
t.Commit();
}
//***2***
//Let's now find the View center
//We can get the view from the Viewport.ViewId
View plan = doc.GetElement(viewport.ViewId) as View;
//
ViewCropRegionShapeManager vcr = plan.GetCropRegionShapeManager();
CurveLoop cloop = vcr.GetAnnotationCropShape();
List<XYZ> pts = new List<XYZ>();
foreach (Curve crv in cloop)
{
pts.Add(crv.GetEndPoint(0));
pts.Add(crv.GetEndPoint(1));
}
//View centroid
XYZ center = GetCentroid(pts, pts.Count);
//See the difference
BoundingBoxXYZ bbox = plan.get_BoundingBox(plan);
XYZ centroid = bbox.Max - bbox.Min;
double centerX = (center.X * 304.8);
double centerY = (center.Y * 304.8);
double centerZ = (center.Z * 304.8);
using (Transaction t = new Transaction(doc, "tes")){
t.Start();
//Line l = Line.CreateBound(new XYZ(0,0,0),new XYZ(centroid.X, centroid.Y,0));
Line l = Line.CreateBound(new XYZ(0,0,0),new XYZ(center.X, center.Y,0));
doc.Create.NewDetailCurve(plan, l);
t.Commit();
}
//TaskDialog.Show("Viewport Center", String.Format("{0}, {1}, {2}", vpX, vpY, vpZ ));
//TaskDialog.Show("Viewport Center", center.ToString());
TaskDialog.Show("Viewport Center", String.Format("{0}, {1}, {2}", centerX, centerY, centerZ));
}
// https://stackoverflow.com/questions/9815699/how-to-calculate-centroid
// http://coding-experiments.blogspot.com/2009/09/xna-quest-for-centroid-of-polygon.html
public static XYZ GetCentroid(List<XYZ> nodes, int count)
{
double x = 0, y = 0, area = 0, k;
XYZ a, b = nodes[count - 1];
for (int i = 0; i < count; i++)
{
a = nodes[i];
k = a.Y * b.X - a.X * b.Y;
area += k;
x += (a.X + b.X) * k;
y += (a.Y + b.Y) * k;
b = a;
}
area *= 3;
return (area == 0) ? XYZ.Zero : new XYZ(x /= area, y /= area, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment