public override Value Evaluate(FSharpList<Value> args) { var crv1 = (Curve)((Value.Container)args[0]).Item; var crv2 = (Curve)((Value.Container)args[1]).Item; IntersectionResultArray xsects = new IntersectionResultArray(); SetComparisonResult result = crv1.Intersect(crv2, out xsects); var results = FSharpList<Value>.Empty; var xsect_results = FSharpList<Value>.Empty; if (xsects != null) { foreach (IntersectionResult ir in xsects) { var xsect = FSharpList<Value>.Empty; xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.UVPoint.U), xsect); xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.UVPoint.V), xsect); xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.XYZPoint), xsect); xsect_results = FSharpList<Value>.Cons(Value.NewList(xsect), xsect_results); pts.Add(ir.XYZPoint); } } results = FSharpList<Value>.Cons(Value.NewList(xsect_results), results); results = FSharpList<Value>.Cons(Value.NewString(result.ToString()), results); return Value.NewList(results); }
public static XYZ Intersection(Curve _curve, Curve _another) { IntersectionResultArray resultArray = new IntersectionResultArray(); SetComparisonResult result = _curve.Intersect(_another, out resultArray); if (result != SetComparisonResult.Overlap) { bool Flag2 = _curve.GetEndPoint(0).IsEqual(_another.GetEndPoint(0)) || _curve.GetEndPoint(0).IsEqual(_another.GetEndPoint(1)); bool Flag3 = _curve.GetEndPoint(1).IsEqual(_another.GetEndPoint(0)) || _curve.GetEndPoint(1).IsEqual(_another.GetEndPoint(1)); if (Flag2) { return(_curve.GetEndPoint(0)); } if (Flag3) { return(_another.GetEndPoint(1)); } return(null); } if (resultArray.Size != 1) { throw new ArithmeticException("Having more one intersection."); } return(resultArray.get_Item(0).XYZPoint); }
public override Value Evaluate(FSharpList <Value> args) { var crv1 = (Curve)((Value.Container)args[0]).Item; var crv2 = (Curve)((Value.Container)args[1]).Item; IntersectionResultArray xsects = new IntersectionResultArray(); SetComparisonResult result = crv1.Intersect(crv2, out xsects); var results = FSharpList <Value> .Empty; var xsect_results = FSharpList <Value> .Empty; if (xsects != null) { foreach (IntersectionResult ir in xsects) { var xsect = FSharpList <Value> .Empty; xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.UVPoint.U), xsect); xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.UVPoint.V), xsect); xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.XYZPoint), xsect); xsect_results = FSharpList <Value> .Cons(Value.NewList(xsect), xsect_results); pts.Add(ir.XYZPoint); } } results = FSharpList <Value> .Cons(Value.NewList(xsect_results), results); results = FSharpList <Value> .Cons(Value.NewString(result.ToString()), results); return(Value.NewList(results)); }
/// <summary> /// Appends a list of the room's near-corner points to a pre-existing list. /// </summary> /// <remarks> /// A near-corner point is offset from the room boundaries by 1.5 ft (18 inches). The points are calculated geometrically and some situations may not return /// all logical near-corner points, or may return points which are inside furniture, casework or other design elements. Only the first boundary region of the room is /// currently processed. /// </remarks> /// <param name="room"></param> /// <param name="nearCornerPoints"></param> /// <returns></returns> private static void AppendRoomNearCornerPoints(Room room, List <XYZ> nearCornerPoints) { IList <IList <BoundarySegment> > segments = room.GetBoundarySegments(new SpatialElementBoundaryOptions()); if (segments == null || segments.Count == 0) { return; } // First region only IList <BoundarySegment> firstSegments = segments[0]; int numSegments = firstSegments.Count; for (int i = 0; i < numSegments; i++) { BoundarySegment seg1 = firstSegments.ElementAt(i); BoundarySegment seg2 = firstSegments.ElementAt(i == numSegments - 1 ? 0 : i + 1); Curve curve1 = seg1.GetCurve(); Curve curve2 = seg2.GetCurve(); Curve offsetCurve1 = curve1.CreateOffset(-1.5, XYZ.BasisZ); Curve offsetCurve2 = curve2.CreateOffset(-1.5, XYZ.BasisZ); IntersectionResultArray intersections = null; SetComparisonResult result = offsetCurve1.Intersect(offsetCurve2, out intersections); // First intersection only if (result == SetComparisonResult.Overlap && intersections.Size == 1) { nearCornerPoints.Add(intersections.get_Item(0).XYZPoint); } } }
public void CreateMark() { if (_mark != null) { var plane = Plane.CreateByNormalAndOrigin(_activeView.ViewDirection, _activeView.Origin); // Создаем пласкость midle = Project_Onto(plane, midle); head = Project_Onto(plane, head); point = Project_Onto(plane, point); var i = 0; while (i == 0) { var target = (new SelectionClass(_uiDoс)).PickElementByCategory(elementCategory); if (target != null) { var pos = get_coordinate(); var reference = new Reference(target); using (Transaction t = new Transaction(_doc, "Добавить выноску")) { t.Start(); var vec = (point - midle).Normalize(); var n_pos = Project_Onto(plane, vec); var l1 = Line.CreateUnbound(n_pos, vec); var l2 = Line.CreateUnbound(midle, (head - midle).Normalize()); var inter1 = new StrongBox <IntersectionResultArray>(); var inter = new IntersectionResultArray(); l1.Intersect(l2, out inter); //inter1. //var new_midle = inter.Value } } } } }
/// <summary> /// Intersects the Line with current plane /// </summary> /// <param name="plane">Invoking point</param> /// <param name="line">Target line</param> /// <param name="result">Intersection result object</param> /// <returns>Intersection status</returns> public static SetComparisonResult Intersect(this Plane plane, Line line, out IntersectionResultArray result) { var startPojection = plane.Project(line.GetEndPoint(0)); //已经使用line.GetEndPoint() 没有必要再判断直线是否bound var endProjection = plane.Project(line.GetEndPoint(1)); //已经使用line.GetEndPoint() 没有必要再判断直线是否bound var projectionLine = Line.CreateBound(startPojection, endProjection); //已经使用line.GetEndPoint() 没有必要再判断直线是否bound return(line.Intersect(projectionLine, out result)); }
public TrussInfo CreateTrussFromRidgeWithSupports(XYZ currentPointOnRidge, EdgeInfo currentRidgeEdgeInfo, TrussType tType, Line support0, Line support1) { TrussInfo currentTrussInfo = null; Document doc = currentRidgeEdgeInfo.CurrentRoof.Document; if (doc == null) { return(currentTrussInfo); } IList <XYZ> currentSupportPoints = new List <XYZ>(); double roofheight = currentRidgeEdgeInfo.GetCurrentRoofHeight(); Line currentRidgeLineFlatten = (currentRidgeEdgeInfo.Curve as Line).Flatten(roofheight); if (currentRidgeLineFlatten == null) { return(currentTrussInfo); } XYZ crossDirection = currentRidgeLineFlatten.Direction.CrossProduct(XYZ.BasisZ); XYZ currentPointOnRidgeFlatten = new XYZ(currentPointOnRidge.X, currentPointOnRidge.Y, roofheight); Line currentCrossedLineInfinite = Line.CreateBound(currentPointOnRidgeFlatten, currentPointOnRidgeFlatten.Add(crossDirection)); currentCrossedLineInfinite.MakeUnbound(); if (support0 != null) { IntersectionResultArray iResultArr = new IntersectionResultArray(); SetComparisonResult iResulComp = currentCrossedLineInfinite.Intersect(support0.Flatten(roofheight), out iResultArr); if (iResultArr != null && iResultArr.Size == 1) { currentSupportPoints.Add(iResultArr.get_Item(0).XYZPoint); } } if (support1 != null) { IntersectionResultArray iResultArr = new IntersectionResultArray(); SetComparisonResult iResulComp = currentCrossedLineInfinite.Intersect(support1.Flatten(roofheight), out iResultArr); if (iResultArr != null && iResultArr.Size == 1) { currentSupportPoints.Add(iResultArr.get_Item(0).XYZPoint); } } using (Transaction t = new Transaction(doc, "Criar treliça")) { t.Start(); currentTrussInfo = CreateTrussInfo(doc, currentPointOnRidge, currentRidgeEdgeInfo, currentSupportPoints, tType); t.Commit(); } return(currentTrussInfo); }
/// <summary> /// Intersects the Line with current plane /// </summary> /// <param name="plane">Invoking point</param> /// <param name="line">Target line</param> /// <param name="result">Intersection result object</param> /// <returns>Intersection status</returns> public static SetComparisonResult Intersect(this Plane plane, Line line, out IntersectionResultArray result) { var startPojection = plane.Project(line.GetEndPoint(0)); var endProjection = plane.Project(line.GetEndPoint(1)); var projectionLine = line.IsBound ? Line.CreateBound(startPojection, endProjection) : Line.CreateUnbound(startPojection, endProjection - startPojection); return(line.Intersect(projectionLine, out result)); }
//method to find the intersection of planarface with a line from the point passed public static double ReturnLeastZ_Value(Document doc, IList <PlanarFace> pf, XYZ xyz, Transform trans) { try { List <XYZ> intersectionPoints = new List <XYZ>(); Line line = doc.Application.Create.NewLineBound(trans.OfPoint(xyz), new XYZ(trans.OfPoint(xyz).X, trans.OfPoint(xyz).Y, trans.OfPoint(xyz).Z + 10)); IntersectionResultArray resultArray = null; foreach (PlanarFace face in pf) { IntersectionResult iResult = null; SetComparisonResult result = new SetComparisonResult(); try { result = face.Intersect(line, out resultArray); } catch { continue; } if (result != SetComparisonResult.Disjoint) { try { iResult = resultArray.get_Item(0); intersectionPoints.Add(iResult.XYZPoint); } catch { continue; } } } XYZ minPoint = intersectionPoints.First(); foreach (XYZ point in intersectionPoints) { if (minPoint.Z > point.Z) { minPoint = point; } } return(minPoint.Z - trans.OfPoint(xyz).Z); } catch { return(-1); } }
// 获取插入点和方向 private void GetIntersectPtAndDirection() { foreach (OutViewInfo viewOutLineInfo in m_OutViewInfos) { foreach (DrawElement drawElement in m_DrawElems) { Curve curve = null; if (drawElement.DrawElemType == ElemType._Grid || drawElement.DrawElemType == ElemType._MultiSegGrid) { Grid grid = drawElement.DrawElem as Grid; if (grid == null || (drawElement.DrawElemType == ElemType._MultiSegGrid && (m_doc.ActiveView.ViewType == ViewType.Section || m_doc.ActiveView.ViewType == ViewType.Elevation))) { continue; } curve = GetGridCurve(m_doc.ActiveView, grid); } else if (drawElement.DrawElemType == ElemType._Level) { Level level = drawElement.DrawElem as Level; if (level == null) { continue; } curve = GetLevelCurve(m_doc.ActiveView, level); } if (!(curve == null)) { Curve curve2D = CurveToZero(curve); //求边界线和轴网/标高的交点 IntersectionResultArray intersectionResultArray = new IntersectionResultArray(); SetComparisonResult setComparisonResult = viewOutLineInfo.OutViewLine.Intersect(curve2D, out intersectionResultArray); if (setComparisonResult == SetComparisonResult.Overlap && intersectionResultArray != null && intersectionResultArray.Size > 0) { for (int i = 0; i < intersectionResultArray.Size; i++) { GridNumShowInfo gridNumShowInfo = new GridNumShowInfo(); gridNumShowInfo.IntersectPoint = intersectionResultArray.get_Item(i).XYZPoint; gridNumShowInfo.OutlineSide = viewOutLineInfo.OutViewSide; gridNumShowInfo.ElemText = drawElement.DrawElem.Name; gridNumShowInfo.ElemClass = drawElement.DrawElemType; m_GridNumShowInfos.Add(gridNumShowInfo); } } } } } }
public static bool IntersectToByMovingZ(this Curve curve, Curve checkedCurve, out IntersectionResultArray intersectionResultArray) { intersectionResultArray = new IntersectionResultArray(); // walls is always vertical - it's very good =) var z = curve.GetCenterPoint().Z; checkedCurve = GetCurveWithChangedZ(checkedCurve, z); if (checkedCurve == null) { return(false); // can't be... } return(curve.Intersect(checkedCurve, out intersectionResultArray) == SetComparisonResult.Overlap); }
public override FScheme.Value Evaluate(FSharpList <FScheme.Value> args) { Solid thisSolid = (Solid)((FScheme.Value.Container)args[0]).Item; Line selectLine = (Line)((FScheme.Value.Container)args[1]).Item; FaceArray faceArr = thisSolid.Faces; var thisEnum = faceArr.GetEnumerator(); SortedList <double, Autodesk.Revit.DB.Face> intersectingFaces = new SortedList <double, Autodesk.Revit.DB.Face>(); for (; thisEnum.MoveNext();) { Autodesk.Revit.DB.Face thisFace = (Autodesk.Revit.DB.Face)thisEnum.Current; IntersectionResultArray resultArray = null; SetComparisonResult resultIntersect = thisFace.Intersect(selectLine, out resultArray); if (resultIntersect != SetComparisonResult.Overlap) { continue; } bool first = true; double linePar = -1.0; foreach (IntersectionResult ir in resultArray) { double irPar = ir.Parameter; if (first == true) { linePar = irPar; first = false; } else if (irPar < linePar) { linePar = irPar; } } intersectingFaces.Add(linePar, thisFace); } var result = FSharpList <FScheme.Value> .Empty; var intersectingFacesEnum = intersectingFaces.Reverse().GetEnumerator(); for (; intersectingFacesEnum.MoveNext();) { Autodesk.Revit.DB.Face faceObj = intersectingFacesEnum.Current.Value; result = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(faceObj), result); } return(FScheme.Value.NewList(result)); }
private static CableTrayAndMassIntersectionModel GetIntersection(CableTrayModel CableTrayModel, MassFormModel massFormModel) { var intersectionsInstance = new CableTrayAndMassIntersectionModel { CableTray = CableTrayModel, MassForm = massFormModel }; var cableTrayCurveStartPoint = CableTrayModel.StarPoint; var cableTrayCurveEndPoint = CableTrayModel.EndPoint; foreach (var massFace in massFormModel.Faces) { IntersectionResultArray intersectionResultArray = null; massFace.Intersect(CableTrayModel.Curve, out intersectionResultArray); if (intersectionResultArray == null) { continue; } foreach (IntersectionResult intResult in intersectionResultArray) { if (intResult.XYZPoint == null) { continue; } var intersectPoint = intResult.XYZPoint; bool isIntersectPointInRange = NumberUtils.IsInRange( intersectPoint.Z, Math.Min(cableTrayCurveStartPoint.Z, cableTrayCurveStartPoint.Z), Math.Max(cableTrayCurveEndPoint.Z, cableTrayCurveEndPoint.Z)); //проверяем находится ли точка на линии if (GeomShark.PointUtils.IsPointBetweenOtherTwoPoints( cableTrayCurveStartPoint.X, cableTrayCurveStartPoint.Y, cableTrayCurveEndPoint.X, cableTrayCurveEndPoint.Y, intersectPoint.X, intersectPoint.Y, 4)) { intersectionsInstance.IntersectionPoints.Add(intersectPoint); } } } return((intersectionsInstance.IntersectionPoints.Count > 0) ? intersectionsInstance : null); }
public XYZ Intersect_cus(Curve c, Curve c1) { XYZ result = null; IntersectionResultArray resultArray = new IntersectionResultArray(); var comparisonResult = c.Intersect(c1, out resultArray); if (comparisonResult != SetComparisonResult.Disjoint) { if (resultArray != null) { result = resultArray.get_Item(0).XYZPoint; } } return(result); }
//取得两条线段的交点,直线延长线上的相交不算。 public static XYZ IntersectionPoint(Line line1, Line line2) { IntersectionResultArray intersectionR = new IntersectionResultArray(); SetComparisonResult comparisonR; comparisonR = line1.Intersect(line2, out intersectionR); XYZ intersectionResult = null; if (SetComparisonResult.Disjoint != comparisonR) //Disjoint不交 { if (!intersectionR.IsEmpty) //两条直线如果重复为一条直线,这里也为空 { intersectionResult = intersectionR.get_Item(0).XYZPoint; } } return(intersectionResult); }
//public static IEnumerable<XYZ> EquallyDivideByInterpolation(this Curve curve, int divideNum) //{ // return CurveDivider.GetDivider(curve.GetType()).Divide(curve, divideNum); //} /// <summary> /// 求曲线交点 /// </summary> /// <param name="c1"></param> /// <param name="c2"></param> /// <returns></returns> public static XYZ GetIntersection(this Curve c1, Curve c2) { IntersectionResultArray intersectionR = new IntersectionResultArray(); SetComparisonResult comparisonR; comparisonR = c1.Intersect(c2, out intersectionR); XYZ intersectionResult = null; if (SetComparisonResult.Disjoint != comparisonR) { if (!intersectionR.IsEmpty) { intersectionResult = intersectionR.get_Item(0).XYZPoint; } } return(intersectionResult); }
public static double ExtractHeightForPoint(double station, Alignment alignment) { double Height = default(double); if (alignment != null) { foreach (var HeightElements in LandXmlParser.LandxmlHeighElements) { if (station >= HeightElements.Range.Item1 && station <= HeightElements.Range.Item2) { var Zray = Autodesk.Revit.DB.Line.CreateUnbound(new XYZ(station, 0, 0), XYZ.BasisZ); IntersectionResultArray Intersections = null; var REsult = HeightElements.SegmentElement.Intersect(Zray, out Intersections); var IntersectionPoint = Intersections.get_Item(0).XYZPoint; return(IntersectionPoint.Z); } } } return(default(double)); }
public XYZ intersectFaceCurve(Curve rayCurve, Face wallFace) { IntersectionResultArray intersectionR = new IntersectionResultArray(); SetComparisonResult results; results = wallFace.Intersect(rayCurve, out intersectionR); XYZ intersectionResult = null; if (SetComparisonResult.Disjoint != results) { if (intersectionR != null) { if (!intersectionR.IsEmpty) { intersectionResult = intersectionR.get_Item(0).XYZPoint; } } } return(intersectionResult); }
static internal XYZ GetRoofIntersectionFlattenLines(Line RidgeLine, XYZ ridgePointFlatten, Line eaveOrValleyLine, double flattenHeight) { Line eaveOrValleyInfiniteLine = (eaveOrValleyLine as Line).Flatten(flattenHeight); eaveOrValleyInfiniteLine.MakeUnbound(); XYZ crossedRidgeDirection = ridgePointFlatten.Add(RidgeLine.Flatten(flattenHeight).Direction.CrossProduct(XYZ.BasisZ)); Line crossedRidgeInfitineLine = Line.CreateBound(ridgePointFlatten, crossedRidgeDirection.Multiply(1)); crossedRidgeInfitineLine = crossedRidgeInfitineLine.Flatten(flattenHeight); crossedRidgeInfitineLine.MakeUnbound(); IntersectionResultArray lineInterserctions = null; eaveOrValleyInfiniteLine.Intersect(crossedRidgeInfitineLine, out lineInterserctions); if (lineInterserctions == null || lineInterserctions.Size > 1 || lineInterserctions.Size == 0) { return(null); } return(lineInterserctions.get_Item(0).XYZPoint); }
static internal XYZ GetFlattenIntersection(this Line targetLine, Line secondLine, bool MakeFirstLineInfinite = true, bool MakeSecondLineInfinite = true) { if (targetLine == null || secondLine == null) { return(null); } targetLine = targetLine.Flatten(); secondLine = secondLine.Flatten(); if (MakeFirstLineInfinite) { targetLine.MakeUnbound(); } if (MakeSecondLineInfinite) { secondLine.MakeUnbound(); } IntersectionResultArray iResultArr = null; targetLine.Intersect(secondLine, out iResultArr); if (iResultArr == null) { return(null); } IntersectionResult iResult = iResultArr.get_Item(0); if (iResult == null) { return(null); } return(iResult.XYZPoint); }
static private IList <EdgeInfo> MergeEdgeCurves(IList <EdgeInfo> targetListOfEdgeInfo) { IList <EdgeInfo> resultingListOfEdgeInfo = targetListOfEdgeInfo.ToList(); foreach (EdgeInfo currentEdgeInfo in targetListOfEdgeInfo) { foreach (EdgeInfo currentOtherEdgeInfo in targetListOfEdgeInfo) { if ((currentEdgeInfo.RoofLineType == currentOtherEdgeInfo.RoofLineType) && !(currentEdgeInfo.Curve.IsAlmostEqualTo(currentOtherEdgeInfo.Curve))) { if (currentEdgeInfo.Curve is Line && currentOtherEdgeInfo.Curve is Line) { Line l1 = currentEdgeInfo.Curve as Line; Line l2 = currentOtherEdgeInfo.Curve as Line; XYZ d1 = l1.Direction; XYZ d2 = l2.Direction; if (d1.AngleTo(d2).IsAlmostEqualTo(0, 0.02) || d1.AngleTo(d2).IsAlmostEqualTo(Math.PI, 0.02) || d1.AngleTo(d2).IsAlmostEqualTo(2 * Math.PI, 0.02)) { IntersectionResultArray edgeIntResult = null; SetComparisonResult edgeCompResult = currentEdgeInfo.Curve.Intersect(currentOtherEdgeInfo.Curve, out edgeIntResult); if (edgeIntResult != null) { XYZ currentIntersPoint = edgeIntResult.get_Item(0).XYZPoint; double maxDist = double.MinValue; XYZ startingPoint = null; XYZ endingPoint = null; for (int i = 0; i <= 1; i++) { XYZ currentPoint = currentEdgeInfo.Curve.GetEndPoint(i); for (int j = 0; j <= 1; j++) { XYZ currentOtherPoint = currentOtherEdgeInfo.Curve.GetEndPoint(j); double currentDist = currentPoint.DistanceTo(currentOtherPoint); if (currentDist > maxDist) { maxDist = currentDist; startingPoint = currentPoint; endingPoint = currentOtherPoint; } } } EdgeInfo currentEdgeInfoNew = new EdgeInfo { CurrentRoof = currentEdgeInfo.CurrentRoof, RoofLineType = currentEdgeInfo.RoofLineType }; Line mergedLine = Line.CreateBound(startingPoint, endingPoint); currentEdgeInfoNew.Curve = mergedLine; resultingListOfEdgeInfo.Remove(currentEdgeInfo); resultingListOfEdgeInfo.Remove(currentOtherEdgeInfo); bool alreadyExists = false; foreach (EdgeInfo currentResultInfo in resultingListOfEdgeInfo) { if (currentResultInfo.Curve.IsAlmostEqualTo(mergedLine)) { alreadyExists = true; } } if (!alreadyExists) { IList <Edge> currentEdges = new List <Edge> { currentEdgeInfo.Edges[0], currentOtherEdgeInfo.Edges[0] }; currentEdgeInfoNew.Edges = currentEdges; resultingListOfEdgeInfo.Add(currentEdgeInfoNew); } //Document doc = currentEdgeInfo.CurrentRoof.Document; //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol; //doc.Create.NewFamilyInstance(currentIntersPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); } } } } } } return(resultingListOfEdgeInfo); }
public StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; //The list of fittings, sorted by TYPE then SKEY IList <Element> fittingsList = elements. OrderBy(e => e.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(new plst().PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbFittings = new StringBuilder(); foreach (Element element in fittingsList) { //If the Element Type field is empty -> ignore the component if (string.IsNullOrEmpty(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString())) { continue; } sbFittings.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbFittings.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger()); //Write Plant3DIso entries if turned on if (iv.ExportToPlant3DIso) { sbFittings.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //MEPModel of the elements is accessed MEPModel mepmodel = familyInstance.MEPModel; //Get connector set for the element ConnectorSet connectorSet = mepmodel.ConnectorManager.Connectors; //Switch to different element type configurations switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()) { case ("ELBOW"): Connector primaryConnector = null; Connector secondaryConnector = null; //Process endpoints of the component foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(" ANGLE "); sbFittings.Append((Conversion.RadianToDegree(element.LookupParameter("Angle").AsDouble()) * 100).ToString("0")); sbFittings.AppendLine(); break; case ("TEE"): //Sort connectors to primary, secondary and none primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null; foreach (Connector connector in connectorSet) { #region Debug //Debug //sbFittings.Append(connector.GetMEPConnectorInfo().IsPrimary); //sbFittings.Append(connector.GetMEPConnectorInfo().IsSecondary); //sbFittings.Append((connector.GetMEPConnectorInfo().IsPrimary == false) & (connector.GetMEPConnectorInfo().IsSecondary == false)); //sbFittings.AppendLine(); #endregion if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } if ((connector.GetMEPConnectorInfo().IsPrimary == false) && (connector.GetMEPConnectorInfo().IsSecondary == false)) { tertiaryConnector = connector; } } //Process endpoints of the component sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(EndWriter.WriteBP1(element, tertiaryConnector)); break; case ("REDUCER-CONCENTRIC"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; //Process endpoints of the component foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, secondaryConnector)); break; case ("REDUCER-ECCENTRIC"): goto case ("REDUCER-CONCENTRIC"); case ("FLANGE"): primaryConnector = null; secondaryConnector = null; tertiaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component //Secondary goes first because it is the weld neck point and the primary second because it is the flanged end //(dunno if it is significant); sbFittings.Append(EndWriter.WriteEP1(element, secondaryConnector)); sbFittings.Append(EndWriter.WriteEP2(element, primaryConnector)); break; case ("FLANGE-BLIND"): primaryConnector = null; foreach (Connector connector in connectorSet) { primaryConnector = connector; } //Connector information extraction sbFittings.Append(EndWriter.WriteEP1(element, primaryConnector)); XYZ endPointOriginFlangeBlind = primaryConnector.Origin; double connectorSizeFlangeBlind = primaryConnector.Radius; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it XYZ reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateUnbound(endPointOriginFlangeBlind, reverseConnectorVector); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { GeometryInstance instance = geometry as GeometryInstance; if (null != instance) { foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } // Get the faces foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; SetComparisonResult result = face.Intersect(detectorLine, out results); if (result == SetComparisonResult.Overlap) { intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(endPointOriginFlangeBlind) == false) { endPointAnalyzed = intersection; } } } } } } sbFittings.Append(EndWriter.WriteEP2(element, endPointAnalyzed, connectorSizeFlangeBlind)); break; case ("CAP"): goto case ("FLANGE-BLIND"); case ("OLET"): primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } XYZ endPointOriginOletPrimary = primaryConnector.Origin; XYZ endPointOriginOletSecondary = secondaryConnector.Origin; //get reference elements ConnectorSet refConnectors = primaryConnector.AllRefs; Element refElement = null; foreach (Connector c in refConnectors) { refElement = c.Owner; } Pipe refPipe = (Pipe)refElement; //Get connector set for the pipes ConnectorSet refConnectorSet = refPipe.ConnectorManager.Connectors; //Filter out non-end types of connectors IEnumerable <Connector> connectorEnd = from Connector connector in refConnectorSet where connector.ConnectorType.ToString() == "End" select connector; //Following code is ported from my python solution in Dynamo. //The olet geometry is analyzed with congruent rectangles to find the connection point on the pipe even for angled olets. XYZ B = endPointOriginOletPrimary; XYZ D = endPointOriginOletSecondary; XYZ pipeEnd1 = connectorEnd.First().Origin; XYZ pipeEnd2 = connectorEnd.Last().Origin; XYZ BDvector = D - B; XYZ ABvector = pipeEnd1 - pipeEnd2; double angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); if (angle > 90) { ABvector = -ABvector; angle = Conversion.RadianToDegree(ABvector.AngleTo(BDvector)); } Line refsLine = Line.CreateBound(pipeEnd1, pipeEnd2); XYZ C = refsLine.Project(B).XYZPoint; double L3 = B.DistanceTo(C); XYZ E = refsLine.Project(D).XYZPoint; double L4 = D.DistanceTo(E); double ratio = L4 / L3; double L1 = E.DistanceTo(C); double L5 = L1 / (ratio - 1); XYZ A; if (angle < 89) { XYZ ECvector = C - E; ECvector = ECvector.Normalize(); double L = L1 + L5; ECvector = ECvector.Multiply(L); A = E.Add(ECvector); #region Debug //Debug //Place family instance at points to debug the alorithm //StructuralType strType = (StructuralType)4; //FamilySymbol familySymbol = null; //FilteredElementCollector collector = new FilteredElementCollector(doc); //IEnumerable<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements(); //FamilySymbol marker = null; //foreach (Element e in collection) //{ // familySymbol = e as FamilySymbol; // if (null != familySymbol.Category) // { // if ("Structural Columns" == familySymbol.Category.Name) // { // break; // } // } //} //if (null != familySymbol) //{ // foreach (Element e in collection) // { // familySymbol = e as FamilySymbol; // if (familySymbol.FamilyName == "Marker") // { // marker = familySymbol; // Transaction trans = new Transaction(doc, "Place point markers"); // trans.Start(); // doc.Create.NewFamilyInstance(A, marker, strType); // doc.Create.NewFamilyInstance(B, marker, strType); // doc.Create.NewFamilyInstance(C, marker, strType); // doc.Create.NewFamilyInstance(D, marker, strType); // doc.Create.NewFamilyInstance(E, marker, strType); // trans.Commit(); // } // } //} #endregion } else { A = E; } angle = Math.Round(angle * 100); sbFittings.Append(EndWriter.WriteCP(A)); sbFittings.Append(EndWriter.WriteBP1(element, secondaryConnector)); sbFittings.Append(" ANGLE "); sbFittings.Append(Conversion.AngleToPCF(angle)); sbFittings.AppendLine(); break; } Composer elemParameterComposer = new Composer(); sbFittings.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (iv.ExportToCII) { sbFittings.Append(Composer.CIIWriter(doc, key)); } #endregion sbFittings.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbFittings.Append(element.UniqueId); sbFittings.AppendLine(); } //// Clear the output file //File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Fittings.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Fittings.pcf")) //{ // w.Write(sbFittings); // w.Close(); //} return(sbFittings); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { var uiapp = commandData.Application; var uidoc = uiapp.ActiveUIDocument; var doc = uidoc.Document; var sel = uidoc.Selection; var acview = doc.ActiveView; //filter target columntypes ElementFilter architectureColumnFilter = new ElementCategoryFilter(BuiltInCategory.OST_Columns); ElementFilter structuralColumnFilter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns); ElementFilter orfilter = new LogicalOrFilter(architectureColumnFilter, structuralColumnFilter); var collector = new FilteredElementCollector(doc); var columnstypes = collector.WhereElementIsElementType().WherePasses(orfilter).ToElements(); ColumnTypesForm typesform = ColumnTypesForm.Getinstance(columnstypes.ToList());//new ColumnTypesForm(columnstypes.ToList()); typesform.ShowDialog(RevitWindowHelper.GetRevitWindow()); //get selected familysymbol of combobox in columntypesForm var familysymbol = typesform.symbolCombo.SelectedItem as FamilySymbol; //varient for setting bottom and top /*for learners self modifing*/ var bottomlevel = default(Level); var bottomoffset = default(double); var toplevel = default(Level); var topoffset = default(double); var grids = doc.TCollector <Grid>(); var points = new List <XYZ>(); foreach (var grid in grids) { foreach (var grid1 in grids) { if (grid.Id == grid1.Id) { continue; } var curve1 = grid.Curve; var curve2 = grid1.Curve; var res = new IntersectionResultArray(); var intersecRes = curve1.Intersect(curve2, out res); if (intersecRes != SetComparisonResult.Disjoint) { if (res != null) { points.Add(res.get_Item(0).XYZPoint); } } } } //distinct points on same location points = points.Where((m, i) => points.FindIndex(n => n.IsAlmostEqualTo(m)) == i).ToList(); //MessageBox.Show(points.Count.ToString()); //CreateColumns as intersection point TransactionGroup tsg = new TransactionGroup(doc); tsg.Start("统一创建柱子"); foreach (var point in points) { doc.Invoke(m => { if (!familysymbol.IsActive) { familysymbol.Activate(); } var instance = doc.Create.NewFamilyInstance(point, familysymbol, acview.GenLevel, StructuralType.NonStructural); }, "创建柱子"); } tsg.Assimilate(); return(Result.Succeeded); }
/// <summary> /// Get the Insulation Layer of Right hand joined Walls /// </summary> public Tuple<Curve, Curve> handleJoinsRight(Document doc, LocationCurve wallLocCurve, Curve lower, Curve upper, ref List<int> bannedWalls) { Tuple<Curve, Curve> existing = new Tuple<Curve, Curve>(upper, lower); if (lower.GetType() == typeof(Arc) || lower.GetType() == typeof(NurbSpline)) return existing; if (upper.GetType() == typeof(Arc) || upper.GetType() == typeof(NurbSpline)) return existing; XYZ IntersectionPointLower = null; XYZ IntersectionPointUpper = null; ElementArray elems = wallLocCurve.get_ElementsAtJoin(1); if (elems == null || elems.Size == 0) return existing; foreach (Element elem in elems) { if (elem.GetType() == typeof(Wall)) { Wall wnext = (Wall)elem; if (!bannedWalls.Contains(wnext.Id.IntegerValue)) { Tuple<Curve, Curve> curves = getInsulationLayer(doc, wnext); Curve lowerunbound = lower.Clone(); lowerunbound.MakeUnbound(); Curve upperunbound = upper.Clone(); upperunbound.MakeUnbound(); Curve lowernext = curves.Item2.Clone(); lowernext.MakeUnbound(); IntersectionResultArray result = new IntersectionResultArray(); lowerunbound.Intersect(lowernext, out result); if (result != null && result.Size == 1) { IntersectionPointLower = result.get_Item(0).XYZPoint; } upperunbound.Intersect(lowernext, out result); if (result != null && result.Size == 1) { IntersectionPointUpper = result.get_Item(0).XYZPoint; } } } } if (IntersectionPointLower == null || IntersectionPointUpper == null) return existing; return new Tuple<Curve, Curve>(Line.CreateBound(upper.GetEndPoint(0), IntersectionPointUpper), Line.CreateBound(lower.GetEndPoint(0), IntersectionPointLower)); }
bool getIntersect(UV pt, Face otherFace, Face sourceface, double maxDistance, out IntersectionResultArray isRe, out double Distance, XYZ nv, Document doc) { var sp = sourceface.Evaluate(pt); var ray = Line.CreateBound(sp + nv * 0.01, sp + nv * 3); var ir = otherFace.Intersect(ray, out var isRes); isRe = isRes; Distance = maxDistance; if (isRes != null) { var itsr = isRes.OfType <IntersectionResult>().FirstOrDefault(); if (itsr != null && ir == SetComparisonResult.Overlap) { var dt = sp.DistanceTo(itsr.XYZPoint); Distance = dt; return(dt < maxDistance); } } return(false); }
public void ParseFrom(Element elm, MEPRevitGraphWriter writer) { var space = elm as Autodesk.Revit.DB.Mechanical.Space; if (space == null) { return; } if (space.Volume < 0.5) { return; } var scannedElements = writer.Cache.ParsedElements; var cpTree = writer.Cache.connectorsCache; var geoTree = writer.Cache.geoCache; var maxDepth = writer.Cache.MaxDepth; var graph = writer.Graph; var lvl = space.Level; if (lvl != null) { graph.AddConnection(elm, lvl, MEPPathConnectionType.Proximity, MEPEdgeTypes.IS_ON); } //get elements in the space //get areas with edges and add to walls var sbopt = new SpatialElementBoundaryOptions(); sbopt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish; sbopt.StoreFreeBoundaryFaces = true; //var geoOpt = new Options(); //var spgeo = space.get_Geometry(geoOpt); //get nearby spaces by extending bb of space //foreach each face of space geometry //split into uv gripd //construct line from each point //get intersect with faces on nearby faces //if it hits increment area count for direction var doc = space.Document; SpatialElementGeometryCalculator sg = new SpatialElementGeometryCalculator(doc, sbopt); var spgets = sg.CalculateSpatialElementGeometry(space); var spgeo = spgets.GetGeometry(); //var spbb = spgeo.GetBoundingBox(); var spbb = elm.get_BoundingBox(null); //var spbbhl = new HLBoundingBoxXYZ(spbb); //spbbhl.Size = spbbhl.Size + new XYZ(2, 2, 4); //get faces var uvdensity = 0.75; var maxDistance = 4D; //var nearbyFaces = nearbySpaces.OfType<SolidGeometrySegment>().Where(spc => spc.OriginatingElement != space.Id).SelectMany(sp => sp.Geometry.Faces.OfType<Face>()); var rayIncidents = new HashSet <FaceIntersectRay>(); //get all the faces in the geometry var spfaces = spgeo.Faces.OfType <Face>().ToList(); foreach (var gface in spfaces) { //extract the faces which bound with other elements (Walls, floors, ceilings, windows etc) var sfaceInfos = spgets.GetBoundaryFaceInfo(gface); foreach (var sfaceInfo in sfaceInfos) { //get the geo face and element of this bounding face var sface = sfaceInfo.GetSubface(); var elmId = sfaceInfo.SpatialBoundaryElement; var lelm = GetElementFromLinkedElement(elmId, doc); var docIdent = string.Empty; //if (lelm == null) continue; //ignore this face if it doesn't resolve to a valid element //find the bounding uv box so we can work out a grid of points var fbb = sface.GetBoundingBox(); var uExt = uvdensity; // (fbb.Max.U - fbb.Min.U) / uvdensity; var vExt = uvdensity; // (fbb.Max.V - fbb.Min.V) / uvdensity; var u = fbb.Min.U; var v = fbb.Min.V; //var sb = new GeoLib.C2DPolygon(); //construct grid for ray tracing Stack <UV> gridPoints = new Stack <UV>(); while (u <= fbb.Max.U) { v = fbb.Min.V; while (v <= fbb.Max.V) { var uvp = new UV(u, v); v += uvdensity; if (!sface.IsInside(uvp)) { continue; //only include points that are actually on this face } gridPoints.Push(uvp); } u += uvdensity; } var nerbyCheckCats = new int[] { }; IList <ElementId> hostElms = new List <ElementId>(); if (lelm != null && !(lelm is HostObject)) { var n = lelm; } if (lelm != null) { docIdent = DocUtils.GetDocumentIdent(lelm.Document); //get cutting elemtns if it's a wall so we can find door and windows if (lelm is HostObject) { var whost = lelm as HostObject; hostElms = whost.FindInserts(true, true, true, true); //build oct tree of hostelems so we can quickly ray trace them later foreach (var hostElm in hostElms) { //ignoring any link and transform for now var ehl = whost.Document.GetElement(hostElm); writer.Cache.geoCacheWriter.AddElement(ehl, true); } } //we need the nearby check to find the cut out elements nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows }; } else { nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Walls, (int)BuiltInCategory.OST_Roofs }; //we need the nearby check to find the bounding element switch (sfaceInfo.SubfaceType) { case SubfaceType.Bottom: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Floors }; break; case SubfaceType.Top: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Roofs, (int)BuiltInCategory.OST_Floors, (int)BuiltInCategory.OST_Windows }; break; case SubfaceType.Side: nerbyCheckCats = new int[] { (int)BuiltInCategory.OST_Doors, (int)BuiltInCategory.OST_Windows, (int)BuiltInCategory.OST_Walls }; break; } } //option 1 - brute force ray trace //option 2 - construct 2d polygon from edges of each face, translate each face into the same plane, then boolean intersect, get area of each intersect //calc space boundaries at midpoint? Face optLastIntermeidateFace = null; SolidGeometrySegment optLastIntermeidateSegment = null; Face optLastHitFace = null; SolidGeometrySegment optLastHitSegment = null; var arWeight = sface.Area / gridPoints.Count; while (gridPoints.Count > 0) { var pt = gridPoints.Pop(); var rayIncident = new FaceIntersectRay(); var nv = sface.ComputeNormal(pt).Normalize(); //var mx = sface.ComputeSecondDerivatives(pt).MixedDerivative.Normalize(); rayIncident.SourceElement = space; rayIncident.SourceFace = sface; rayIncident.SourceUV = pt; rayIncident.RayVecotor = nv; rayIncident.IntermediatDocIdent = docIdent; rayIncident.IntermeidateElement = lelm != null ? lelm.Id : ElementId.InvalidElementId; rayIncident.AreaWeight = arWeight; rayIncident.SubFaceType = sfaceInfo.SubfaceType; rayIncidents.Add(rayIncident); var sp = sface.Evaluate(pt); rayIncident.SourceXYZ = sp; var ray = Line.CreateBound(sp, sp + nv * 4); var rayBB = new HLBoundingBoxXYZ(sp, (sp + nv * 4), true); //rayBB.Size = rayBB.Size + new XYZ(0.5, 0.5, 0.5); //Plane geoPlane = Plane.c(sp, sp + nv * 5, sp + nv * 5 + (mx * 0.2)); //SketchPlane skPlane = SketchPlane.Create(doc, geoPlane); //doc.Create.NewModelCurve(ray, skPlane); //check cache for hit on otherside, if there is one nearby on this face we can ignore it as we're not including both sides //var nearbyrayHits = writer.Cache.rayhitCache.GetNearby(ray, 0.4F); //var validSimilarHit = nearbyrayHits.FirstOrDefault(rh => rh.HittingSegment != null && rh.HittingSegment.OriginatingElement == space.Id && rh.IntermeidateElement == rayIncident.IntermeidateElement); //if (validSimilarHit != null && sface.IsInside(validSimilarHit.HittingUV)) //{ // rayIncident.Ignore = true; // log.Info("Got hit on other side, ignoring"); // continue; // } if (optLastIntermeidateFace != null) { IntersectionResultArray issRes = null; var issGeoHit = getIntersect(pt, optLastIntermeidateFace, sface, maxDistance, out issRes, out double distance, nv, doc); if (issGeoHit) { rayIncident.IntermediatDocIdent = optLastIntermeidateSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = optLastIntermeidateSegment.OriginatingElement; } else { optLastIntermeidateFace = null; optLastIntermeidateSegment = null; } } GeometrySegment[] nearbyElements = null; if (optLastIntermeidateFace == null) { nearbyElements = geoTree.GetColliding(rayBB); var nearbyCutoutElements = nearbyElements.Where(iel => (hostElms.Count == 0 || hostElms.Contains(iel.OriginatingElement)) && nerbyCheckCats.Contains(iel.OriginatingElementCategory.IntegerValue)) .OfType <SolidGeometrySegment>(); IntersectionResultArray isRes = null; bool isGeoHit = false; foreach (var extSegment in nearbyCutoutElements) { foreach (var extFace in extSegment.Geometry.Faces.OfType <Face>()) { isGeoHit = getIntersect(pt, extFace, sface, maxDistance, out isRes, out double distance, nv, doc); if (isGeoHit) { rayIncident.IntermediatDocIdent = extSegment.OriginatingDocIdent; rayIncident.IntermeidateElement = extSegment.OriginatingElement; optLastIntermeidateFace = extFace; optLastIntermeidateSegment = extSegment; break; } } if (isGeoHit) { break; } } } if (optLastHitFace != null) { var isHit = getIntersect(pt, optLastHitFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = optLastHitFace.Project(srcXYZ); if (isHit) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = optLastHitFace; rayIncident.HittingSegment = optLastHitSegment; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); continue; //shortcut if we find a hit on the same face again } else { optLastHitFace = null; optLastHitSegment = null; } } if (nearbyElements == null) { nearbyElements = geoTree.GetColliding(rayBB, (ob) => { return(ob.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces); }); } //BoundingBoxIntersectsFilter bif = new BoundingBoxIntersectsFilter(new Outline(sp - new XYZ(0.1, 0.1, 0.1), (sp + nv * 2) + new XYZ(0.1, 0.1, 0.1))); //var sfv = new FilteredElementCollector(space.Document); //var sepl = sfv.WherePasses(bif).ToElements(); var nearbySpaces = nearbyElements.Where(ne => ne.OriginatingElementCategory.IntegerValue == (int)BuiltInCategory.OST_MEPSpaces).OfType <SolidGeometrySegment>().Distinct().ToList(); //find the extents of this face which face faces on other nearby faces (whaaat?) //check each face of each nearby space for intersect with ray foreach (var nearSpace in nearbySpaces) { var isHit = false; foreach (var otFace in nearSpace.Geometry.Faces.OfType <Face>()) { isHit = getIntersect(pt, otFace, sface, maxDistance, out var isRe, out double distance, nv, doc); var isRes = isRe; //project point onto other face instead? var srcXYZ = sface.Evaluate(pt); var otXYZRes = otFace.Project(srcXYZ); if (isHit) { if (nearSpace.OriginatingElement.IntegerValue != elm.Id.IntegerValue) { var itx = isRes.OfType <IntersectionResult>().FirstOrDefault(); rayIncident.HittingFace = otFace; rayIncident.HittingSegment = nearSpace; rayIncident.HittingUV = itx.UVPoint; rayIncident.HittingXYZ = itx.XYZPoint; rayIncident.Distance = distance; nv = sface.ComputeNormal(pt).Normalize(); //optimization: check this face again first for the next ray check, since it's likely to be another hit optLastHitFace = otFace; optLastHitSegment = nearSpace; rayIncident.Ignore = false; } else { if (distance < 0.1) { isHit = false; //looks like we hit our own face, ouch! } rayIncident.Ignore = true; } break; } } if (isHit) { break; } } } } /* * space * face * intermediate element (Wall/window/door) * face (space) * face * * * add connection * this space -> section -> other space * wall ------------^ */ } //var ec = new elmComparer(); var srcNode = graph.AddElement(space); double minIncluedArea = 4; VectorBucketiser vbw = new VectorBucketiser(8, 5); var includeRays = rayIncidents.Where(r => !r.Ignore); var outsideNode = graph.Nodes.FirstOrDefault(n => n.Name == "Outside"); var groundNode = graph.Nodes.FirstOrDefault(n => n.Name == "Ground"); //group by the intermediate element (wall/floor/etc) foreach (var docGroup in includeRays.GroupBy(ri => ri.IntermediatDocIdent))//, ec)) { var sdoc = DocUtils.GetDocument(docGroup.Key, elm.Document.Application); foreach (var intermediateElemGroup in docGroup.GroupBy(ri => ri.IntermeidateElement.IntegerValue))//, ec)) { var selmid = new ElementId(intermediateElemGroup.Key); Element selm = sdoc != null?sdoc.GetElement(selmid) : null; //group similar vectors into buckets foreach (var rayVectorBuckets in intermediateElemGroup.GroupBy(ri => vbw.GetBucket(ri.RayVecotor))) { var rg = rayVectorBuckets.ToList(); var gs = rg.GroupBy(vr => vr.HittingSegment == null ? null : vr.HittingSegment.OriginatingElement).ToList(); //group each vector and intermediate element by the element it hits foreach (var orgElmGroup in gs) { //find a section already matching this section //actually easier to treat each path as separate sections //var edNodes = graph.GetEdges(intermediateElemGroup.Key).Where(ed => ed.NextNode.AsAbstractNode.Name == "Surface" //&& ed.NextNode.Connections.Any(cn => cn.NextNode.OriginId == spNode.OriginId)).Where(ed => ed.; var apporxIntersect = orgElmGroup.Sum(et => et.AreaWeight); var vector = orgElmGroup.First().RayVecotor; if (apporxIntersect < minIncluedArea) { continue; } var direction = VectorBucketiser.GetZeroClamppedPoint(orgElmGroup.First().RayVecotor); //should be rayVectorGroup.Key.AverageVector, but not yet implemented; MEPRevitNode spNode = null; if (orgElmGroup.Key != null) { var otherSpace = doc.GetElement(orgElmGroup.Key); spNode = graph.AddElement(otherSpace); } else { if (selm != null && (selm.Name.ToLower().Contains("exterior") || selm is Autodesk.Revit.DB.Opening || selm.Name.ToLower().Contains("window") || selm is Autodesk.Revit.DB.RoofBase)) { if (outsideNode == null) { outsideNode = new MEPRevitNode("Outside", "Boundary", "OutsideBoundary", new MEPGraph.Model.Environment()); } spNode = outsideNode; } else if (selm != null && (selm.Name.ToLower().Contains("floor") || selm is Autodesk.Revit.DB.Floor)) { if (groundNode == null) { groundNode = new MEPRevitNode("Ground", "Boundary", "GroundBoundary", new MEPGraph.Model.Environment()); } spNode = groundNode; } else { spNode = new MEPRevitNode("Void", "Boundary", "OtherBoundary", new MEPGraph.Model.VoidVolume()); continue; //ignore void boundaries for now } } var sectionN = graph.NewSection(selm, MEPGraph.Model.MEPEdgeTypes.IS_ON); if (selm == null) { var emptyBondary = new MEPRevitNode(); emptyBondary.AsAbstractNode.Name = "OpenBoundary"; var cl = graph.AddConnection(emptyBondary, sectionN, MEPPathConnectionType.SectionOf, MEPGraph.Model.MEPEdgeTypes.IS_ON); cl.AsNodeEdge.ExtendedProperties.Add("rvid", intermediateElemGroup.Key); } sectionN.AsAbstractNode.Name = "Surface"; var edgesf = graph.AddConnection(srcNode, sectionN, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); //total up intersecting area var sampleIntersect = orgElmGroup.First(); edgesf.SetWeight("Area", apporxIntersect); //edgesf.SetWeight("Direction", new HoareLea.MEPGraph.Model.MEPPoint(direction.X, direction.Y, direction.Z)); edgesf.SetWeight("DirectionX", direction.X); edgesf.SetWeight("DirectionY", direction.Y); edgesf.SetWeight("DirectionZ", direction.Z); edgesf.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); /* * HLBoundingBoxXYZ bb = new HLBoundingBoxXYZ(); * foreach (var et in orgElmGroup) * { * if (et.HittingXYZ != null) * { * bb.ExpandToContain(et.HittingXYZ); * } * } * if (!bb.IsInvalid) * { * sectionN.BoundingBox = bb; * var avgCenterPoint = bb.MidPoint; * var size = bb.Size; * sectionN.SetProperty("OriginX", avgCenterPoint.X); * sectionN.SetProperty("OriginY", avgCenterPoint.Y); * sectionN.SetProperty("OriginZ", avgCenterPoint.Z); * sectionN.SetProperty("SizeX", size.X); * sectionN.SetProperty("SizeY", size.Y); * sectionN.SetProperty("SizeZ", size.Z); * }*/ var edgest = graph.AddConnection(sectionN, spNode, MEPPathConnectionType.Analytical, MEPGraph.Model.MEPEdgeTypes.BOUNDED_BY); var directionn = direction;//.Negate(); edgest.SetWeight("Area", apporxIntersect); edgest.SetWeight("DirectionX", directionn.X); edgest.SetWeight("DirectionY", directionn.Y); edgest.SetWeight("DirectionZ", directionn.Z); edgest.SetWeight("SubFaceType", (int)sampleIntersect.SubFaceType); } } } } }
protected void getEndPointsWithSingleConnector(Autodesk.Revit.DB.Element element) { //First End Point ConnectorSet connectorSet = connectorSet = (element as FamilyInstance).MEPModel.ConnectorManager.Connectors; Connector connector = connectorSet.Cast <Connector>().First(); this.KeyPoints.Add(new DataType.ExternalKeyPoint(DataType.KeypointType.END, connector.Origin, connector.Radius, this.getEndtype(element, RevitParam.ParameterName.Primary_Endtype))); //Second End Point XYZ endPointOrigin = connector.Origin; double connectorSize = connector.Radius; //Connector의 Second End Point를 구하기 위해, Connector의 Normal Vector를 활용한다. XYZ normalVector = connector.CoordinateSystem.BasisZ.Negate(); Line normalLine = Line.CreateUnbound(endPointOrigin, normalVector); //Geometry와 Normal Line이 교차하는 지점이 있는지 확인한다. Options opt = new Options(); opt.DetailLevel = ViewDetailLevel.Fine; GeometryElement geometryElement = (element as FamilyInstance).get_Geometry(opt); //Prepare resulting point XYZ epSecondary = null; foreach (GeometryObject geometry in geometryElement) { GeometryInstance instance = geometry as GeometryInstance; if (null == instance) { continue; } foreach (GeometryObject instanceObject in instance.GetInstanceGeometry()) { Solid solid = instanceObject as Solid; if (solid == null || 0 == solid.Faces.Size) { continue; } //각 면을 체크하며, Connector의 Normal Vector과 겹치는지 확인 foreach (Face face in solid.Faces) { IntersectionResultArray results = null; SetComparisonResult result = face.Intersect(normalLine, out results); if (result == SetComparisonResult.Overlap) { foreach (IntersectionResult intersectionResult in results) { //Connector Point가 아니라면! if (intersectionResult.XYZPoint.IsAlmostEqualTo(endPointOrigin) == false) { epSecondary = intersectionResult.XYZPoint; break; } } if (epSecondary != null) { break; } } } if (epSecondary != null) { break; } } } //만약, EndPoint를 찾지 못했다면! if (epSecondary == null) { throw new Exception("Fail: Get Secondary End Point from Single Connector Calculation Error."); } this.KeyPoints.Add(new DataType.ExternalKeyPoint(DataType.KeypointType.END, epSecondary, connectorSize, this.getEndtype(element, RevitParam.ParameterName.Secondary_Endtype))); }
public override Value Evaluate(FSharpList<Value> args) { var crv = (Curve)((Value.Container)args[0]).Item; Face face = null; Solid tempSolid = null; Plane thisPlane = null; if (((Value.Container)args[1]).Item is Face) face = (Autodesk.Revit.DB.Face)((Value.Container)args[1]).Item; else if (((Value.Container)args[1]).Item is Plane) { thisPlane = ((Value.Container)args[1]).Item as Plane; // tesselate curve and find uv envelope in projection to the plane IList<XYZ> tessCurve = crv.Tessellate(); var curvePointEnum = tessCurve.GetEnumerator(); XYZ corner1 = new XYZ(); XYZ corner2 = new XYZ(); bool cornersSet = false; for (; curvePointEnum.MoveNext(); ) { if (!cornersSet) { corner1 = curvePointEnum.Current; corner2 = curvePointEnum.Current; cornersSet = true; } else { for (int coord = 0; coord < 3; coord++) { if (corner1[coord] > curvePointEnum.Current[coord]) corner1 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner1[coord], coord == 1 ? curvePointEnum.Current[coord] : corner1[coord], coord == 2 ? curvePointEnum.Current[coord] : corner1[coord]); if (corner2[coord] < curvePointEnum.Current[coord]) corner2 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner2[coord], coord == 1 ? curvePointEnum.Current[coord] : corner2[coord], coord == 2 ? curvePointEnum.Current[coord] : corner2[coord]); } } } double dist1 = thisPlane.Origin.DistanceTo(corner1); double dist2 = thisPlane.Origin.DistanceTo(corner2); double sizeRect = 2.0 * (dist1 + dist2) + 100.0; CurveLoop cLoop = new CurveLoop(); for (int index = 0; index < 4; index++) { double coord0 = (index == 0 || index == 3) ? -sizeRect : sizeRect; double coord1 = (index < 2) ? -sizeRect : sizeRect; XYZ pnt0 = thisPlane.Origin + coord0 * thisPlane.XVec + coord1 * thisPlane.YVec; double coord3 = (index < 2) ? sizeRect : -sizeRect; double coord4 = (index == 0 || index == 3) ? -sizeRect : sizeRect; XYZ pnt1 = thisPlane.Origin + coord3 * thisPlane.XVec + coord4 * thisPlane.YVec; Line cLine = dynRevitSettings.Revit.Application.Create.NewLineBound(pnt0, pnt1); cLoop.Append(cLine); } List<CurveLoop> listCLoops = new List<CurveLoop> (); listCLoops.Add(cLoop); tempSolid = GeometryCreationUtilities.CreateExtrusionGeometry(listCLoops, thisPlane.Normal, 100.0); //find right face FaceArray facesOfExtrusion = tempSolid.Faces; for (int indexFace = 0; indexFace < facesOfExtrusion.Size; indexFace++) { Face faceAtIndex = facesOfExtrusion.get_Item(indexFace); if (faceAtIndex is PlanarFace) { PlanarFace pFace = faceAtIndex as PlanarFace; if (Math.Abs(thisPlane.Normal.DotProduct(pFace.Normal)) < 0.99) continue; if (Math.Abs(thisPlane.Normal.DotProduct(thisPlane.Origin - pFace.Origin)) > 0.1) continue; face = faceAtIndex; break; } } if (face == null) throw new Exception("Curve Face Intersection could not process supplied Plane."); } IntersectionResultArray xsects = new IntersectionResultArray(); SetComparisonResult result = face.Intersect(crv, out xsects); var xsect_results = FSharpList<Value>.Empty; var results = FSharpList<Value>.Empty; if (xsects != null) { foreach (IntersectionResult ir in xsects) { var xsect = FSharpList<Value>.Empty; try { xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.EdgeParameter), xsect); } catch { xsect = FSharpList<Value>.Cons(Value.NewNumber(0), xsect); } xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.EdgeObject), xsect); xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.Parameter), xsect); if (thisPlane != null) { UV planeUV = new UV(thisPlane.XVec.DotProduct(ir.XYZPoint - thisPlane.Origin), thisPlane.YVec.DotProduct(ir.XYZPoint - thisPlane.Origin)); xsect = FSharpList<Value>.Cons(Value.NewContainer(planeUV), xsect); } else xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.UVPoint), xsect); xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.XYZPoint), xsect); xsect_results = FSharpList<Value>.Cons(Value.NewList(xsect), xsect_results); } } results = FSharpList<Value>.Cons(Value.NewList(xsect_results), results); results = FSharpList<Value>.Cons(Value.NewString(result.ToString()), results); return Value.NewList(results); }
static internal XYZ AdjustTopPointToRoofAngle(XYZ targetTopPoint, IList <XYZ> supportPoints, EdgeInfo currentRidgeInfo) { if (currentRidgeInfo.RelatedPanelFaces == null || currentRidgeInfo.RelatedPanelFaces.Count < 1) { currentRidgeInfo.RelatedPanelFaces = currentRidgeInfo.GetRelatedPanels(); } if (currentRidgeInfo.RelatedPanelFaces == null || currentRidgeInfo.RelatedPanelFaces.Count < 1) { return(targetTopPoint); } PlanarFace relatedFace = currentRidgeInfo.RelatedPanelFaces[0] as PlanarFace; if (relatedFace == null) { return(targetTopPoint); } Line ridgeLine = currentRidgeInfo.Curve as Line; if (ridgeLine == null) { return(targetTopPoint); } XYZ ridgeDirection = ridgeLine.Direction; XYZ ridgeDirectionCrossed = ridgeDirection.CrossProduct(XYZ.BasisZ); XYZ projectedPoint = targetTopPoint.Add(ridgeDirectionCrossed.Multiply(0.1)); IntersectionResult iResult = relatedFace.Project(projectedPoint); if (iResult == null) { projectedPoint = targetTopPoint.Add(ridgeDirectionCrossed.Negate().Multiply(0.1)); iResult = relatedFace.Project(projectedPoint); if (iResult == null) { return(targetTopPoint); } } //Just to make sure that the targetTopPoint is located on Ridge IntersectionResult ridgeProjected = ridgeLine.Project(targetTopPoint); if (ridgeProjected != null) { targetTopPoint = ridgeProjected.XYZPoint; } XYZ roofSlopeLineDirection = Line.CreateBound(iResult.XYZPoint, targetTopPoint).Direction; if (supportPoints == null || supportPoints.Count < 1) { return(targetTopPoint); } //This code assumes that there are 1 or 2 supportPoints XYZ supportPoint = supportPoints[0]; if (supportPoints.Count == 2) { XYZ supportPoints1 = supportPoints[1]; if (supportPoints1.DistanceTo(projectedPoint) < supportPoint.DistanceTo(projectedPoint)) { supportPoint = supportPoints1; } } Line roofSlopeLine = Line.CreateUnbound(supportPoint, roofSlopeLineDirection); Line roofRidgeLine = Line.CreateUnbound(targetTopPoint, XYZ.BasisZ); IntersectionResultArray iResultArrCurves = null; roofSlopeLine.Intersect(roofRidgeLine, out iResultArrCurves); if (iResultArrCurves != null && iResultArrCurves.Size == 1) { return(iResultArrCurves.get_Item(0).XYZPoint); } return(targetTopPoint); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; View acview = uidoc.ActiveView; var chamferDis = 300d; //倒角距离 var ref1 = sel.PickObject(ObjectType.Element, doc.GetSelectionFilter(m => m is Pipe)); var ref2 = sel.PickObject(ObjectType.Element, doc.GetSelectionFilter(m => m is Pipe)); var pipe1 = ref1.GetElement(doc) as Pipe; var pipe2 = ref2.GetElement(doc) as Pipe; var pickpoint1 = ref1.GlobalPoint; var pickpoint2 = ref2.GlobalPoint; var line1 = (pipe1.Location as LocationCurve).Curve as Line; var line2 = (pipe2.Location as LocationCurve).Curve as Line; //取得拾取点在管道轴线上的投影点 pickpoint1 = pickpoint1.ProjectToXLine(line1); pickpoint2 = pickpoint2.ProjectToXLine(line2); var line1copy = line1.Clone(); var line2copy = line2.Clone(); line1copy.MakeUnbound(); line2copy.MakeUnbound(); //取得交点 var intersectionresult = default(IntersectionResult); IntersectionResultArray resultarr = default(IntersectionResultArray); var comparisonResult = line1copy.Intersect(line2copy, out resultarr); if (comparisonResult != SetComparisonResult.Disjoint) { intersectionresult = resultarr.get_Item(0); } var intersection = intersectionresult.XYZPoint; var dir1 = (pickpoint1 - intersection).Normalize(); var dir2 = (pickpoint2 - intersection).Normalize(); var chamferpoint1 = intersection + dir1 * chamferDis.MetricToFeet(); var chamferpoint2 = intersection + dir2 * chamferDis.MetricToFeet(); Transaction ts = new Transaction(doc, "管线倒角"); try { ts.Start(); pipe1 = changeSizeOfpipe(pipe1, dir1, chamferpoint1); pipe2 = changeSizeOfpipe(pipe2, dir2, chamferpoint2); var resultpipeid = ElementTransformUtils.CopyElements(doc, new Collection <ElementId>() { pipe1.Id }, new XYZ()).First(); var resultpipe = resultpipeid.GetElement(doc) as Pipe; (resultpipe.Location as LocationCurve).Curve = Line.CreateBound(chamferpoint1, chamferpoint2); //连接管道 var con1 = pipe1.ConnectorManager.Connectors.Cast <Connector>().Where(m => m?.Origin != null && m.Origin.IsAlmostEqualTo(chamferpoint1)).First(); var con2 = resultpipe.ConnectorManager.Connectors.Cast <Connector>().Where(m => m?.Origin != null && m.Origin.IsAlmostEqualTo(chamferpoint1)).First(); doc.Create.NewElbowFitting(con1, con2); var con3 = pipe2.ConnectorManager.Connectors.Cast <Connector>().Where(m => m?.Origin != null && m.Origin.IsAlmostEqualTo(chamferpoint2)).First(); var con4 = resultpipe.ConnectorManager.Connectors.Cast <Connector>().Where(m => m?.Origin != null && m.Origin.IsAlmostEqualTo(chamferpoint2)).First(); doc.Create.NewElbowFitting(con3, con4); ts.Commit(); } catch (Exception) { if (ts.GetStatus() == TransactionStatus.Started) { ts.RollBack(); } //throw; } return(Result.Succeeded); }
/// <summary> /// Get the Insulation Layer of Left hand joined Walls /// </summary> public Curve handleJoinsLeft(Document doc, LocationCurve wallLocCurve, Curve lower, ref List<int> bannedWalls) { if (lower.GetType() == typeof(Arc) || lower.GetType() == typeof(NurbSpline)) return lower; XYZ IntersectionPoint = null; ElementArray elems = wallLocCurve.get_ElementsAtJoin(0); if (elems == null || elems.Size == 0) return lower; foreach (Element elem in elems) { if (elem.GetType() == typeof(Wall)) { Wall wnext = (Wall)elem; if (!bannedWalls.Contains(wnext.Id.IntegerValue)) { Tuple<Curve, Curve> curves = getInsulationLayer(doc, wnext); Curve lowerunbound = lower.Clone(); lowerunbound.MakeUnbound(); Curve upper = curves.Item1.Clone(); upper.MakeUnbound(); IntersectionResultArray result = new IntersectionResultArray(); lowerunbound.Intersect(upper, out result); if (result != null && result.Size == 1) { IntersectionPoint = result.get_Item(0).XYZPoint; } } } } if (IntersectionPoint == null) return lower; Line l = Line.CreateBound(IntersectionPoint, lower.GetEndPoint(1)); return l; }
public override Value Evaluate(FSharpList<Value> args) { var crv = (Curve)((Value.Container)args[0]).Item; var face = (Autodesk.Revit.DB.Face)((Value.Container)args[1]).Item; IntersectionResultArray xsects = new IntersectionResultArray(); SetComparisonResult result = face.Intersect(crv, out xsects); var xsect_results = FSharpList<Value>.Empty; var results = FSharpList<Value>.Empty; if (xsects != null) { foreach (IntersectionResult ir in xsects) { var xsect = FSharpList<Value>.Empty; try { xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.EdgeParameter), xsect); } catch { xsect = FSharpList<Value>.Cons(Value.NewNumber(0), xsect); } xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.EdgeObject), xsect); xsect = FSharpList<Value>.Cons(Value.NewNumber(ir.Parameter), xsect); xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.UVPoint), xsect); xsect = FSharpList<Value>.Cons(Value.NewContainer(ir.XYZPoint), xsect); xsect_results = FSharpList<Value>.Cons(Value.NewList(xsect), xsect_results); } } results = FSharpList<Value>.Cons(Value.NewList(xsect_results), results); results = FSharpList<Value>.Cons(Value.NewString(result.ToString()), results); return Value.NewList(results); }
// This routine may return null geometry for one of three reasons: // 1. Invalid input. // 2. No IfcMaterialLayerUsage. // 3. The IfcMaterialLayerUsage isn't handled. // If the reason is #1 or #3, we want to warn the user. If it is #2, we don't. Pass back shouldWarn to let the caller know. private IList <GeometryObject> CreateGeometryFromMaterialLayerUsage(IFCImportShapeEditScope shapeEditScope, Transform extrusionPosition, IList <CurveLoop> loops, XYZ extrusionDirection, double currDepth, out ElementId materialId, out bool shouldWarn) { IList <GeometryObject> extrusionSolids = null; materialId = ElementId.InvalidElementId; try { shouldWarn = true; // Invalid input. // Check for valid input. if (shapeEditScope == null || extrusionPosition == null || loops == null || loops.Count() == 0 || extrusionDirection == null || !Application.IsValidThickness(currDepth)) { return(null); } IFCProduct creator = shapeEditScope.Creator; if (creator == null) { return(null); } shouldWarn = false; // Missing, empty, or optimized out IfcMaterialLayerSetUsage - valid reason to stop. IIFCMaterialSelect materialSelect = creator.MaterialSelect; if (materialSelect == null) { return(null); } IFCMaterialLayerSetUsage materialLayerSetUsage = materialSelect as IFCMaterialLayerSetUsage; if (materialLayerSetUsage == null) { return(null); } IFCMaterialLayerSet materialLayerSet = materialLayerSetUsage.MaterialLayerSet; if (materialLayerSet == null) { return(null); } IList <IFCMaterialLayer> materialLayers = materialLayerSet.MaterialLayers; if (materialLayers == null || materialLayers.Count == 0) { return(null); } // Optimization: if there is only one layer, use the standard method, with possibly an overloaded material. ElementId baseMaterialId = GetMaterialElementId(shapeEditScope); if (materialLayers.Count == 1) { IFCMaterial oneMaterial = materialLayers[0].Material; if (oneMaterial == null) { return(null); } materialId = oneMaterial.GetMaterialElementId(); if (materialId != ElementId.InvalidElementId) { // We will not override the material of the element if the layer material has no color. if (Importer.TheCache.MaterialsWithNoColor.Contains(materialId)) { materialId = ElementId.InvalidElementId; } } return(null); } // Anything below here is something we should report to the user, with the exception of the total thickness // not matching the extrusion thickness. This would require more analysis to determine that it is actually // an error condition. shouldWarn = true; IList <IFCMaterialLayer> realMaterialLayers = new List <IFCMaterialLayer>(); double totalThickness = 0.0; foreach (IFCMaterialLayer materialLayer in materialLayers) { double depth = materialLayer.LayerThickness; if (MathUtil.IsAlmostZero(depth)) { continue; } if (depth < 0.0) { return(null); } realMaterialLayers.Add(materialLayer); totalThickness += depth; } // Axis3 means that the material layers are stacked in the Z direction. This is common for floor slabs. bool isAxis3 = (materialLayerSetUsage.Direction == IFCLayerSetDirection.Axis3); // For elements extruded in the Z direction, if the extrusion layers don't have the same thickness as the extrusion, // this could be one of two reasons: // 1. There is a discrepancy between the extrusion depth and the material layer set usage calculated depth. // 2. There are multiple extrusions in the body definition. // In either case, we will use the extrusion geometry over the calculated material layer set usage geometry. // In the future, we may decide to allow for case #1 by passing in a flag to allow for this. if (isAxis3 && !MathUtil.IsAlmostEqual(totalThickness, currDepth)) { shouldWarn = false; return(null); } int numLayers = realMaterialLayers.Count(); if (numLayers == 0) { return(null); } // We'll use this initial value for the Axis2 case, so read it here. double baseOffsetForLayer = materialLayerSetUsage.Offset; // Needed for Axis2 case only. The axisCurve is the curve defined in the product representation representing // a base curve (an axis) for the footprint of the element. Curve axisCurve = null; // The oriented cuve list represents the 4 curves of supported Axis2 footprint in the following order: // 1. curve along length of object closest to the first material layer with the orientation of the axis curve // 2. connecting end curve // 3. curve along length of object closest to the last material layer with the orientation opposite of the axis curve // 4. connecting end curve. IList <Curve> orientedCurveList = null; if (!isAxis3) { // Axis2 means that the material layers are stacked inthe Y direction. This is by definition for IfcWallStandardCase, // which has a local coordinate system whose Y direction is orthogonal to the length of the wall. if (materialLayerSetUsage.Direction == IFCLayerSetDirection.Axis2) { axisCurve = GetAxisCurve(creator, extrusionPosition); if (axisCurve == null) { return(null); } orientedCurveList = GetOrientedCurveList(loops, axisCurve, extrusionPosition.BasisZ, baseOffsetForLayer, totalThickness); if (orientedCurveList == null) { return(null); } } else { return(null); // Not handled. } } extrusionSolids = new List <GeometryObject>(); bool positiveOrientation = (materialLayerSetUsage.DirectionSense == IFCDirectionSense.Positive); // Always extrude in the positive direction for Axis2. XYZ materialExtrusionDirection = (positiveOrientation || !isAxis3) ? extrusionDirection : -extrusionDirection; // Axis2 repeated values. // The IFC concept of offset direction is reversed from Revit's. XYZ normalDirectionForAxis2 = positiveOrientation ? -extrusionPosition.BasisZ : extrusionPosition.BasisZ; bool axisIsCyclic = (axisCurve == null) ? false : axisCurve.IsCyclic; double axisCurvePeriod = axisIsCyclic ? axisCurve.Period : 0.0; Transform curveLoopTransform = Transform.Identity; IList <CurveLoop> currLoops = null; double depthSoFar = 0.0; for (int ii = 0; ii < numLayers; ii++) { IFCMaterialLayer materialLayer = materialLayers[ii]; // Ignore 0 thickness layers. No need to warn. double depth = materialLayer.LayerThickness; if (MathUtil.IsAlmostZero(depth)) { continue; } // If the thickness is non-zero but invalid, fail. if (!Application.IsValidThickness(depth)) { return(null); } double extrusionDistance = 0.0; if (isAxis3) { // Offset the curve loops if necessary, using the base extrusionDirection, regardless of the direction sense // of the MaterialLayerSetUsage. double offsetForLayer = positiveOrientation ? baseOffsetForLayer + depthSoFar : baseOffsetForLayer - depthSoFar; if (!MathUtil.IsAlmostZero(offsetForLayer)) { curveLoopTransform.Origin = offsetForLayer * extrusionDirection; currLoops = new List <CurveLoop>(); foreach (CurveLoop loop in loops) { CurveLoop newLoop = CurveLoop.CreateViaTransform(loop, curveLoopTransform); if (newLoop == null) { return(null); } currLoops.Add(newLoop); } } else { currLoops = loops; } extrusionDistance = depth; } else { // startClipCurve, firstEndCapCurve, endClipCurve, secondEndCapCurve. Curve[] outline = new Curve[4]; double[][] endParameters = new double[4][]; double startClip = depthSoFar; double endClip = depthSoFar + depth; outline[0] = orientedCurveList[0].CreateOffset(startClip, normalDirectionForAxis2); outline[1] = orientedCurveList[1].Clone(); outline[2] = orientedCurveList[2].CreateOffset(totalThickness - endClip, normalDirectionForAxis2); outline[3] = orientedCurveList[3].Clone(); for (int jj = 0; jj < 4; jj++) { outline[jj].MakeUnbound(); endParameters[jj] = new double[2]; endParameters[jj][0] = 0.0; endParameters[jj][1] = 0.0; } // Trim/Extend the curves so that they make a closed loop. for (int jj = 0; jj < 4; jj++) { IntersectionResultArray resultArray = null; outline[jj].Intersect(outline[(jj + 1) % 4], out resultArray); if (resultArray == null || resultArray.Size == 0) { return(null); } int numResults = resultArray.Size; if ((numResults > 1 && !axisIsCyclic) || (numResults > 2)) { return(null); } UV intersectionPoint = resultArray.get_Item(0).UVPoint; endParameters[jj][1] = intersectionPoint.U; endParameters[(jj + 1) % 4][0] = intersectionPoint.V; if (numResults == 2) { // If the current result is closer to the end of the curve, keep it. UV newIntersectionPoint = resultArray.get_Item(1).UVPoint; int endParamIndex = (jj % 2); double newParamToCheck = newIntersectionPoint[endParamIndex]; double oldParamToCheck = (endParamIndex == 0) ? endParameters[jj][1] : endParameters[(jj + 1) % 4][0]; double currentEndPoint = (endParamIndex == 0) ? orientedCurveList[jj].GetEndParameter(1) : orientedCurveList[(jj + 1) % 4].GetEndParameter(0); // Put in range of [-Period/2, Period/2]. double newDist = (currentEndPoint - newParamToCheck) % axisCurvePeriod; if (newDist < -axisCurvePeriod / 2.0) { newDist += axisCurvePeriod; } if (newDist > axisCurvePeriod / 2.0) { newDist -= axisCurvePeriod; } double oldDist = (currentEndPoint - oldParamToCheck) % axisCurvePeriod; if (oldDist < -axisCurvePeriod / 2.0) { oldDist += axisCurvePeriod; } if (oldDist > axisCurvePeriod / 2.0) { oldDist -= axisCurvePeriod; } if (Math.Abs(newDist) < Math.Abs(oldDist)) { endParameters[jj][1] = newIntersectionPoint.U; endParameters[(jj + 1) % 4][0] = newIntersectionPoint.V; } } } CurveLoop newCurveLoop = new CurveLoop(); for (int jj = 0; jj < 4; jj++) { if (endParameters[jj][1] < endParameters[jj][0]) { if (!outline[jj].IsCyclic) { return(null); } endParameters[jj][1] += Math.Floor(endParameters[jj][0] / axisCurvePeriod + 1.0) * axisCurvePeriod; } outline[jj].MakeBound(endParameters[jj][0], endParameters[jj][1]); newCurveLoop.Append(outline[jj]); } currLoops = new List <CurveLoop>(); currLoops.Add(newCurveLoop); extrusionDistance = currDepth; } // Determine the material id. IFCMaterial material = materialLayer.Material; ElementId layerMaterialId = (material == null) ? ElementId.InvalidElementId : material.GetMaterialElementId(); // The second option here is really for Referencing. Without a UI (yet) to determine whether to show the base // extusion or the layers for objects with material layer sets, we've chosen to display the base material if the layer material // has no color information. This means that the layer is assigned the "wrong" material, but looks better on screen. // We will reexamine this decision (1) for the Open case, (2) if there is UI to toggle between layers and base extrusion, or // (3) based on user feedback. if (layerMaterialId == ElementId.InvalidElementId || Importer.TheCache.MaterialsWithNoColor.Contains(layerMaterialId)) { layerMaterialId = baseMaterialId; } SolidOptions solidOptions = new SolidOptions(layerMaterialId, shapeEditScope.GraphicsStyleId); // Create the extrusion for the material layer. GeometryObject extrusionSolid = GeometryCreationUtilities.CreateExtrusionGeometry( currLoops, materialExtrusionDirection, extrusionDistance, solidOptions); if (extrusionSolid == null) { return(null); } extrusionSolids.Add(extrusionSolid); depthSoFar += depth; } } catch { // Ignore the specific exception, but let the user know there was a problem processing the IfcMaterialLayerSetUsage. shouldWarn = true; return(null); } return(extrusionSolids); }
static public TrussInfo BuildTrussAtHip(XYZ currentPointOnHip, EdgeInfo currentEdgeInfo, Element firstSupport, Element secondSupport) { TrussInfo trussInfoToReturn = null; if (!(firstSupport.Location is LocationCurve) || !(secondSupport.Location is LocationCurve)) { return(trussInfoToReturn); } Line hipLine = currentEdgeInfo.Curve as Line; Line firstSupportLocationLine = (firstSupport.Location as LocationCurve).Curve as Line; Line secondSupportLocationLine = (secondSupport.Location as LocationCurve).Curve as Line; if (firstSupportLocationLine == null || secondSupportLocationLine == null || hipLine == null) { return(trussInfoToReturn); } //Relocate the placement of the truss to the center of the Hip subtracting the intersection of the supports XYZ intersectiongOfSupports = firstSupportLocationLine.GetFlattenIntersection(secondSupportLocationLine); if (intersectiongOfSupports == null) { return(trussInfoToReturn); } XYZ higherHipPoint = currentEdgeInfo.Curve.GetEndPoint(0); XYZ lowerHipPoint = currentEdgeInfo.Curve.GetEndPoint(1); if (higherHipPoint.Z < lowerHipPoint.Z) { higherHipPoint = lowerHipPoint; } Line newHipLine = Line.CreateBound(higherHipPoint, intersectiongOfSupports).Flatten(); //TODO get this offset by the UI, if no offset is applied, the trusses from two hips will collide double TRUSS_HIP_OFFSET = Utils.Utils.ConvertM.cmToFeet(15); double centerParameter = newHipLine.ComputeRawParameter(0.5); XYZ newLineTrussPosition = newHipLine.Evaluate(centerParameter + TRUSS_HIP_OFFSET, false); //DEBUG.CreateDebugPoint(currentEdgeInfo.CurrentRoof.Document, newLineTrussPosition); IntersectionResultArray iResultArr = null; currentEdgeInfo.Curve.Intersect(Line.CreateUnbound(newLineTrussPosition, XYZ.BasisZ), out iResultArr); if (iResultArr == null || iResultArr.Size < 1) { return(trussInfoToReturn); } currentPointOnHip = iResultArr.get_Item(0).XYZPoint; //DEBUG.CreateDebugPoint(currentEdgeInfo.CurrentRoof.Document, currentPointOnHip); /////////////////////// Line currentPointCrossLine = Line.CreateBound(currentPointOnHip, currentPointOnHip.Add(hipLine.Flatten().Direction.CrossProduct(XYZ.BasisZ))); //DEBUG.CreateDebugFlattenLine(currentEdgeInfo.CurrentRoof.Document, currentPointCrossLine); //DEBUG.CreateDebugFlattenLine(currentEdgeInfo.CurrentRoof.Document, firstSupportLocationLine); //DEBUG.CreateDebugFlattenLine(currentEdgeInfo.CurrentRoof.Document, secondSupportLocationLine); XYZ firstSupportPoint = currentPointCrossLine.GetFlattenIntersection(firstSupportLocationLine, true, false); XYZ secondSupportPoint = currentPointCrossLine.GetFlattenIntersection(secondSupportLocationLine, true, false); if (firstSupportPoint == null || secondSupportPoint == null) { return(trussInfoToReturn); } double roofHeight = currentEdgeInfo.GetCurrentRoofHeight(); firstSupportPoint = new XYZ(firstSupportPoint.X, firstSupportPoint.Y, roofHeight); secondSupportPoint = new XYZ(secondSupportPoint.X, secondSupportPoint.Y, roofHeight); //DEBUG.CreateDebugPoint(currentEdgeInfo.CurrentRoof.Document, firstSupportPoint); //DEBUG.CreateDebugPoint(currentEdgeInfo.CurrentRoof.Document, secondSupportPoint); if (currentEdgeInfo.RoofLineType != RoofLineType.Hip) { return(trussInfoToReturn); } // currentTopPoint = GeometrySupport.AdjustTopPointToRoofAngle(currentTopPoint, new List<XYZ> { firstPointOnEave, secondPointOnEave }, currentEdgeInfo); trussInfoToReturn = GeometrySupport.GetTrussInfo(currentPointOnHip, firstSupportPoint, secondSupportPoint); return(trussInfoToReturn); }
public override Value Evaluate(FSharpList <Value> args) { var crv = (Curve)((Value.Container)args[0]).Item; Face face = null; Solid tempSolid = null; Plane thisPlane = null; if (((Value.Container)args[1]).Item is Face) { face = (Autodesk.Revit.DB.Face)((Value.Container)args[1]).Item; } else if (((Value.Container)args[1]).Item is Plane) { thisPlane = ((Value.Container)args[1]).Item as Plane; // tesselate curve and find uv envelope in projection to the plane IList <XYZ> tessCurve = crv.Tessellate(); var curvePointEnum = tessCurve.GetEnumerator(); XYZ corner1 = new XYZ(); XYZ corner2 = new XYZ(); bool cornersSet = false; for (; curvePointEnum.MoveNext();) { if (!cornersSet) { corner1 = curvePointEnum.Current; corner2 = curvePointEnum.Current; cornersSet = true; } else { for (int coord = 0; coord < 3; coord++) { if (corner1[coord] > curvePointEnum.Current[coord]) { corner1 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner1[coord], coord == 1 ? curvePointEnum.Current[coord] : corner1[coord], coord == 2 ? curvePointEnum.Current[coord] : corner1[coord]); } if (corner2[coord] < curvePointEnum.Current[coord]) { corner2 = new XYZ(coord == 0 ? curvePointEnum.Current[coord] : corner2[coord], coord == 1 ? curvePointEnum.Current[coord] : corner2[coord], coord == 2 ? curvePointEnum.Current[coord] : corner2[coord]); } } } } double dist1 = thisPlane.Origin.DistanceTo(corner1); double dist2 = thisPlane.Origin.DistanceTo(corner2); double sizeRect = 2.0 * (dist1 + dist2) + 100.0; CurveLoop cLoop = new CurveLoop(); for (int index = 0; index < 4; index++) { double coord0 = (index == 0 || index == 3) ? -sizeRect : sizeRect; double coord1 = (index < 2) ? -sizeRect : sizeRect; XYZ pnt0 = thisPlane.Origin + coord0 * thisPlane.XVec + coord1 * thisPlane.YVec; double coord3 = (index < 2) ? sizeRect : -sizeRect; double coord4 = (index == 0 || index == 3) ? -sizeRect : sizeRect; XYZ pnt1 = thisPlane.Origin + coord3 * thisPlane.XVec + coord4 * thisPlane.YVec; Line cLine = dynRevitSettings.Revit.Application.Create.NewLineBound(pnt0, pnt1); cLoop.Append(cLine); } List <CurveLoop> listCLoops = new List <CurveLoop> (); listCLoops.Add(cLoop); tempSolid = GeometryCreationUtilities.CreateExtrusionGeometry(listCLoops, thisPlane.Normal, 100.0); //find right face FaceArray facesOfExtrusion = tempSolid.Faces; for (int indexFace = 0; indexFace < facesOfExtrusion.Size; indexFace++) { Face faceAtIndex = facesOfExtrusion.get_Item(indexFace); if (faceAtIndex is PlanarFace) { PlanarFace pFace = faceAtIndex as PlanarFace; if (Math.Abs(thisPlane.Normal.DotProduct(pFace.Normal)) < 0.99) { continue; } if (Math.Abs(thisPlane.Normal.DotProduct(thisPlane.Origin - pFace.Origin)) > 0.1) { continue; } face = faceAtIndex; break; } } if (face == null) { throw new Exception("Curve Face Intersection could not process supplied Plane."); } } IntersectionResultArray xsects = new IntersectionResultArray(); SetComparisonResult result = face.Intersect(crv, out xsects); var xsect_results = FSharpList <Value> .Empty; var results = FSharpList <Value> .Empty; if (xsects != null) { foreach (IntersectionResult ir in xsects) { var xsect = FSharpList <Value> .Empty; try { xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.EdgeParameter), xsect); } catch { xsect = FSharpList <Value> .Cons(Value.NewNumber(0), xsect); } xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.EdgeObject), xsect); xsect = FSharpList <Value> .Cons(Value.NewNumber(ir.Parameter), xsect); if (thisPlane != null) { UV planeUV = new UV(thisPlane.XVec.DotProduct(ir.XYZPoint - thisPlane.Origin), thisPlane.YVec.DotProduct(ir.XYZPoint - thisPlane.Origin)); xsect = FSharpList <Value> .Cons(Value.NewContainer(planeUV), xsect); } else { xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.UVPoint), xsect); } xsect = FSharpList <Value> .Cons(Value.NewContainer(ir.XYZPoint), xsect); xsect_results = FSharpList <Value> .Cons(Value.NewList(xsect), xsect_results); } } results = FSharpList <Value> .Cons(Value.NewList(xsect_results), results); results = FSharpList <Value> .Cons(Value.NewString(result.ToString()), results); return(Value.NewList(results)); }
/// <summary> /// DrawInsulation /// </summary> public double drawInsulation(List<ElementId> grp, Document doc, Curve lower, double distance, Curve upper, ref bool leftwing, List<Interruption> Breaks, bool zigzag) { double dist = distance / lower.Length; if (dist > 1) return 100; XYZ P1 = lower.Evaluate(dist, true); IntersectionResultArray result = new IntersectionResultArray(); XYZ normal = lower.GetCurveTangentToEndPoint(P1); SetComparisonResult scr = Line.CreateUnbound(P1, normal).Intersect(upper, out result); if (result == null || result.Size == 0) { if (dist > 0.5) return 100; else { upper = upper.Clone(); upper.MakeUnbound(); scr = Line.CreateUnbound(P1, normal).Intersect(upper, out result); } } XYZ P3 = result.get_Item(0).XYZPoint; double height = P1.DistanceTo(P3); double r = height / 4; double distr = (distance + r) / lower.Length; if (distr > 1) return 100; foreach (Interruption interrupt in Breaks) { if (distr > lower.ComputeNormalizedParameter(interrupt.from) && distr < lower.ComputeNormalizedParameter(interrupt.to)) return r; } XYZ P2 = (distr < 1) ? lower.Evaluate(distr, true) : P1; double disth = (distance + height) / lower.Length; SetComparisonResult scr2 = Line.CreateUnbound(P2, lower.GetCurveTangentToEndPoint(P2)).Intersect(upper, out result); if (result == null || result.Size == 0) return 100; XYZ P4 = (P1 != P2) ? result.get_Item(0).XYZPoint : upper.GetEndPoint(1); if (zigzag) drawZigZag(grp, doc, P1, P2, P3, P4, leftwing); else drawSoftLoop(grp, doc, P1, P2, P3, P4, leftwing); if (leftwing) leftwing = false; else leftwing = true; return r; }