private FamilyInstanceCreationData GetCreationData(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol) { //calculate the desired rotation //we do this by finding the angle between the z axis //and vector between the start of the beam and the target point //both projected onto the start plane of the beam. var zAxis = new XYZ(0, 0, 1); var yAxis = new XYZ(0, 1, 0); //flatten the beam line onto the XZ plane //using the start's z coordinate var start = curve.GetEndPoint(0); var end = curve.GetEndPoint(1); var newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane //catch the case where the end is directly above //the start, creating a normal with zero length //in that case, use the Z axis XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize(); double gamma = upVector.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal); return(new FamilyInstanceCreationData(curve, symbol, level, structuralType) { RotateAngle = gamma }); }
// PB: This implementation borrows the somewhat risky notions from the original Dynamo // implementation. In short, it has the ability to infer a sketch plane, // which might also mean deleting the original one. /// <summary> /// Initialize a ModelCurve element /// </summary> /// <param name="crv"></param> /// <param name="makeReferenceCurve"></param> private void InitModelCurve(Autodesk.Revit.DB.Curve crv, bool makeReferenceCurve) { //Phase 1 - Check to see if the object exists and should be rebound var mc = ElementBinder.GetElementFromTrace <Autodesk.Revit.DB.ModelCurve>(Document); //There was a modelcurve, try and set sketch plane // if you can't, rebuild if (mc != null) { InternalSetCurveElement(mc); InternalSetSketchPlaneFromCurve(crv); return; } ElementId oldId = (mc != null) ? mc.Id : ElementId.InvalidElementId; string oldUniqueId = (mc != null) ? mc.UniqueId : string.Empty; TransactionManager.Instance.EnsureInTransaction(Document); // (sic erat scriptum) var sp = GetSketchPlaneFromCurve(crv); var plane = sp.GetPlane(); if (CurveUtils.GetPlaneFromCurve(crv, true) == null) { var flattenCurve = Flatten3dCurveOnPlane(crv, plane); mc = Document.IsFamilyDocument ? Document.FamilyCreate.NewModelCurve(flattenCurve, sp) : Document.Create.NewModelCurve(flattenCurve, sp); setCurveMethod(mc, crv); } else { mc = Document.IsFamilyDocument ? Document.FamilyCreate.NewModelCurve(crv, sp) : Document.Create.NewModelCurve(crv, sp); } if (mc.SketchPlane.Id != sp.Id) { //THIS BIZARRE as Revit could use different existing SP, so if Revit had found better plane this sketch plane has no use DocumentManager.Instance.DeleteElement(new ElementUUID(sp.UniqueId)); } InternalSetCurveElement(mc); if (oldId != mc.Id && oldId != ElementId.InvalidElementId) { DocumentManager.Instance.DeleteElement(new ElementUUID(oldUniqueId)); } if (makeReferenceCurve) { mc.ChangeToReferenceLine(); } TransactionManager.Instance.TransactionTaskDone(); ElementBinder.SetElementForTrace(this.InternalElement); }
/// <summary> /// Internal constructor - creates a single StructuralFraming instance /// </summary> internal StructuralFraming(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol) { //Phase 1 - Check to see if the object exists and should be rebound var oldFam = ElementBinder.GetElementFromTrace <Autodesk.Revit.DB.FamilyInstance>(Document); //There was a point, rebind to that, and adjust its position if (oldFam != null) { InternalSetFamilyInstance(oldFam); InternalSetFamilySymbol(symbol); InternalSetCurve(curve); return; } //Phase 2- There was no existing point, create one TransactionManager.Instance.EnsureInTransaction(Document); var creationData = GetCreationData(curve, upVector, level, structuralType, symbol); Autodesk.Revit.DB.FamilyInstance fi; if (Document.IsFamilyDocument) { var elementIds = Document.FamilyCreate.NewFamilyInstances2(new List <FamilyInstanceCreationData>() { creationData }); if (elementIds.Count == 0) { throw new Exception("Could not create the FamilyInstance"); } fi = (Autodesk.Revit.DB.FamilyInstance)Document.GetElement(elementIds.First()); } else { var elementIds = Document.Create.NewFamilyInstances2(new List <FamilyInstanceCreationData>() { creationData }); if (elementIds.Count == 0) { throw new Exception("Could not create the FamilyInstance"); } fi = (Autodesk.Revit.DB.FamilyInstance)Document.GetElement(elementIds.First()); } InternalSetFamilyInstance(fi); TransactionManager.Instance.TransactionTaskDone(); ElementBinder.SetElementForTrace(this.InternalElement); }
private void InternalSetCurve(Autodesk.Revit.DB.Curve crv) { TransactionManager.Instance.EnsureInTransaction(Document); //update the curve var locCurve = InternalFamilyInstance.Location as LocationCurve; locCurve.Curve = crv; TransactionManager.Instance.TransactionTaskDone(); }
/// <summary> /// Set the curve internally. Returns false if this method failed to set the curve /// </summary> /// <param name="c"></param> /// <returns></returns> private bool InternalSetSketchPlaneFromCurve(Autodesk.Revit.DB.Curve c) { TransactionManager.Instance.EnsureInTransaction(Document); // Infer the sketch plane Autodesk.Revit.DB.Plane plane = CurveUtils.GetPlaneFromCurve(c, false); // attempt to change the sketch plane bool needsRemake = false; string idSpUnused = resetSketchPlaneMethod(this.InternalCurveElement, c, plane, out needsRemake); // if we got a valid id, delete the old sketch plane if (idSpUnused != String.Empty) { DocumentManager.Instance.DeleteElement(new ElementUUID(idSpUnused)); } TransactionManager.Instance.TransactionTaskDone(); return(!needsRemake); }
// PB: This implementation borrows the somewhat risky notions from the original Dynamo // implementation. In short, it has the ability to infer a sketch plane, // which might also mean deleting the original one. /// <summary> /// Internal constructor for ModelCurve /// </summary> /// <param name="crv"></param> /// <param name="makeReferenceCurve"></param> private ModelCurve(Autodesk.Revit.DB.Curve crv, bool makeReferenceCurve) { SafeInit(() => InitModelCurve(crv, makeReferenceCurve)); }