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); }
/// <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 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); }
//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 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 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); }
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)); }
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 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); }
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 StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; plst pList = new plst(); //paramList = new plst(); //The list of fittings, sorted by TYPE then SKEY IList <Element> accessoriesList = elements. OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbAccessories = new StringBuilder(); //This is a workaround to try to determine what element caused an exception Element element = null; try { foreach (Element Element in accessoriesList) { //This is a workaround to try to determine what element caused an exception element = Element; sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbAccessories.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsString()); if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE") { sbAccessories.AppendLine(" STATUS DOTTED-UNDIMENSIONED"); sbAccessories.AppendLine(" MATERIAL-LIST EXCLUDE"); } //Write Plant3DIso entries if turned on if (InputVars.ExportToIsogen) { sbAccessories.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //Gather connectors of the element var cons = mp.GetConnectors(element); //Switch to different element type configurations switch (element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()) { case ("FILTER"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("INSTRUMENT"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("VALVE"): goto case ("INSTRUMENT"); case ("VALVE-ANGLE"): //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); //The centre point is obtained by creating an bound line from primary connector and projecting the secondary point on the line. XYZ reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line primaryLine = Line.CreateBound(cons.Primary.Origin, cons.Primary.Origin + reverseConnectorVector * 10); XYZ centrePoint = primaryLine.Project(cons.Secondary.Origin).XYZPoint; sbAccessories.Append(EndWriter.WriteCP(centrePoint)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case ("INSTRUMENT-DIAL"): //Connector information extraction sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); XYZ primConOrigin = cons.Primary.Origin; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateBound(primConOrigin, primConOrigin + reverseConnectorVector * 10); //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) { continue; } foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; try { SetComparisonResult result = face.Intersect(detectorLine, out results); if (result != SetComparisonResult.Overlap) { continue; } intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(primConOrigin) == false) { endPointAnalyzed = intersection; } } catch (Exception) { continue; } } } } //If the point is still null after geometry intersection, it means the analysis failed //Create an artificial point if (endPointAnalyzed == null) { endPointAnalyzed = cons.Primary.Origin + reverseConnectorVector * 2; } sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case "SUPPORT": sbAccessories.Append(EndWriter.WriteCO(familyInstance, cons.Primary)); sbAccessories.Append(pdw.ParameterValue("TAG", new[] { "TAG 1", "TAG 2", "TAG 3" }, element)); break; case "FLOOR-SYMBOL": sbAccessories.Append(EndWriter.WriteCO(familyInstance)); break; case "INSTRUMENT-3WAY": //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, cons.Primary)); sbAccessories.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbAccessories.Append(EndWriter.WriteEP3(element, cons.Tertiary)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; } Composer elemParameterComposer = new Composer(); sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT")) { sbAccessories.Append(Composer.CIIWriter(doc, key)); } #endregion sbAccessories.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbAccessories.Append(element.UniqueId); sbAccessories.AppendLine(); //Process tap entries of the element if any //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc); sbAccessories.Append(tapsWriter.tapsWriter); } } } catch (Exception e) { throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message); } //// Clear the output file //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf")) //{ // w.Write(sbAccessories); // w.Close(); //} return(sbAccessories); }
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> /// /// </summary> internal override void Execute() { #region 与revit文档交互入口 UIDocument uidoc = this.uiapp.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; View actiView = doc.ActiveView; #endregion // 选择基准点 XYZ pointGet = sel.PickPoint("请选择墙面上的一个点"); // 选择轴网 IList <Element> elements = sel.PickElementsByRectangle(new GridFilter(), "请拾取轴网"); // 求基准线 Grid grid1 = elements[0] as Grid; IList <Curve> gridCurves1 = grid1.GetCurvesInView(DatumExtentType.ViewSpecific, actiView); Line line1 = gridCurves1.First() as Line; // 基准点需要移动一个高度 pointGet = pointGet + new XYZ(0, 0, line1.Origin.Z); XYZ direction1 = line1.Direction; Transform transform = Transform.CreateRotation(new XYZ(0, 0, 1), Math.PI / 2); Line line2 = line1.CreateTransformed(transform) as Line; XYZ direction2 = line2.Direction; // 判断基准线移动方向 Line line_0 = Line.CreateBound(line1.GetEndPoint(0), pointGet); Line line_1 = Line.CreateBound(line1.GetEndPoint(1), pointGet); int intx = 0; Line baseline = null; if (line_0.Length < line_1.Length) { intx = 0; // 基准线需要左右延长一个极长距离 baseline = Line.CreateBound(pointGet + (-1) * direction1 * 10 * 0.3048 - direction2 * 500, pointGet + (-1) * direction1 * 10 * 0.3048 + direction2 * 500); } else { intx = 1; baseline = Line.CreateBound(pointGet + direction1 * 10 * 0.3048 - direction2 * 500, pointGet + direction1 * 10 * 0.3048 + direction2 * 500); } // 处理每一根轴网 foreach (Element ele in elements) { Grid singleGrid = ele as Grid; IList <Curve> singleCurves = singleGrid.GetCurvesInView(DatumExtentType.ViewSpecific, actiView); Line singelLine = singleCurves.First() as Line; XYZ singelDirection = singelLine.Direction; // 判断轴网方向与基准轴网的方向关系 选择需要保留的端点 XYZ stayPoint = null; if (singelDirection.IsAlmostEqualTo(direction1 * (-1)))//反向 { stayPoint = singelLine.GetEndPoint(intx); } else// 同向 { if (intx == 0) { stayPoint = singelLine.GetEndPoint(1); } else { stayPoint = singelLine.GetEndPoint(0); } } //求轴网和baseline的交点,基于交点和轴网远处端点创建新的轴网位置线 IntersectionResultArray resultArray = new IntersectionResultArray(); SetComparisonResult setComparisonResult = singelLine.Intersect(baseline, out resultArray); if (setComparisonResult == SetComparisonResult.Overlap) { XYZ xYZ = resultArray.get_Item(0).XYZPoint; Line newLine = Line.CreateBound(xYZ, stayPoint); using (Transaction trans = new Transaction(doc, "modify")) { trans.Start(); singleGrid.SetDatumExtentType(DatumEnds.End0, actiView, DatumExtentType.ViewSpecific); singleGrid.SetDatumExtentType(DatumEnds.End1, actiView, DatumExtentType.ViewSpecific); singleGrid.SetCurveInView(DatumExtentType.ViewSpecific, actiView, newLine); trans.Commit(); } } } }
// 获取插入点和方向 private void GetIntersectPtAndDirection() { foreach (ViewOutLineInfo viewOutLineInfo in this.m_lstViewOutLineInfo) { foreach (DrawElement drawElement in this.m_lstDrawElems) { Curve curve = null; if (drawElement.DrawElemType == ElemType.eGrid || drawElement.DrawElemType == ElemType.eMultiSegGrid) { Grid grid = drawElement.DrawElem as Grid; if (grid == null || (drawElement.DrawElemType == ElemType.eMultiSegGrid && (this.m_doc.ActiveView.ViewType == ViewType.Section || this.m_doc.ActiveView.ViewType == ViewType.Elevation))) { continue; } curve = GetGridCurve(this.m_doc.ActiveView, grid); } else if (drawElement.DrawElemType == ElemType.eLevel) { Level level = drawElement.DrawElem as Level; if (level == null) { continue; } curve = GetLevelCurve(this.m_doc.ActiveView, level); } if (!(curve == null)) { Curve curve2; if (curve is Arc) { System.Drawing.Point point = this.Revit2Screen(curve.GetEndPoint(0)); System.Drawing.Point point2 = this.Revit2Screen(curve.GetEndPoint(1)); System.Drawing.Point point3 = this.Revit2Screen(curve.Evaluate(0.5, true)); XYZ xyz = new XYZ((double)point.X, (double)point.Y, 0.0); XYZ xyz2 = new XYZ((double)point2.X, (double)point2.Y, 0.0); XYZ xyz3 = new XYZ((double)point3.X, (double)point3.Y, 0.0); curve2 = Arc.Create(xyz, xyz2, xyz3); } else { System.Drawing.Point point4 = this.Revit2Screen(curve.GetEndPoint(0)); System.Drawing.Point point5 = this.Revit2Screen(curve.GetEndPoint(1)); XYZ xyz4 = new XYZ((double)point4.X, (double)point4.Y, 0.0); XYZ xyz5 = new XYZ((double)point5.X, (double)point5.Y, 0.0); curve2 = Line.CreateBound(xyz4, xyz5); } IntersectionResultArray intersectionResultArray = new IntersectionResultArray(); SetComparisonResult setComparisonResult = viewOutLineInfo.ViewOutLine.Intersect(curve2, 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.OutlineSide; gridNumShowInfo.ElemText = drawElement.DrawElem.Name; gridNumShowInfo.ElemClass = drawElement.DrawElemType; this.m_lstGridNumShowInfo.Add(gridNumShowInfo); } } } } } }
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 StringBuilder Export(string pipeLineAbbreviation, HashSet <Element> elements, Document document) { Document doc = document; string key = pipeLineAbbreviation; plst pList = new plst(); //paramList = new plst(); //The list of fittings, sorted by TYPE then SKEY IList <Element> accessoriesList = elements. OrderBy(e => e.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString()). ThenBy(e => e.get_Parameter(pList.PCF_ELEM_SKEY.Guid).AsString()).ToList(); StringBuilder sbAccessories = new StringBuilder(); //This is a workaround to try to determine what element caused an exception Element element = null; try { foreach (Element Element in accessoriesList) { //This is a workaround to try to determine what element caused an exception element = Element; //If the Element Type field is empty -> ignore the component if (string.IsNullOrEmpty(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString())) { continue; } sbAccessories.AppendLine(element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()); sbAccessories.AppendLine(" COMPONENT-IDENTIFIER " + element.get_Parameter(new plst().PCF_ELEM_COMPID.Guid).AsInteger()); //Write Plant3DIso entries if turned on if (InputVars.ExportToPlant3DIso) { sbAccessories.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(pList.PCF_ELEM_TYPE.Guid).AsString()) { case ("FILTER"): //Process endpoints of the component Connector primaryConnector = null; Connector secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); break; case ("INSTRUMENT"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; case ("VALVE"): goto case ("INSTRUMENT"); case ("VALVE-ANGLE"): //Process endpoints of the component primaryConnector = null; secondaryConnector = null; foreach (Connector connector in connectorSet) { if (connector.GetMEPConnectorInfo().IsPrimary) { primaryConnector = connector; } if (connector.GetMEPConnectorInfo().IsSecondary) { secondaryConnector = connector; } } //Process endpoints of the component sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); //The centre point is obtained by creating an unbound line from primary connector and projecting the secondary point on the line. XYZ reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line primaryLine = Line.CreateUnbound(primaryConnector.Origin, reverseConnectorVector); XYZ centrePoint = primaryLine.Project(secondaryConnector.Origin).XYZPoint; sbAccessories.Append(EndWriter.WriteCP(centrePoint)); break; case ("INSTRUMENT-DIAL"): ////Process endpoints of the component //primaryConnector = null; //foreach (Connector connector in connectorSet) primaryConnector = connector; ////Process endpoints of the component //sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); ////The co-ords point is obtained by creating an unbound line from primary connector and taking an arbitrary point a long the line. //reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ.Multiply(0.656167979); //XYZ coOrdsPoint = primaryConnector.Origin; //Transform pointTranslation; //pointTranslation = Transform.CreateTranslation(reverseConnectorVector); //coOrdsPoint = pointTranslation.OfPoint(coOrdsPoint); primaryConnector = null; foreach (Connector connector in connectorSet) { primaryConnector = connector; } //Connector information extraction sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); XYZ primConOrigin = primaryConnector.Origin; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it reverseConnectorVector = -primaryConnector.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateUnbound(primConOrigin, 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) { continue; } foreach (GeometryObject instObj in instance.GetInstanceGeometry()) { Solid solid = instObj as Solid; if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } foreach (Face face in solid.Faces) { IntersectionResultArray results = null; XYZ intersection = null; SetComparisonResult result = face.Intersect(detectorLine, out results); if (result != SetComparisonResult.Overlap) { continue; } intersection = results.get_Item(0).XYZPoint; if (intersection.IsAlmostEqualTo(primConOrigin) == false) { endPointAnalyzed = intersection; } } } } sbAccessories.Append(EndWriter.WriteCO(endPointAnalyzed)); break; case "SUPPORT": primaryConnector = (from Connector c in connectorSet where c.GetMEPConnectorInfo().IsPrimary select c).FirstOrDefault(); sbAccessories.Append(EndWriter.WriteCO(familyInstance, primaryConnector)); break; case "INSTRUMENT-3WAY": //Sort connectors to primary, secondary and none primaryConnector = null; secondaryConnector = null; Connector tertiaryConnector = null; foreach (Connector connector in connectorSet) { 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 sbAccessories.Append(EndWriter.WriteEP1(element, primaryConnector)); sbAccessories.Append(EndWriter.WriteEP2(element, secondaryConnector)); sbAccessories.Append(EndWriter.WriteEP3(element, tertiaryConnector)); sbAccessories.Append(EndWriter.WriteCP(familyInstance)); break; } Composer elemParameterComposer = new Composer(); sbAccessories.Append(elemParameterComposer.ElemParameterWriter(element)); #region CII export if (InputVars.ExportToCII && !string.Equals(element.get_Parameter(pList.PCF_ELEM_TYPE.Guid).AsString(), "SUPPORT")) { sbAccessories.Append(Composer.CIIWriter(doc, key)); } #endregion sbAccessories.Append(" UNIQUE-COMPONENT-IDENTIFIER "); sbAccessories.Append(element.UniqueId); sbAccessories.AppendLine(); //Process tap entries of the element if any //Diameter Limit nullifies the tapsWriter output if the tap diameter is less than the limit so it doesn't get exported if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP1").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP1", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP2").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP2", doc); sbAccessories.Append(tapsWriter.tapsWriter); } if (string.IsNullOrEmpty(element.LookupParameter("PCF_ELEM_TAP3").AsString()) == false) { TapsWriter tapsWriter = new TapsWriter(element, "PCF_ELEM_TAP3", doc); sbAccessories.Append(tapsWriter.tapsWriter); } } } catch (Exception e) { throw new Exception("Element " + element.Id.IntegerValue.ToString() + " caused an exception: " + e.Message); } //// Clear the output file //System.IO.File.WriteAllBytes(InputVars.OutputDirectoryFilePath + "Accessories.pcf", new byte[0]); //// Write to output file //using (StreamWriter w = File.AppendText(InputVars.OutputDirectoryFilePath + "Accessories.pcf")) //{ // w.Write(sbAccessories); // w.Close(); //} return(sbAccessories); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; //WALLS FACES List <PlanarFace> wallFaces = new List <PlanarFace>(); //WALLS Reference wallRef = uidoc.Selection.PickObject(ObjectType.Element, "Select a Wall"); Element wall = doc.GetElement(wallRef); LocationCurve lc = wall.Location as LocationCurve; Line wallLine = lc.Curve as Line; XYZ perpDir = wallLine.Direction.CrossProduct(XYZ.BasisZ); Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = false; opt.View = doc.ActiveView; GeometryElement geomElem = doc.GetElement(wallRef).get_Geometry(opt); foreach (GeometryObject geomObj in geomElem) { Solid geomSolid = geomObj as Solid; foreach (Face geomFace in geomSolid.Faces) { XYZ faceNormal = geomFace.ComputeNormal(new UV(0.5, 0.5)); //select only the vertical faces if (faceNormal.CrossProduct(perpDir).IsAlmostEqualTo(XYZ.Zero)) { PlanarFace pf = geomFace as PlanarFace; wallFaces.Add(pf); } } } //GET MESH Reference meshRef = uidoc.Selection.PickObject(ObjectType.Element, "Select Mesh"); Element e = doc.GetElement(meshRef); GeometryElement geomElemSurvey = e.get_Geometry(opt); Mesh geomMesh = null; foreach (GeometryObject geomObj in geomElemSurvey) { try { GeometryInstance gi = geomObj as GeometryInstance; foreach (GeometryObject element in gi.GetInstanceGeometry()) { geomMesh = element as Mesh; } } catch { geomMesh = geomObj as Mesh; } } using (Transaction t = new Transaction(doc, "Find intersection")) { t.Start(); List <XYZ> intPts = new List <XYZ>(); for (int i = 0; i < geomMesh.NumTriangles; i++) { MeshTriangle triangle = geomMesh.get_Triangle(i); XYZ vertex1 = triangle.get_Vertex(0); XYZ vertex2 = triangle.get_Vertex(1); XYZ vertex3 = triangle.get_Vertex(2); Line[] edgeList = new Line[3]; try { Line[] edges = new Line[] { Line.CreateBound(vertex1, vertex2), Line.CreateBound(vertex1, vertex3), Line.CreateBound(vertex2, vertex3) }; for (int k = 0; k < edgeList.Length; k++) { edgeList[k] = edges[k]; } } catch { } // Plane facePlane = Plane.CreateByThreePoints(vertex1, vertex2, vertex3); // SketchPlane sp = SketchPlane.Create(doc, facePlane); // doc.Create.NewModelCurve(edge12, sp); // doc.Create.NewModelCurve(edge13, sp); // doc.Create.NewModelCurve(edge23, sp); foreach (PlanarFace pf in wallFaces) { XYZ[] pts = new XYZ[2]; int count = 0; if (edgeList[0] != null) { foreach (Line edge in edgeList) { IntersectionResultArray intersections = null; SetComparisonResult scr = pf.Intersect(edge, out intersections); if (scr == SetComparisonResult.Overlap && intersections.Size == 1) { for (int j = 0; j < intersections.Size; j++) { //TaskDialog.Show("r", intersections.get_Item(i)); } //TaskDialog.Show("r", intersections.Size.ToString()); IntersectionResult iResult = intersections.get_Item(0); intPts.Add(iResult.XYZPoint); pts[count] = iResult.XYZPoint; count = 1; if (pts.Length == 2 && pts[1] != null) { // TaskDialog.Show("r", String.Format("{0}\n{1}",pts[0], pts[1])); try { Plane wallPlane = Plane.CreateByNormalAndOrigin(pf.FaceNormal, pf.Origin); SketchPlane spWall = SketchPlane.Create(doc, wallPlane); doc.Create.NewModelCurve(Line.CreateBound(pts[0], pts[1]), spWall); } catch { } } } } } } } t.Commit(); } return(Result.Succeeded); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { #region UI数据交互入口 UIApplication uiapp = commandData.Application; UIDocument uIdoc = uiapp.ActiveUIDocument; Document doc = uIdoc.Document; #endregion #region 创建轴网基准线 3000mmm*3000mm 5*5 List <Line> horizontalLines = new List <Line>(); List <Line> verticalLines = new List <Line>(); double distance = 3000;//轴网间距 double _distance = UnitUtils.Convert(distance, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET); XYZ origin = XYZ.Zero; XYZ horizontalXyzStart = new XYZ(-_distance, 0, 0); XYZ verticalXyzStart = new XYZ(0, -_distance, 0); int count = 6; double distanceBuffer = _distance * count; XYZ horizontalXyzEnd = new XYZ(-_distance + distanceBuffer, 0, 0); XYZ verticalXyzEnd = new XYZ(0, -_distance + distanceBuffer, 0); XYZ horizontalMoveDistance = new XYZ(0, _distance, 0); XYZ verticalMoveDistance = new XYZ(_distance, 0, 0); for (int i = 0; i < 5; i++) { horizontalLines.Add(Line.CreateBound(horizontalXyzStart + horizontalMoveDistance * i, horizontalXyzEnd + horizontalMoveDistance * i)); verticalLines.Add(Line.CreateBound(verticalXyzStart + verticalMoveDistance * i, verticalXyzEnd + verticalMoveDistance * i)); } #endregion List <string> ints = new List <string>() { "1", "2", "3", "4", "5" }; List <string> letters = new List <string>() { "A", "B", "C", "D", "E" }; #region 基于基准线,创建轴网 using (var craetGrids = new Transaction(doc, "创建轴网")) { craetGrids.Start(); for (int i = 0; i < 5; i++) { Grid gridH = Grid.Create(doc, horizontalLines[i]); gridH.Name = letters[i]; Grid gridV = Grid.Create(doc, verticalLines[i]); gridV.Name = ints[i]; } craetGrids.Commit(); } #endregion FamilySymbol columnSymbol = (new FilteredElementCollector(doc)).OfCategory(BuiltInCategory.OST_Columns).OfClass(typeof(FamilySymbol)).WhereElementIsElementType().Cast <FamilySymbol>().First(); Level level = (new FilteredElementCollector(doc)).OfCategory(BuiltInCategory.OST_Levels).OfClass(typeof(Level)).WhereElementIsNotElementType().Cast <Level>().First(); #region 在轴网相交的位置,放置柱子,并同时写入entity using (var craetGrids = new Transaction(doc, "放置柱子,并写入entity")) { craetGrids.Start(); int i = 0; columnSymbol.Activate(); verticalLines.ForEach(p0 => { int j = 0; horizontalLines.ForEach(p1 => { IntersectionResultArray intersectionResultArray = new IntersectionResultArray(); SetComparisonResult overLap = p0.Intersect(p1, out intersectionResultArray); XYZ interSectPoint = intersectionResultArray.get_Item(0).XYZPoint; FamilyInstance parkingColumn = doc.Create.NewFamilyInstance(interSectPoint, columnSymbol, level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); SetEntityToBaseWallLoop(doc, schemaGuid, parkingColumn.Id, ints[i].ToString() + letters[j].ToString()); j++; }); i++; }); craetGrids.Commit(); } #endregion return(Result.Succeeded); //throw new NotImplementedException(); }
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); }
/// <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; }
/// <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)); }
internal IList <XYZ> ProjectRidgePointOnEaves(XYZ currentPointOnRidge) { if (RoofLineType != RoofLineType.Ridge && RoofLineType != RoofLineType.RidgeSinglePanel) { throw new Exception("EdgeInfo is not a Ridge!"); } double currentRoofTotalHeight = GetCurrentRoofHeight(); if (RelatedRidgeEaves.Count == 0) { RelatedRidgeEaves = GetRelatedEaves(); } if (RelatedRidgeEaves.Count == 0) { throw new Exception("No ridge related eave was found!"); } IList <XYZ> projectionPoints = new List <XYZ>(); Line currentRidgeLine = Curve.Clone() as Line; if (currentRidgeLine == null) { throw new Exception("The ridge is not a straight line!"); } //TODO try to extract the this to use on get top truss point XYZ crossedDirection = currentRidgeLine.Direction.CrossProduct(XYZ.BasisZ); Line CrossedRidgeLine = Line.CreateBound(currentPointOnRidge, crossedDirection.Add(currentPointOnRidge)).Flatten(currentRoofTotalHeight); Line CrossedRidgeLineFlatten = (CrossedRidgeLine.Clone() as Line); CrossedRidgeLineFlatten.MakeUnbound(); foreach (Edge currentEdge in RelatedRidgeEaves) { Line firstEaveLine = (currentEdge.AsCurve() as Line); if (firstEaveLine == null) { continue; } Line firstEaveLineFlatten = firstEaveLine.Flatten(currentRoofTotalHeight); IntersectionResultArray projectionResultArr = null; CrossedRidgeLineFlatten.Intersect(firstEaveLineFlatten, out projectionResultArr); if (projectionResultArr == null || projectionResultArr.Size == 0) { continue; } XYZ currentIntersPoint = projectionResultArr.get_Item(0).XYZPoint; if (currentIntersPoint == null) { continue; } projectionPoints.Add(currentIntersPoint); } if (projectionPoints == null || projectionPoints.Count == 0) { //Document doc = CurrentRoof.Document; //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol; //doc.Create.NewFamilyInstance(Edges[0].Evaluate(0.5), fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); //throw new Exception("No projection between ridge and eave could be stabilished!"); } return(projectionPoints); }
// Get the path best one private Tuple <XYZ, XYZ> GetBestPath() { XYZ bStartingP = null, bEndingP = null; //left in the plan XYZ S1 = new XYZ(); XYZ S2 = new XYZ(); XYZ S3 = new XYZ(); XYZ S4 = new XYZ(); // right in the plan XYZ S5 = new XYZ(); XYZ S6 = new XYZ(); XYZ S7 = new XYZ(); XYZ S8 = new XYZ(); ////// Lookup, it is the 2nd space we are checking in //left in the plan XYZ S1Lookup = new XYZ(); XYZ S2Lookup = new XYZ(); XYZ S3Lookup = new XYZ(); XYZ S4Lookup = new XYZ(); // right in the plan XYZ S5Lookup = new XYZ(); XYZ S6Lookup = new XYZ(); XYZ S7Lookup = new XYZ(); XYZ S8Lookup = new XYZ(); int i = 0; foreach (var spaceInfoItem in RevitDataContext.lazyInstance.SpacesInfo) { // Polygon Right in the plan BoundingBoxXYZ bbxyz = spaceInfoItem.Key.get_BoundingBox(null); bbxyz.Enabled = true; S1 = new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2)); S2 = new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2)); S3 = new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2)); S4 = new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(0).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2)); S5 = new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2)); S6 = new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(1).Z, 2)); S7 = new XYZ(Math.Round(bbxyz.get_Bounds(0).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2)); S8 = new XYZ(Math.Round(bbxyz.get_Bounds(1).X, 2), Math.Round(bbxyz.get_Bounds(1).Y, 2), Math.Round(bbxyz.get_Bounds(0).Z, 2)); List <Tuple <Space, List <Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ> > > > Gintersections = new List <Tuple <Space, List <Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ> > > >(); ////// Lookup, it is the 2nd space we are checking in for (int j = 0; j < RevitDataContext.lazyInstance.SpacesInfo.Count(); j += 1) { if (j != i) { /// param are projected face start & ending point, lookingup start & ending point and intersection respectively List <Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ> > intersections = new List <Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ> >(); BoundingBoxXYZ bbxyzLookup = RevitDataContext.lazyInstance.SpacesInfo.ElementAt(j).Key.get_BoundingBox(null); bbxyzLookup.Enabled = true; // Polygon Left in the plan S1Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(0).X, 2), Math.Round(bbxyzLookup.get_Bounds(0).Y, 2), Math.Round(bbxyzLookup.get_Bounds(1).Z, 2)); S2Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(1).X, 2), Math.Round(bbxyzLookup.get_Bounds(0).Y, 2), Math.Round(bbxyzLookup.get_Bounds(1).Z, 2)); S3Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(0).X, 2), Math.Round(bbxyzLookup.get_Bounds(0).Y, 2), Math.Round(bbxyzLookup.get_Bounds(0).Z, 2)); S4Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(1).X, 2), Math.Round(bbxyzLookup.get_Bounds(0).Y, 2), Math.Round(bbxyzLookup.get_Bounds(0).Z, 2)); // Polygon Right in the plan S5Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(0).X, 2), Math.Round(bbxyzLookup.get_Bounds(1).Y, 2), Math.Round(bbxyzLookup.get_Bounds(1).Z, 2)); S6Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(1).X, 2), Math.Round(bbxyzLookup.get_Bounds(1).Y, 2), Math.Round(bbxyzLookup.get_Bounds(1).Z, 2)); S7Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(0).X, 2), Math.Round(bbxyzLookup.get_Bounds(1).Y, 2), Math.Round(bbxyzLookup.get_Bounds(0).Z, 2)); S8Lookup = new XYZ(Math.Round(bbxyzLookup.get_Bounds(1).X, 2), Math.Round(bbxyzLookup.get_Bounds(1).Y, 2), Math.Round(bbxyzLookup.get_Bounds(0).Z, 2)); // Polygon projected from highest of first polygon to lowest lookup's polygon XYZ S1Pp = new XYZ(Math.Round(S2.X, 2), Math.Round(S2.Y, 2), Math.Round(S4Lookup.Z, 2)); XYZ S2Pp = new XYZ(Math.Round(S6.X, 2), Math.Round(S6.Y, 2), Math.Round(S8Lookup.Z, 2)); XYZ S3Pp = new XYZ(Math.Round(S1.X, 2), Math.Round(S1.Y, 2), Math.Round(S3Lookup.Z, 2)); XYZ S4Pp = new XYZ(Math.Round(S5.X, 2), Math.Round(S5.Y, 2), Math.Round(S7Lookup.Z, 2)); // because for some reasons Line object has no properties startingpoint and ending point List <Tuple <Line, XYZ, XYZ> > projectedFace = new List <Tuple <Line, XYZ, XYZ> >(); projectedFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S8Lookup, S7Lookup), S8Lookup, S7Lookup)); projectedFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S4Lookup, S3Lookup), S4Lookup, S3Lookup)); projectedFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S4Lookup, S8Lookup), S4Lookup, S8Lookup)); projectedFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S3Lookup, S7Lookup), S3Lookup, S7Lookup)); List <Tuple <Line, XYZ, XYZ> > lookingUpFace = new List <Tuple <Line, XYZ, XYZ> >(); lookingUpFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S2Pp, S4Pp), S2Pp, S4Pp)); lookingUpFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S1Pp, S3Pp), S1Pp, S3Pp)); lookingUpFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S1Pp, S2Pp), S1Pp, S2Pp)); lookingUpFace.Add(new Tuple <Line, XYZ, XYZ>(Line.CreateBound(S3Pp, S4Pp), S3Pp, S4Pp)); foreach (Tuple <Line, XYZ, XYZ> lp in projectedFace) { foreach (Tuple <Line, XYZ, XYZ> llu in lookingUpFace) { IntersectionResultArray intersectionR = new IntersectionResultArray(); SetComparisonResult res = SetComparisonResult.Disjoint; res = lp.Item1.Intersect(llu.Item1, out intersectionR); if (SetComparisonResult.Disjoint != res) { if (intersectionR != null) { if (!intersectionR.IsEmpty) { intersections.Add(new Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ>(new Tuple <XYZ, XYZ>(new XYZ(Math.Round(lp.Item2.X, 2), Math.Round(lp.Item2.Y, 2), Math.Round(lp.Item2.Z, 2)), new XYZ(Math.Round(lp.Item3.X, 2), Math.Round(lp.Item3.Y, 2), Math.Round(lp.Item3.Z, 2))), new Tuple <XYZ, XYZ>(new XYZ(Math.Round(llu.Item2.X, 2), Math.Round(llu.Item2.Y, 2), Math.Round(llu.Item2.Z, 2)), new XYZ(Math.Round(llu.Item3.X, 2), Math.Round(llu.Item3.Y, 2), Math.Round(llu.Item3.Z, 2))), new XYZ(Math.Round(intersectionR.get_Item(0).XYZPoint.X, 2), Math.Round(intersectionR.get_Item(0).XYZPoint.Y, 2), Math.Round(intersectionR.get_Item(0).XYZPoint.Z, 2)))); } } } } } Utils.lazyInstance.PurgeList(intersections); Gintersections.Add(new Tuple <Space, List <Tuple <Tuple <XYZ, XYZ>, Tuple <XYZ, XYZ>, XYZ> > >(RevitDataContext.lazyInstance.SpacesInfo.ElementAt(j).Key, intersections)); } } var Ginters = Gintersections.Distinct().ToList(); CorrespIntersec.Add(spaceInfoItem.Key, Ginters); i += 1; } return(new Tuple <XYZ, XYZ>(bStartingP, bEndingP)); }
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) { 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).AsString()); if (element.get_Parameter(new plst().PCF_ELEM_SPEC.Guid).AsString() == "EXISTING-INCLUDE") { sbFittings.AppendLine(" STATUS DOTTED-UNDIMENSIONED"); sbFittings.AppendLine(" MATERIAL-LIST EXCLUDE"); } //Write Plant3DIso entries if turned on if (iv.ExportToIsogen) { sbFittings.Append(Composer.Plant3DIsoWriter(element, doc)); } //Cast the elements gathered by the collector to FamilyInstances FamilyInstance familyInstance = (FamilyInstance)element; Options options = new Options(); //Gather connectors of the element var cons = mp.GetConnectors(element); //Switch to different element type configurations switch (element.get_Parameter(new plst().PCF_ELEM_TYPE.Guid).AsString()) { case ("ELBOW"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(" ANGLE "); Parameter par = element.LookupParameter("Angle"); if (par == null) { par = element.LookupParameter("angle"); } if (par == null) { throw new Exception($"Angle parameter on elbow {element.Id.IntegerValue} does not exist or is named differently!"); } sbFittings.Append((Conversion.RadianToDegree(par.AsDouble()) * 100).ToString("0")); sbFittings.AppendLine(); break; //case ("BEND"): // sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); // sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); // sbFittings.Append(EndWriter.WriteCP(familyInstance)); // break; case ("TEE"): //Process endpoints of the component sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteCP(familyInstance)); sbFittings.Append(EndWriter.WriteBP1(element, cons.Tertiary)); break; case ("REDUCER-CONCENTRIC"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Secondary)); break; case ("REDUCER-ECCENTRIC"): goto case ("REDUCER-CONCENTRIC"); case ("COUPLING"): goto case ("REDUCER-CONCENTRIC"); case ("FLANGE"): //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); It is not, it should be specified the type of end, BW, PL, FL etc. to work correctly. sbFittings.Append(EndWriter.WriteEP1(element, cons.Secondary)); sbFittings.Append(EndWriter.WriteEP2(element, cons.Primary)); break; case ("FLANGE-BLIND"): sbFittings.Append(EndWriter.WriteEP1(element, cons.Primary)); XYZ endPointOriginFlangeBlind = cons.Primary.Origin; double connectorSizeFlangeBlind = cons.Primary.Radius; //Analyses the geometry to obtain a point opposite the main connector. //Extraction of the direction of the connector and reversing it XYZ reverseConnectorVector = -cons.Primary.CoordinateSystem.BasisZ; Line detectorLine = Line.CreateBound(endPointOriginFlangeBlind, endPointOriginFlangeBlind + reverseConnectorVector * 10); //Begin geometry analysis GeometryElement geometryElement = familyInstance.get_Geometry(options); //Prepare resulting point XYZ endPointAnalyzed = null; foreach (GeometryObject geometry in geometryElement) { if (geometry is GeometryInstance 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"): XYZ endPointOriginOletPrimary = cons.Primary.Origin; XYZ endPointOriginOletSecondary = cons.Secondary.Origin; //get reference elements Pipe refPipe = null; var refCons = mp.GetAllConnectorsFromConnectorSet(cons.Primary.AllRefs); Connector refCon = refCons.Where(x => x.Owner.IsType <Pipe>()).FirstOrDefault(); if (refCon == null) { //Find the target pipe var filter = new ElementClassFilter(typeof(Pipe)); var view3D = Shared.Filter.Get3DView(doc); var refIntersect = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3D); ReferenceWithContext rwc = refIntersect.FindNearest(cons.Primary.Origin, cons.Primary.CoordinateSystem.BasisZ); var refId = rwc.GetReference().ElementId; refPipe = (Pipe)doc.GetElement(refId); if (refPipe == null) { throw new Exception($"Olet {element.Id.IntegerValue} cannot find a reference Pipe!"); } } else { refPipe = (Pipe)refCon.Owner; } Cons refPipeCons = mp.GetConnectors(refPipe); //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 = refPipeCons.Primary.Origin; XYZ pipeEnd2 = refPipeCons.Secondary.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, cons.Secondary)); 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) { // get the document Document doc = commandData.Application.ActiveUIDocument.Document; // start a transaction using (Transaction t = new Transaction(doc, "Change Project Units")) { t.Start(); Level level = new FilteredElementCollector(doc).OfClass(typeof(Level)).FirstOrDefault() as Level; // get all lines List <Line> lines = new List <Line>(); FilteredElementCollector collector = new FilteredElementCollector(doc).OfClass(typeof(CurveElement)).OfCategory(BuiltInCategory.OST_Lines); foreach (CurveElement l in collector) { string style = doc.GetElement(l.LookupParameter("Line Style").AsElementId()).Name; if (style == "A-WALL") { lines.Add(l.GeometryCurve as Line); } } Dictionary <string, List <LineDistance> > directions = new Dictionary <string, List <LineDistance> >(); foreach (Line l in lines) { XYZ vector = l.Direction; //bool found = false; string absoluteDirection = Math.Abs(vector.X).ToString() + Math.Abs(vector.Y).ToString() + Math.Abs(vector.Z).ToString(); LineDistance dist = new LineDistance(); dist.Line = l; if (directions.ContainsKey(absoluteDirection)) { directions[absoluteDirection].Add(dist); } else { directions[absoluteDirection] = new List <LineDistance>() { dist }; } } IList <Line> wallLines = new List <Line>(); foreach (List <LineDistance> direction in directions.Values) { LineDistance baseline = direction[0]; Line axis; XYZ axisPoint; XYZ negativeAxisPoint; if (baseline.Line.Direction.X == 0 && baseline.Line.Direction.Y == 1) { axis = Line.CreateUnbound(new XYZ(0, 0, 0), new XYZ(1, 0, 0)); axisPoint = new XYZ(1, 0, 1); negativeAxisPoint = new XYZ(-1, 0, -1); } else { axis = Line.CreateUnbound(new XYZ(0, 0, 0), new XYZ(0, 1, 0)); axisPoint = new XYZ(0, 1, 1); negativeAxisPoint = new XYZ(0, -1, -1); } foreach (LineDistance line in direction) { IntersectionResultArray intersect1 = new IntersectionResultArray(); Line temp = line.Line.Clone() as Line; temp.MakeUnbound(); temp.Intersect(axis, out intersect1); XYZ point1 = intersect1.get_Item(0).XYZPoint; line.Distance = XYZ.Zero.DistanceTo(point1); } direction.OrderBy(s => s.Line.GetEndPoint(0).X).ThenBy(s => s.Line.GetEndPoint(0).Y); for (int i = 0; i < direction.Count - 1; i++) { if (direction[i].Checked) { continue; } bool added = false; List <LineDistance> applicable = new List <LineDistance>(); for (int j = i + 1; j < direction.Count - 1; j++) { double diff = Math.Abs(direction[i].Distance - direction[j].Distance); if (diff > 0 && diff < 1.25) { // check how close they are to each other Line longerLine; XYZ projectPoint1; XYZ projectPoint2; if (direction[i].Line.Length > direction[j].Line.Length) { longerLine = direction[i].Line.Clone() as Line; projectPoint1 = direction[j].Line.GetEndPoint(0); projectPoint2 = direction[j].Line.GetEndPoint(1); } else { longerLine = direction[j].Line.Clone() as Line; projectPoint1 = direction[i].Line.GetEndPoint(0); projectPoint2 = direction[i].Line.GetEndPoint(1); } longerLine.MakeUnbound(); IntersectionResult projection1 = longerLine.Project(projectPoint1); IntersectionResult projection2 = longerLine.Project(projectPoint2); if (Math.Abs(projection1.Distance) < 1.25 || Math.Abs(projection2.Distance) < 1.25) { applicable.Add(direction[j]); direction[j].Checked = true; if (!added) { applicable.Add(direction[i]); added = true; } } } else if (diff > 1.25) { break; } } // add the longest line to the list of applicable lines double longest = 0; int longestIndex = 0; bool lineDirection = true; for (int p = 0; p < applicable.Count; p++) { if (applicable[p].Line.Length > longest) { if (applicable[p].Distance > applicable[longestIndex].Distance) { lineDirection = true; } else { lineDirection = false; } longest = applicable[p].Line.Length; longestIndex = p; } } if (longest > 0) { applicable[longestIndex].Normal = lineDirection; Line shifted = Offset(applicable[longestIndex].Line, 0.25); wallLines.Add(shifted); } } } List <Wall> walls = new List <Wall>(); foreach (Line c in wallLines) { try { walls.Add(Wall.Create(doc, c, level.Id, false)); } catch { // do nothing } } // next create doors List <FamilyInstance> doors = new List <FamilyInstance>(); FilteredElementCollector doorCollector = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).OfCategory(BuiltInCategory.OST_Doors); FamilySymbol doorType = doorCollector.FirstOrDefault() as FamilySymbol; Dictionary <string, List <XYZ> > doorMap = new Dictionary <string, List <XYZ> >(); List <XYZ> doorLocations = new List <XYZ>(); FilteredElementCollector dwgCollector = new FilteredElementCollector(doc).OfClass(typeof(ImportInstance)); foreach (ImportInstance import in dwgCollector) { if (import.LookupParameter("Name").AsString().ToLower().Contains("door")) { XYZ location = import.GetTransform().Origin; doorLocations.Add(location); // check which wall this door is closest to foreach (Wall wall in walls) { try { LocationCurve wallLocation = wall.Location as LocationCurve; // this assumes all walls are only about 6" thick if (wallLocation.Curve.Distance(location) < 0.5) { if (doorMap.ContainsKey(wall.Id.ToString())) { doorMap[wall.Id.ToString()] = new List <XYZ>() { location }; } else { doorMap[wall.Id.ToString()].Add(location); } } } catch { // do nothing } } } } // create all the walls using the default type foreach (string id in doorMap.Keys) { Wall wall = doc.GetElement(id) as Wall; foreach (XYZ door in doorMap[id]) { doc.Create.NewFamilyInstance(door, doorType, wall, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); } } t.Commit(); } return(Result.Succeeded); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; try { Element tTypeElement = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Where(fsy => fsy is TrussType).ToList().FirstOrDefault(); if (tTypeElement == null) { message = "Nenhum tipo de treliça foi encontrada no projeto, por favor, carregue um tipo e rode este comando novamente"; return(Result.Failed); } TrussType tType = tTypeElement as TrussType; ISelectionFilter ridgeSelectionFilter = new RoofClasses.SelectionFilters.StraightLinesAndFacesRidgeSelectionFilter(doc); Reference currentReference = sel.PickObject(ObjectType.Edge, ridgeSelectionFilter); FootPrintRoof currentFootPrintRoof = doc.GetElement(currentReference) as FootPrintRoof; RoofClasses.EdgeInfo currentRidgeInfo = Support.GetMostSimilarEdgeInfo(currentReference, doc); if (currentRidgeInfo == null) { message = "Nenhuma linha inferior pode ser obtida a partir da seleção"; return(Result.Failed); } // #region DEBUG ONLY //#if DEBUG // using (Transaction ta = new Transaction(doc, "Line test")) // { // ta.Start(); // Frame fr = new Frame(currentRidgeInfo.Curve.Evaluate(0.5, true), XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ); // SketchPlane skp = SketchPlane.Create(doc, Plane.Create(fr)); // doc.Create.NewModelCurve(currentRidgeInfo.Curve, skp); // ta.Commit(); // } //#endif // #endregion Line currentRidgeLine = currentRidgeInfo.Curve as Line; if (currentRidgeLine == null) { message = "Ridge must be a straight line"; return(Result.Failed); } ISelectionFilter currentTrussBaseSupportFilter = new RoofClasses.SelectionFilters.SupportsSelectionFilter(currentRidgeLine.Direction.CrossProduct(XYZ.BasisZ)); XYZ baseSupportPoint = null; try { Reference currentTrussBaseRef = sel.PickObject(ObjectType.Element, currentTrussBaseSupportFilter, "Selecione uma base para a treliça ou (ESC) para ignorar"); Element currentTrussBaseElem = doc.GetElement(currentTrussBaseRef.ElementId); //We can safely convert because the selection filter does not select anything that is not a curve locatated Curve currentElementCurve = (currentTrussBaseElem.Location as LocationCurve).Curve; if (currentRidgeLine != null) { if (currentElementCurve is Line) { Line currentSupportLine = currentElementCurve as Line; double height = currentRidgeInfo.GetCurrentRoofHeight(); currentRidgeLine = currentRidgeLine.Flatten(height); currentSupportLine = currentSupportLine.Flatten(height); IntersectionResultArray iResutArr = new IntersectionResultArray(); SetComparisonResult compResult = currentRidgeLine.Intersect(currentSupportLine, out iResutArr); if (iResutArr.Size == 1) { IntersectionResult iResult = iResutArr.get_Item(0); if (iResult != null) { baseSupportPoint = currentRidgeInfo.Curve.Project(iResult.XYZPoint).XYZPoint; } } } } } catch { } if (baseSupportPoint == null) { baseSupportPoint = currentRidgeLine.Project(currentReference.GlobalPoint).XYZPoint; } Managers.TrussRidgeManager currentTrussManager = new Managers.TrussRidgeManager(); Line currentSupport0ElemLine = null; Line currentSupport1ElemLine = null; currentTrussBaseSupportFilter = new RoofClasses.SelectionFilters.SupportsSelectionFilter(currentRidgeLine.Direction); if (currentRidgeInfo.RoofLineType == RoofClasses.RoofLineType.Ridge) { try { Reference currentSupport0Ref = sel.PickObject(ObjectType.Element, currentTrussBaseSupportFilter, "O primeiro suporte para a treliça"); Element currentSupport0Elem = doc.GetElement(currentSupport0Ref.ElementId); Curve currentSupport0ElemCurve = (currentSupport0Elem.Location as LocationCurve).Curve; currentSupport0ElemLine = currentSupport0ElemCurve as Line; Reference currentSupport1Ref = sel.PickObject(ObjectType.Element, currentTrussBaseSupportFilter, "O segundo suporte para a treliça"); Element currentSupport1Elem = doc.GetElement(currentSupport1Ref.ElementId); Curve currentSupport1ElemCurve = (currentSupport1Elem.Location as LocationCurve).Curve; currentSupport1ElemLine = currentSupport1ElemCurve as Line; } catch { currentSupport0ElemLine = null; currentSupport1ElemLine = null; } } else if (currentRidgeInfo.RoofLineType == RoofClasses.RoofLineType.RidgeSinglePanel) { try { Reference currentSupport0Ref = sel.PickObject(ObjectType.Element, currentTrussBaseSupportFilter, "O suporte para a treliça"); Element currentSupport0Elem = doc.GetElement(currentSupport0Ref.ElementId); Curve currentSupport0ElemCurve = (currentSupport0Elem.Location as LocationCurve).Curve; currentSupport0ElemLine = currentSupport0ElemCurve as Line; } catch { currentSupport0ElemLine = null; } } RoofClasses.TrussInfo currentTrussInfo = currentTrussManager.CreateTrussFromRidgeWithSupports(baseSupportPoint, currentRidgeInfo, tType, currentSupport0ElemLine, currentSupport1ElemLine); //#region DEBUG ONLY //if (currentReference != null) // DEBUG.CreateDebugPoint(doc, baseSupportPoint); //#endregion } catch (Exception e) { if (!(e is Autodesk.Revit.Exceptions.OperationCanceledException)) { throw e; } } return(Result.Succeeded); }
// 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); }
/// <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; }