Hi,
I'm trying to create a vertical opening with the code below.
The opening can be created if the 3rd argument is "true". The resulting opening is perpendicular to the face.
But when the 3rd argument is "false" to create a vertical opening, Revit gives an error "Can't change plane of Opening Cut Sketch."
The code is included as a document macro in the attached RVT.
public void opening()
{
Document doc = this.Document;
UIDocument uidoc = new UIDocument(doc);
double gutterWidth = 2;
Reference edgeRef = uidoc.Selection.PickObject(ObjectType.Edge, "Select roof edge");
RoofBase roof = doc.GetElement(edgeRef) as RoofBase;
PlanarFace pf = roof.GetGeometryObjectFromReference(HostObjectUtils.GetTopFaces(roof).FirstOrDefault()) as PlanarFace;
Edge edge = roof.GetGeometryObjectFromReference(edgeRef) as Edge;
Line line = edge.AsCurve() as Line;
CurveArray openingCa = new CurveArray();
XYZ offsetDir = line.Direction.CrossProduct(XYZ.BasisZ);
Line openingLineParallel = offsetLine(line, offsetDir, gutterWidth);
if (pf.Project(openingLineParallel.Evaluate(0.5, true)) == null)
{
offsetDir = line.Direction.CrossProduct(XYZ.BasisZ);
openingLineParallel = offsetLine(line, offsetDir.Negate(), gutterWidth);
}
line = offsetLine(line, offsetDir, 1);
openingCa.Append(line);
openingCa.Append(openingLineParallel);
openingCa.Append(Line.CreateBound(line.GetEndPoint(0), findNearestPoint(line.GetEndPoint(0), new List<XYZ>{openingLineParallel.GetEndPoint(0), openingLineParallel.GetEndPoint(1)})));
openingCa.Append(Line.CreateBound(line.GetEndPoint(1), findNearestPoint(line.GetEndPoint(1), new List<XYZ>{openingLineParallel.GetEndPoint(0), openingLineParallel.GetEndPoint(1)})));
using (Transaction t = new Transaction(doc, "d"))
{
t.Start();
// code works when 3rd argument in the line below is true
// when it is false (to make a vertical cut), it fails with "Can't change plane of Opening Cut Sketch."
Opening opening = doc.Create.NewOpening(roof, openingCa, false);
t.Commit();
}
}
public Line offsetLine(Line line, XYZ dir, double offset)
{
Line ret = null;
ret = Line.CreateBound(line.GetEndPoint(0).Add(dir.Multiply(offset)),
line.GetEndPoint(1).Add(dir.Multiply(offset)));
return ret;
}
private XYZ findNearestPoint(XYZ pt, List<XYZ> xyzs)
{
double dist = double.PositiveInfinity;
XYZ nearest = null;
foreach (XYZ xyz in xyzs)
{
double thisDistance = pt.DistanceTo(xyz);
if (thisDistance < dist)
{
nearest = xyz;
dist = thisDistance;
}
}
if (nearest == null)
return pt;
return nearest;
}