public override Value Evaluate(FSharpList <Value> args) { bool isRefCurve = Convert.ToBoolean(((Value.Number)args[1]).Item); //Build a sequence that unwraps the input list from it's Value form. IEnumerable <ReferencePoint> refPts = ((Value.List)args[0]).Item.Select( x => (ReferencePoint)((Value.Container)x).Item ); //Add all of the elements in the sequence to a ReferencePointArray. ReferencePointArray refPtArr = new ReferencePointArray(); foreach (var refPt in refPts) { refPtArr.Append(refPt); } //Standard logic for updating an old result, if it exists. if (this.Elements.Any()) { if (dynUtils.TryGetElement(this.Elements[0], out c)) { c.SetPoints(refPtArr); } else { //TODO: This method of handling bad elements may cause problems. Instead of overwriting // index in Elements, might be better to just add it the Elements and then do // this.DeleteElement(id, true) on the old index. c = this.UIDocument.Document.FamilyCreate.NewCurveByPoints(refPtArr); this.Elements[0] = c.Id; } } else { c = this.UIDocument.Document.FamilyCreate.NewCurveByPoints(refPtArr); this.Elements.Add(c.Id); } c.IsReferenceLine = isRefCurve; return(Value.NewContainer(c)); }
public override Value Evaluate(FSharpList <Value> args) { //Our eventual output. Autodesk.Revit.DB.CurveByPoints c = null; var input = args[0]; Curve gc = (Curve)((Value.Container)args[0]).Item; XYZ start = gc.get_EndPoint(0); XYZ end = gc.get_EndPoint(1); //If we've made any elements previously... if (this.Elements.Any()) { bool replaceElement = true; //...try to get the first one... if (dynUtils.TryGetElement(this.Elements[0], out c)) { //..and if we do, update it's position. ReferencePointArray existingPts = c.GetPoints(); //update the points on the curve to match if (gc.GetType() == typeof(Line) && existingPts.Size == 2) { existingPts.get_Item(0).Position = start; existingPts.get_Item(1).Position = end; replaceElement = false; } // NOTE: there is no way I found in REVITAPI to tell if existing curve by points is arc else if (gc.GetType() == typeof(Arc) && existingPts.Size == 3) { if (existingPts.Size != 3) { var newPts = new ReferencePointArray(); newPts.Append(existingPts.get_Item(0)); if (existingPts.Size < 3) { newPts.Append(this.UIDocument.Document.FamilyCreate.NewReferencePoint(gc.Evaluate(0.5, true))); } else { newPts.Append(existingPts.get_Item(1)); } newPts.Append(existingPts.get_Item(existingPts.Size - 1)); c.SetPoints(newPts); existingPts = c.GetPoints(); } existingPts.get_Item(0).Position = start; existingPts.get_Item(2).Position = end; existingPts.get_Item(1).Position = gc.Evaluate(0.5, true); replaceElement = false; } else if (gc.GetType() != typeof(Arc)) { int nPoints = existingPts.Size; IList <XYZ> xyzList = gc.Tessellate(); int numPoints = xyzList.Count; if (nPoints != numPoints) { var newPts = new ReferencePointArray(); newPts.Append(existingPts.get_Item(0)); newPts.get_Item(0).Position = xyzList[0]; for (int iPoint = 1; iPoint < numPoints; iPoint++) { if (iPoint == numPoints - 1) { newPts.Append(existingPts.get_Item(nPoints - 1)); newPts.get_Item(iPoint).Position = xyzList[iPoint]; } else if (iPoint < nPoints - 1) { newPts.Append(existingPts.get_Item(iPoint)); newPts.get_Item(iPoint).Position = xyzList[iPoint]; } else { newPts.Append(this.UIDocument.Document.FamilyCreate.NewReferencePoint(xyzList[iPoint])); } } if (nPoints > numPoints) { //have to delete as API call to SetPoints leaves points in the doc for (int iPoint = numPoints - 1; iPoint < nPoints - 1; iPoint++) { this.DeleteElement(existingPts.get_Item(iPoint).Id); } } c.SetPoints(newPts); existingPts = c.GetPoints(); } else { for (int iPoint = 0; iPoint < numPoints; iPoint++) { if (iPoint == 0) { existingPts.get_Item(iPoint).Position = start; } else if (iPoint == nPoints - 1) { existingPts.get_Item(iPoint).Position = end; } else { existingPts.get_Item(iPoint).Position = xyzList[iPoint]; } } } replaceElement = false; } if (replaceElement) { IList <XYZ> xyzList = gc.Tessellate(); int numPoint = xyzList.Count; double step = 1.0 / (numPoint - 1.0); double tolerance = 0.0000001; replaceElement = false; for (int index = 0; index < numPoint; index++) { IntersectionResult projXYZ = c.GeometryCurve.Project(xyzList[index]); if (projXYZ.XYZPoint.DistanceTo(xyzList[index]) > tolerance) { replaceElement = true; break; } } } } if (replaceElement) { this.DeleteElement(this.Elements[0]); ReferencePointArray existingPts = c.GetPoints(); c = null; c = CreateCurveByPoints(c, gc, start, end); this.Elements[0] = c.Id; } } else { c = CreateCurveByPoints(c, gc, start, end); this.Elements.Add(c.Id); } return(Value.NewContainer(c)); }