/// <summary> /// 打断两根 X型 T型 相交线段 /// </summary> /// <param name="_line1"></param> /// <param name="_line2"></param> /// <returns></returns> public static List <Line> CutOffTwoIntersetionLines_X_T(Line _line1, Line _line2) { List <Line> lines = new List <Line>(); XYZ _line1_start = _line1.GetEndPoint(0); XYZ _line1_end = _line1.GetEndPoint(1); XYZ _line2_start = _line2.GetEndPoint(0); XYZ _line2_end = _line2.GetEndPoint(1); XYZ intersectionPint = GetIntersetionPointFromTwoLines(_line1, _line2); //该处需要判断是源于 T型 的存在 if (!intersectionPint.IsAlmostEqualTo(_line1_start, 0.0001)) { lines.Add(Line.CreateBound(intersectionPint, _line1_start)); } if (!intersectionPint.IsAlmostEqualTo(_line1_end, 0.0001)) { lines.Add(Line.CreateBound(intersectionPint, _line1_end)); } if (!intersectionPint.IsAlmostEqualTo(_line2_start, 0.0001)) { lines.Add(Line.CreateBound(intersectionPint, _line2_start)); } if (!intersectionPint.IsAlmostEqualTo(_line2_end, 0.0001)) { lines.Add(Line.CreateBound(intersectionPint, _line2_end)); } return(lines); }
static public DuctOrientation GetDuctOrientation(ConnectorManager conMngr) { XYZ orientation = GetDuctDirection(conMngr); double angleToZ = orientation.AngleTo(XYZ.BasisZ); if (orientation.IsAlmostEqualTo(XYZ.BasisZ) || orientation.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { return(DuctOrientation.StraightVertical); } else if (orientation.IsAlmostEqualTo(new XYZ(orientation.X, orientation.Y, 0))) { return(DuctOrientation.Horizontal); } // угол между Z и вектором от 60 до 120 градусов else if (angleToZ > (Math.PI / 3) && angleToZ < (2 * Math.PI / 3)) { return(DuctOrientation.AlmostHorizontal); } // угол между Z и вектором больше 150 градусов или меньше 30 else if (angleToZ > (5 * Math.PI / 6) || angleToZ < (Math.PI / 6)) { return(DuctOrientation.AlmostVertical); } else { return(DuctOrientation.Angled); } }
/// <summary> /// Retrieve the room plan view boundary /// polygon loops and convert to 2D integer-based. /// For optimisation and consistency reasons, /// convert all coordinates to integer values in /// millimetres. Revit precision is limited to /// 1/16 of an inch, which is abaut 1.2 mm, anyway. /// </summary> static JtLoops GetRoomLoops(Room room) { SpatialElementBoundaryOptions opt = new SpatialElementBoundaryOptions(); opt.SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Center; // loops closed //SpatialElementBoundaryLocation.Finish; // loops not closed IList <IList <BoundarySegment> > loops = room. GetBoundarySegments(opt); int nLoops = loops.Count; JtLoops jtloops = new JtLoops(nLoops); foreach (IList <BoundarySegment> loop in loops) { int nSegments = loop.Count; JtLoop jtloop = new JtLoop(nSegments); XYZ p0 = null; // loop start point XYZ p; // segment start point XYZ q = null; // segment end point foreach (BoundarySegment seg in loop) { // Todo: handle non-linear curve. // Especially: if two long lines have a // short arc in between them, skip the arc // and extend both lines. p = seg.Curve.GetEndPoint(0); jtloop.Add(new Point2dInt(p)); Debug.Assert(null == q || q.IsAlmostEqualTo(p), "expected last endpoint to equal current start point"); q = seg.Curve.GetEndPoint(1); if (_debug_output) { Debug.Print("{0} --> {1}", Util.PointString(p), Util.PointString(q)); } if (null == p0) { p0 = p; // save loop start point } } Debug.Assert(q.IsAlmostEqualTo(p0), "expected last endpoint to equal loop start point"); jtloops.Add(jtloop); } return(jtloops); }
/// <summary> /// 判断两根相交线段 结果为1,则是 L型 or V型;为0,则是X型 or T型, 或不相交; 如果是方向一致的线,1则为首尾相连 线段,2则为重叠 /// </summary> /// <param name="_line1"></param> /// <param name="_line2"></param> /// <returns></returns> public static int is_L_or_V_twolinesoverlap(Line _line1, Line _line2) { int _intersectCount = 0; XYZ _line1_start = _line1.GetEndPoint(0); XYZ _line1_end = _line1.GetEndPoint(1); XYZ _line2_start = _line2.GetEndPoint(0); XYZ _line2_end = _line2.GetEndPoint(1); if (_line1_start.IsAlmostEqualTo(_line2_start, 0.0001)) { _intersectCount += 1; } if (_line1_end.IsAlmostEqualTo(_line2_start, 0.0001)) { _intersectCount += 1; } if (_line1_start.IsAlmostEqualTo(_line2_end, 0.0001)) { _intersectCount += 1; } if (_line1_end.IsAlmostEqualTo(_line2_end, 0.0001)) { _intersectCount += 1; } return(_intersectCount); }
/// <summary> /// Identifies if the curve lies entirely in an XY plane (Z = constant) /// </summary> /// <param name="curve">The curve.</param> /// <returns>True if the curve lies in an XY plane, false otherwise.</returns> public static bool IsCurveInXYPlane(Curve curve) { // quick reject - are endpoints at same Z double zDelta = curve.GetEndPoint(1).Z - curve.GetEndPoint(0).Z; if (Math.Abs(zDelta) > 1e-05) { return(false); } if (!(curve is Line) && !curve.IsCyclic) { // Create curve loop from curve and connecting line to get plane List <Curve> curves = new List <Curve>(); curves.Add(curve); curves.Add(Line.CreateBound(curve.GetEndPoint(1), curve.GetEndPoint(0))); CurveLoop curveLoop = CurveLoop.Create(curves); XYZ normal = curveLoop.GetPlane().Normal.Normalize(); if (!normal.IsAlmostEqualTo(XYZ.BasisZ) && !normal.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { return(false); } } return(true); }
/// <summary> /// Check if the given bottom edge was shared by a trapezoid face with left edge vertical. /// </summary> /// <param name="hostNormal">Corbel Host face Normal</param> /// <param name="corbelBottomFace">Bottom Face of Corbel</param> /// <param name="bottomEdge">Given bottom edge to test</param> /// <param name="trapezoidFace">Output the trapezoid Face</param> /// <param name="topEdge">Output trapezoid top edge</param> /// <param name="leftEdge">Output trapezoid left edge</param> /// <param name="rightEdge">Output trapezoid right edge</param> /// <returns>True if there is a trapezoid face share the given bottom edge, otherwise false.</returns> private static bool IsTrapezoid( XYZ hostNormal, PlanarFace corbelBottomFace, Edge bottomEdge, out PlanarFace trapezoidFace, out Edge topEdge, out Edge leftEdge, out Edge rightEdge) { PlanarFace face1 = bottomEdge.get_Face(0) as PlanarFace; PlanarFace face2 = bottomEdge.get_Face(1) as PlanarFace; trapezoidFace = face1 == corbelBottomFace ? face2 : face1; EdgeArray trapezoidFaceEdges = trapezoidFace.EdgeLoops.get_Item(0); XYZ bottomEdgeDir = (bottomEdge.Evaluate(1.0) - bottomEdge.Evaluate(0.0)).Normalize(); int bottomEdgeIndex = -1; topEdge = null; for (int i = 0; i < trapezoidFaceEdges.Size; i++) { Edge edge = trapezoidFaceEdges.get_Item(i); XYZ edgeDir = (edge.Evaluate(1.0) - edge.Evaluate(0.0)).Normalize(); if (edgeDir.IsAlmostEqualTo(bottomEdgeDir) || edgeDir.IsAlmostEqualTo(-bottomEdgeDir)) { if (edge.Evaluate(0.0).IsAlmostEqualTo(bottomEdge.Evaluate(0.0))) { bottomEdge = edge; bottomEdgeIndex = i; } else { topEdge = edge; } } } leftEdge = trapezoidFaceEdges.get_Item((trapezoidFaceEdges.Size + bottomEdgeIndex - 1) % trapezoidFaceEdges.Size); rightEdge = trapezoidFaceEdges.get_Item((bottomEdgeIndex + 1) % trapezoidFaceEdges.Size); XYZ leftEdgeDir = (leftEdge.Evaluate(1.0) - leftEdge.Evaluate(0.0)).Normalize(); bool isLeftEdgeVertical = false; if (leftEdgeDir.IsAlmostEqualTo(hostNormal) || leftEdgeDir.IsAlmostEqualTo(-hostNormal)) { isLeftEdgeVertical = true; } XYZ rightEdgeDir = (rightEdge.Evaluate(1.0) - rightEdge.Evaluate(0.0)).Normalize(); bool rightEdgeIsVertical = false; if (rightEdgeDir.IsAlmostEqualTo(hostNormal) || rightEdgeDir.IsAlmostEqualTo(-hostNormal)) { rightEdgeIsVertical = true; } return(isLeftEdgeVertical && !rightEdgeIsVertical); }
public static List <Curve> SplitCurve(Curve c, XYZ p, double shortCurveTolerance, bool preserveDirection = true) { //only lines are splited, arcs must implemented if (c != null && p != null //&& c is Line && IsPointOnCurve(c, p)) { XYZ cS = GetEndPoint(c, 0); XYZ cE = GetEndPoint(c, 1); if (!p.IsAlmostEqualTo(cS) && !p.IsAlmostEqualTo(cE) && (p.DistanceTo(cS) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cS), shortCurveTolerance)) && (p.DistanceTo(cE) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cE), shortCurveTolerance))) { Curve c1 = null; Curve c2 = null; if (c is Arc) { Arc arc = c as Arc; //XYZ center = arc.Evaluate(0.5, true); XYZ center1 = PushOnCurveByCurve(c, GetEndPoint(c, 0), VectorUtils.GetVectorOfCurve(c), cS.DistanceTo(p) / 2.0); XYZ center2 = PushOnCurveByCurve(c, GetEndPoint(c, 1), VectorUtils.GetVectorOfCurve(c).Negate(), cE.DistanceTo(p) / 2.0); c1 = Arc.Create(cS, p, center1); c2 = Arc.Create(p, cE, center2); } else { if (preserveDirection) { c1 = LineUtils.NewLineBound(cS, p) as Curve; c2 = LineUtils.NewLineBound(p, cE) as Curve; } else { c1 = LineUtils.NewLineBound(p, cS) as Curve; c2 = LineUtils.NewLineBound(p, cE) as Curve; } } if (c1 != null && c2 != null) { return(new List <Curve>() { c1, c2 }); } } } return(null); }
/// <summary> /// Generate and return an SVG path definition to /// represent the given room boundary loop, scaled /// from the given bounding box to fit into a /// 100 x 100 canvas. Actually, the size is /// determined by _target_square_size. /// </summary> string GetSvgPathFrom( BoundingBoxXYZ bb, IList <BoundarySegment> loop) { // Determine scaling and offsets to transform // from bounding box to (0,0)-(100,100). XYZ pmin = bb.Min; XYZ pmax = bb.Max; XYZ vsize = pmax - pmin; XYZ pmid = pmin + 0.5 * vsize; double size = Math.Max(vsize.X, vsize.Y); double scale = _target_square_size / size; StringBuilder s = new StringBuilder(); int nSegments = loop.Count; XYZ p0 = null; // loop start point XYZ p; // segment start point XYZ q = null; // segment end point foreach (BoundarySegment seg in loop) { Curve curve = seg.GetCurve(); // Todo: handle non-linear curve. // Especially: if two long lines have a // short arc in between them, skip the arc // and extend both lines. p = curve.GetEndPoint(0); Debug.Assert(null == q || q.IsAlmostEqualTo(p), "expected last endpoint to equal current start point"); q = curve.GetEndPoint(1); if (null == p0) { p0 = p; // save loop start point s.Append("M" + GetSvgPointFrom(p, pmid, scale)); } s.Append("L" + GetSvgPointFrom(q, pmid, scale)); } s.Append("Z"); Debug.Assert(q.IsAlmostEqualTo(p0), "expected last endpoint to equal loop start point"); return(s.ToString()); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { // 【获取句柄】 UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; // 【获取墙】 Wall wall = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall; if (wall != null) { // 【获取定位线】 Line wallLine = (wall.Location as LocationCurve).Curve as Line; // 【获取方向,用来寻找参照】 XYZ wallDir = wallLine.Direction; // 【获取墙定位线的参照】 ReferenceArray refArry = new ReferenceArray(); // 【定义几何选项】 Options opt = new Options(); opt.ComputeReferences = true; opt.DetailLevel = ViewDetailLevel.Fine; //【获取墙的几何】 GeometryElement gelem = wall.get_Geometry(opt); foreach (GeometryObject gobj in gelem) { if (gobj is Solid) { Solid solid = gobj as Solid; if (solid.Volume > 0) { foreach (Face face in solid.Faces) { if (face is PlanarFace) { XYZ faceDir = face.ComputeNormal(new UV()); //判断是否平行 if (faceDir.IsAlmostEqualTo(wallDir) || faceDir.IsAlmostEqualTo(-wallDir)) { refArry.Append(face.Reference); TaskDialog.Show("1", "1"); } } } } } } Transaction trans = new Transaction(doc, "开始标注"); trans.Start(); Dimension dimension = doc.Create.NewDimension(doc.ActiveView, wallLine, refArry); trans.Commit(); } return(Result.Succeeded); }
public static List <Curve> GetBoundary(List <CurveArray> polys) { bool IsSame(Curve crv1, Curve crv2) { XYZ start1 = crv1.GetEndPoint(0); XYZ start2 = crv2.GetEndPoint(0); XYZ end1 = crv1.GetEndPoint(1); XYZ end2 = crv2.GetEndPoint(1); if (start1.IsAlmostEqualTo(start2) && end1.IsAlmostEqualTo(end2) || start1.IsAlmostEqualTo(end2) && start2.IsAlmostEqualTo(end1)) { return(true); } else { return(false); } } List <Curve> shatters = new List <Curve>(); List <Curve> boundary = new List <Curve>(); foreach (CurveArray poly in polys) { for (int i = 0; i < poly.Size; i++) { shatters.Add(poly.get_Item(i)); } } Debug.Print("Shatters in all: " + shatters.Count.ToString()); for (int i = 0; i < shatters.Count; i++) { for (int j = 0; j < shatters.Count; j++) { if (j != i) { if (IsSame(shatters[i], shatters[j])) { goto a; } } } boundary.Add(shatters[i]); a :; } Debug.Print("Boundry size: " + boundary.Count.ToString()); return(boundary); }
/// <summary> /// Creates a selection filter that will let faces pass, if their normal vector at (0/0) is /// codirectional or parallel to the given normal vector /// </summary> /// <param name="doc"></param> /// <param name="normal"></param> /// <param name="acceptParallel"></param> /// <returns></returns> public static IReferenceSelectionFilter GetFaceNormalFilter(Document doc, XYZ normal, bool acceptParallel = false) { XYZ _normal = normal.Normalize (); XYZ minusNormal = -1*_normal; return GetReferenceFilter ((reference, xyz) => { Element element = doc.GetElement (reference); Face face = element.GetGeometryObjectFromReference (reference) as Face; if (face == null) return false; XYZ faceNormal = face.ComputeNormal (UV.Zero); bool erg = faceNormal.IsAlmostEqualTo (_normal); if (acceptParallel) erg |= faceNormal.IsAlmostEqualTo(minusNormal); return erg; }); }
public static IList <PlanarFace> ListNearestFace(PlanarFace face, IList <PlanarFace> listFaces) { IList <PlanarFace> list = new List <PlanarFace>(); PlanarFace face2 = Facelibry.NearestFace(face, listFaces); XYZ point = Facelibry.CenterPoint(face2); double num = Facelibry.PointToFace(point, face); XYZ faceNormal = face.FaceNormal; XYZ right = Facelibry.CenterPoint(face); foreach (PlanarFace planarFace in listFaces) { XYZ xyz = Facelibry.CenterPoint(planarFace); XYZ xyz2 = xyz - right; bool flag = xyz2.IsAlmostEqualTo(new XYZ()); if (!flag) { double num2 = Facelibry.PointToFace(xyz, face); bool flag2 = num2 <1.02 * num && num2> 0.98 * num; if (flag2) { list.Add(planarFace); } } } return(list); }
public static bool ExtentGeometryChanged(Guid docId, ElementId currentGridId, Outline currentOutline) { bool changed = false; try { if (gridExtents.ContainsKey(docId)) { if (gridExtents[docId].ContainsKey(currentGridId)) { Outline oldOutline = gridExtents[docId][currentGridId]; XYZ oldMin = oldOutline.MinimumPoint; XYZ oldMax = oldOutline.MaximumPoint; XYZ curMin = currentOutline.MinimumPoint; XYZ curMax = currentOutline.MaximumPoint; if (!oldMin.IsAlmostEqualTo(curMin) || !oldMax.IsAlmostEqualTo(curMax)) { changed = true; } } } } catch (Exception ex) { string message = ex.Message; } return(changed); }
/// <summary> /// Check if a point is on a line /// </summary> /// <param name="pt"></param> /// <param name="line"></param> /// <returns></returns> public static bool IsPtOnLine(XYZ pt, Line line) { XYZ ptStart = line.GetEndPoint(0); XYZ ptEnd = line.GetEndPoint(1); XYZ vec1 = (ptStart - pt).Normalize(); XYZ vec2 = (ptEnd - pt).Normalize(); if (!vec1.IsAlmostEqualTo(vec2) || pt.IsAlmostEqualTo(ptStart) || pt.IsAlmostEqualTo(ptEnd)) { return(true); } else { return(false); } }
private Room getOtherRoom(Room r1, BoundarySegment seg, XYZ point) { // we already know what one of the rooms is attached to a boundary segment. // this attempts to find the other. Curve crv = seg.GetCurve(); XYZ vector = crv.GetEndPoint(1).Subtract(crv.GetEndPoint(0)).Normalize(); XYZ otherVector = XYZ.BasisZ; if (vector.IsAlmostEqualTo(XYZ.BasisZ)) { otherVector = XYZ.BasisY; } XYZ perp = vector.CrossProduct(otherVector).Normalize(); XYZ testp1 = point.Add(perp.Multiply(0.25)); XYZ testp2 = point.Add(perp.Negate().Multiply(0.25)); Parameter phaseParm = r1.get_Parameter(BuiltInParameter.ROOM_PHASE); Phase p = _doc.GetElement(phaseParm.AsElementId()) as Phase; Room roomP1 = _doc.GetRoomAtPoint(testp1, p); Room roomP2 = _doc.GetRoomAtPoint(testp2, p); if ((roomP1 != null) && (roomP1.Id != r1.Id)) { return(roomP1); } if ((roomP2 != null) && (roomP2.Id != r1.Id)) { return(roomP2); } return(null); }
/// <summary> /// Check point in polygon containment by vector crossproduct /// Only apply to cw or ccw polycurve array /// </summary> /// <param name="crvArr"></param> /// <param name="pt"></param> /// <returns></returns> public static bool PointInPoly(CurveArray crvArr, XYZ pt) { int judgement = 0; int counter = 0; foreach (Curve crv in crvArr) { XYZ ptstart = crv.GetEndPoint(0); XYZ ptend = crv.GetEndPoint(1); XYZ direction = (pt - ptstart).CrossProduct(pt - ptend).Normalize(); if (direction.IsAlmostEqualTo(new XYZ(0, 0, 1))) { judgement += 1; } counter += 1; } if (judgement < counter) { return(false); } else { return(true); } }
public static void API_rotate(Document doc) { XYZ pos2 = (tempFi1.Location as LocationPoint).Point; XYZ face2 = tempFi1.FacingOrientation; using (Transaction trans = new Transaction(doc)) { trans.Start("rotate"); doc.Delete(tempFi1.Id); trans.Commit(); } if (pos1.IsAlmostEqualTo(pos2)) { return; } else { //求旋转中心 XYZ rotateCenter = GetRotateCenter(pos1, face1, pos2, face2); double angle = face1.AngleOnPlaneTo(face2, new XYZ(0, 0, 1)); using (Transaction trans = new Transaction(doc)) { trans.Start("rotate"); //执行模块打的旋转操作 //ModuleRotate.RotateOperation(doc, Rotate_CMD.allFi, rotateCenter, angle); trans.Commit(); } } }
public static bool ExtentGeometryChanged(string centralPath, ElementId currentGridId, Outline currentOutline) { bool changed = false; try { if (gridExtents.ContainsKey(centralPath)) { if (gridExtents[centralPath].ContainsKey(currentGridId)) { Outline oldOutline = gridExtents[centralPath][currentGridId]; XYZ oldMin = oldOutline.MinimumPoint; XYZ oldMax = oldOutline.MaximumPoint; XYZ curMin = currentOutline.MinimumPoint; XYZ curMax = currentOutline.MaximumPoint; if (!oldMin.IsAlmostEqualTo(curMin) || !oldMax.IsAlmostEqualTo(curMax)) { changed = true; } } } } catch (Exception ex) { string message = ex.Message; LogUtil.AppendLog("GridUtils-ExtentGeometryChanged:" + ex.Message); } return(changed); }
public Particle makeParticleFromXYZ(ElementId eid, double mass, XYZ position, bool fix) { bool found = false; for (int i = 0; i < particles.Count(); ++i) { if (eid != null && (particles[i].getElementID() != null) && position != null) { if (position.IsAlmostEqualTo(particles[i].getPosition())) { found = true; particles[i].setPosition(position); return(particles[i]); } } } if (found == false)//if we did not find one make a new one { Particle part = new Particle(partID++, eid, mass, position, fix); particles.Add(part); return(part); } return(null); }
private FamilyInstanceCreationData GetCreationData(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol) { //calculate the desired rotation //we do this by finding the angle between the z axis //and vector between the start of the beam and the target point //both projected onto the start plane of the beam. var zAxis = new XYZ(0, 0, 1); var yAxis = new XYZ(0, 1, 0); //flatten the beam line onto the XZ plane //using the start's z coordinate var start = curve.GetEndPoint(0); var end = curve.GetEndPoint(1); var newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane //catch the case where the end is directly above //the start, creating a normal with zero length //in that case, use the Z axis XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize(); double gamma = upVector.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal); return(new FamilyInstanceCreationData(curve, symbol, level, structuralType) { RotateAngle = gamma }); }
static public Curve Flatten(this Curve curve, double height = 0) { XYZ firstPoint = curve.GetEndPoint(0); firstPoint = new XYZ(firstPoint.X, firstPoint.Y, height); XYZ secondPoint = curve.GetEndPoint(1); secondPoint = new XYZ(secondPoint.X, secondPoint.Y, height); if (firstPoint.IsAlmostEqualTo(secondPoint)) { return(null); } if (curve is Line) { return(Line.CreateBound(firstPoint, secondPoint)); } if (curve is Arc) { XYZ centerPoint = curve.Evaluate(0.5, true); centerPoint = new XYZ(centerPoint.X, centerPoint.Y, height); return(Arc.Create(firstPoint, secondPoint, centerPoint)); } throw new Exception("THIAGO -> Curve can't be flatten because it is not a line or arc"); }
public void Test() { XYZ2 xyz_1 = new XYZ2(0, 0, 0); XYZ2 xyz_2 = new XYZ2(0, 0, 1); XYZ2 xyz_3 = new XYZ2(0, 1, 0); XYZ a = new XYZ(0, 1.0, 0); TaskDialog.Show("xyz", (a.IsAlmostEqualTo(xyz_3)).ToString()); List <XYZ2> myListXYZ = new List <XYZ2>() { xyz_1, xyz_2, xyz_3 }; XYZ2 xyz_test = new XYZ2(0, 0, 0); if (xyz_1 == xyz_test) { TaskDialog.Show("abc", "Yes"); } if (myListXYZ.Contains(xyz_test)) { TaskDialog.Show("abc", "Yes"); } else { TaskDialog.Show("abc", "No"); } }
static private XYZ GetExtendedPoint(XYZ startPosition, PlanarFace targetPlanarFace, double amount = 0.1) { if (targetPlanarFace != null) { CurveLoop currentCurveLoop = GetOuterCurveLoop(targetPlanarFace); foreach (Curve currentCurve in currentCurveLoop) { if (currentCurve.GetEndPoint(0).Z.IsAlmostEqualTo(targetPlanarFace.Origin.Z) && currentCurve.GetEndPoint(1).Z.IsAlmostEqualTo(targetPlanarFace.Origin.Z)) { XYZ p0 = startPosition; XYZ p1 = startPosition; if (p0.IsAlmostEqualTo(currentCurve.GetEndPoint(0))) { p1 = currentCurve.GetEndPoint(1); } else { p1 = currentCurve.GetEndPoint(0); } XYZ lineDirection = Line.CreateBound(p0, p1).Direction; XYZ extendendPoint = p0 + (lineDirection.Negate() * amount); return(extendendPoint); } } } return(startPosition); }
/// <summary> /// /// </summary> /// <param name="cur1"></param> /// <param name="cur2"></param> /// <param name="mergedCur"></param> /// <returns></returns> public static bool Merge(Bcurve cur1, Bcurve cur2, out Bcurve mergedCur) { mergedCur = new Bcurve(); if ((cur1.Id == cur2.Id) && (cur1.Curve is Line) && (cur2.Curve is Line)) { Line lin1 = cur1.Curve as Line; Line lin2 = cur2.Curve as Line; if ((lin1.Direction.Normalize().IsAlmostEqualTo (lin2.Direction.Normalize())) && (lin1.IsBound) && (lin2.IsBound)) { XYZ lin1s = lin1.GetEndPoint(0); XYZ lin1e = lin1.GetEndPoint(1); XYZ lin2s = lin2.GetEndPoint(0); XYZ lin2e = lin2.GetEndPoint(1); if (lin1s.IsAlmostEqualTo(lin2e)) { mergedCur = new Bcurve (Line.CreateBound(lin2s, lin1e), cur1); return(true); } else if (lin1e.IsAlmostEqualTo(lin2s)) { mergedCur = new Bcurve( Line.CreateBound(lin1s, lin2e), cur1); return(true); } } } return(false); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Wall wall = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall; if (wall != null) { ReferenceArray refArry = new ReferenceArray(); Line wallLine = (wall.Location as LocationCurve).Curve as Line; XYZ wallDir = ((wall.Location as LocationCurve).Curve as Line).Direction; // wallDir = new XYZ(wallDir.Y, -wallDir.X, 0); Options opt = new Options(); opt.ComputeReferences = true; opt.DetailLevel = ViewDetailLevel.Fine; GeometryElement gelem = wall.get_Geometry(opt); foreach (GeometryObject gobj in gelem) { if (gobj is Solid) { Solid solid = gobj as Solid; foreach (Face face in solid.Faces) { if (face is PlanarFace) { XYZ faceDir = face.ComputeNormal(new UV()); if (faceDir.IsAlmostEqualTo(wallDir) || faceDir.IsAlmostEqualTo(-wallDir)) { refArry.Append(face.Reference); } } } } } Transaction trans = new Transaction(doc, "trans"); trans.Start(); doc.Create.NewDimension(doc.ActiveView, wallLine, refArry); trans.Commit(); } return(Result.Succeeded); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uiDoc = commandData.Application.ActiveUIDocument; Document doc = uiDoc.Document; FilteredElementCollector coll = new FilteredElementCollector(doc); ElementClassFilter gridFilter = new ElementClassFilter(typeof(Grid)); List <Element> grid = coll.WherePasses(gridFilter).ToElements().ToList(); List <Line> gridLines = new List <Line>(); List <XYZ> intXyzs = new List <XYZ>(); foreach (Grid g in grid) { gridLines.Add(g.Curve as Line); } foreach (Line line1 in gridLines) { foreach (Line line2 in gridLines) { XYZ normal1 = line1.Direction; XYZ normal2 = line2.Direction; if (normal1.IsAlmostEqualTo(normal2)) { continue;//如果平行,执行下一条 } SetComparisonResult intRst = line1.Intersect(line2, out IntersectionResultArray results); if (intRst == SetComparisonResult.Overlap && results.Size == 1) { XYZ tp = results.get_Item(0).XYZPoint; if (intXyzs.Where(m => m.IsAlmostEqualTo(tp)).Count() == 0) { intXyzs.Add(tp);//如果不重复,则添加该交点 } } } } Level level = doc.GetElement(new ElementId(311)) as Level; FamilySymbol familySymbol = doc.GetElement(new ElementId(338370)) as FamilySymbol; using (Transaction tr = new Transaction(doc)) { tr.Start("Clomn"); if (!familySymbol.IsActive) { familySymbol.Activate(); } foreach (XYZ xyz in intXyzs) { FamilyInstance familyInstance = doc.Create.NewFamilyInstance(xyz, familySymbol, level, StructuralType.NonStructural); } tr.Commit(); } return(Result.Succeeded); }
private List <ModelCurve> DrawInsulLine(MEPCurve e, double stepLength, double height, GraphicsStyle style) { Curve ductCurve = GeometryUtils.FindDuctCurve(e.ConnectorManager); XYZ pt1 = ductCurve.GetEndPoint(0); XYZ pt2 = ductCurve.GetEndPoint(1); // создаем плоскость, на которой будет рисоваться штриховка XYZ VOffset; XYZ ductVector = GeometryUtils.GetDuctDirection(e.ConnectorManager); // Вертикальная линии if (ductVector.IsAlmostEqualTo(XYZ.BasisZ) | ductVector.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { // находим перпендикулярный вектор, нормализуем его и умножаем до нужной длины VOffset = (pt2 - pt1).CrossProduct(XYZ.BasisY).Normalize() * (height / 2); } else { VOffset = (pt2 - pt1).CrossProduct(XYZ.BasisZ).Normalize() * (height / 2); } XYZ UOffset = (pt2 - pt1).Normalize() * (stepLength / 2); int steps = (int)Math.Floor((pt2 - pt1).GetLength() / UOffset.GetLength()); List <XYZ> points = new List <XYZ>(); points.Add(pt1); for (int i = 0; i < steps; i++) { pt1 = pt1 + UOffset; XYZ VOffsetedPt = pt1 + VOffset; points.Add(VOffsetedPt); VOffset = VOffset.Negate(); } points.Add(pt2); ModelCurveCreator mcc = new ModelCurveCreator(doc); mcc.LineStyle = style; if (points.Count() > 2) { var array = mcc.MakeModelCurve(points, false); return(array); } else { return(null); } }
private bool IsParallel(Grid grid1, Grid grid2) { Line line1 = grid1.Curve as Line; Line line2 = grid2.Curve as Line; XYZ direction1 = line1.Direction; XYZ backdirection1 = direction1.Negate(); XYZ direction2 = line2.Direction; if (direction2.IsAlmostEqualTo(direction1) || direction2.IsAlmostEqualTo(backdirection1)) { return(true); } else { return(false); } }
/// <summary> /// 找到一个点与所有线段的重合端点线段,并输出重合端点的线段索引值 /// </summary> /// <param name="_i_xyz"></param> /// <param name="_Lines"></param> /// <param name="Lines"></param> /// <returns></returns> public static int IsXYZcoincideAllLines(XYZ _i_xyz, List <Line> _Lines, out List <int> list_int) { list_int = new List <int>();//收集与 i 线段的一个端点重合线段的索引值 int _count = _Lines.Count; for (int k = 0; k < _count; k++) { XYZ _k_xyz_0 = _Lines[k].GetEndPoint(0); XYZ _k_xyz_1 = _Lines[k].GetEndPoint(1); if (_i_xyz.IsAlmostEqualTo(_k_xyz_0, 0.0001) || _i_xyz.IsAlmostEqualTo(_k_xyz_1, 0.0001))//判断线段端点是否重合 { list_int.Add(k); } } return(list_int.Count); }
static public DuctOrientation GetDuctOrientation(ConnectorManager conMngr) { XYZ orientation = GetDuctDirection(conMngr); if (orientation.IsAlmostEqualTo(XYZ.BasisZ) || orientation.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { return(DuctOrientation.StraightVertical); } else if (orientation.IsAlmostEqualTo(new XYZ(orientation.X, orientation.Y, 0))) { return(DuctOrientation.Horizontal); } else { return(DuctOrientation.Angled); } }
public static Solid CylinderByAxisOriginRadiusHeight(XYZ axis, XYZ origin, double radius, double height) { // get axis that is perp to axis by first generating random vector var zaxis = axis.Normalize(); var randXyz = new XYZ(1, 0, 0); if (axis.IsAlmostEqualTo(randXyz)) randXyz = new XYZ(0, 1, 0); var yaxis = zaxis.CrossProduct(randXyz).Normalize(); // get second axis that is perp to axis var xaxis = yaxis.CrossProduct(zaxis); // create circle (this is ridiculous, but curve loop doesn't work with a circle - you need two arcs) var arc1 = dynRevitSettings.Doc.Application.Application.Create.NewEllipse(origin, radius, radius, xaxis, yaxis, 0, Circle.RevitPI); var arc2 = dynRevitSettings.Doc.Application.Application.Create.NewEllipse(origin, radius, radius, xaxis, yaxis, Circle.RevitPI, 2 * Circle.RevitPI); // create curve loop from cirle var circleLoop = Autodesk.Revit.DB.CurveLoop.Create(new List<Curve>() { arc1, arc2 }); // extrude the curve and return return GeometryCreationUtilities.CreateExtrusionGeometry(new List<Autodesk.Revit.DB.CurveLoop>() { circleLoop }, zaxis, height); }
/// <summary> /// Find the list of parallel linear grids via the given direction. /// </summary> /// <param name="linearGrids">The set of linear grids.</param> /// <param name="baseDirection">The given direction.</param> /// <returns>The list of parallel grids, containing the anti direction grids.</returns> private static List<Grid> FindParallelGrids(IDictionary<XYZ, List<Grid>> linearGrids, XYZ baseDirection) { List<XYZ> directionList = linearGrids.Keys.ToList(); List<Grid> parallelGrids = linearGrids[baseDirection]; foreach (XYZ direction in directionList) { if (baseDirection.IsAlmostEqualTo(direction)) continue; double dotProduct = direction.DotProduct(baseDirection); if (MathUtil.IsAlmostEqual(dotProduct, -1.0)) { parallelGrids = parallelGrids.Union<Grid>(linearGrids[direction]).ToList(); return parallelGrids; } } return parallelGrids; }
public override Value Evaluate(FSharpList<Value> args) { var symbol = (FamilySymbol)((Value.Container)args[0]).Item; var curves = ((Value.List) args[1]).Item; IEnumerable<Tuple<Curve, XYZ>> data; if (args[2].IsList) { var targets = ((Value.List)args[2]).Item; if (curves.Count() != targets.Count()) throw new Exception("The number of curves and the number of up vectors must be the same."); //if we get a list of up vectors, then pair each //curve with a corresponding up vector data = curves.Zip(targets, (first, second) => new Tuple<Curve, XYZ>((Curve) ((Value.Container) first).Item, (XYZ) ((Value.Container) second).Item)); } else { //if we get a single up vector, then pair each //curve with that up vector data = curves.Select(x=>new Tuple<Curve, XYZ>((Curve)((Value.Container)x).Item, (XYZ)((Value.Container)args[2]).Item)); } var instData = new List<FamilyInstanceCreationData>(); int count = 0; foreach (var pair in data) { var curve = pair.Item1; var target = pair.Item2; //calculate the desired rotation //we do this by finding the angle between the z axis //and vector between the start of the beam and the target point //both projected onto the start plane of the beam. XYZ zAxis = new XYZ(0, 0, 1); XYZ yAxis = new XYZ(0, 1, 0); //flatten the beam line onto the XZ plane //using the start's z coordinate XYZ start = curve.get_EndPoint(0); XYZ end = curve.get_EndPoint(1); XYZ newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane ////use the x axis of the curve's transform ////as the normal of the start plane //XYZ planeNormal = (curve.get_EndPoint(0) - curve.get_EndPoint(1)).Normalize(); //catch the case where the end is directly above //the start, creating a normal with zero length //in that case, use the Z axis XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize(); XYZ target_project = target - target.DotProduct(planeNormal)*planeNormal; XYZ z_project = zAxis - zAxis.DotProduct(planeNormal)*planeNormal; //double gamma = target_project.AngleTo(z_project); double gamma = target.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal); FamilyInstance instance = null; if (this.Elements.Count > count) { if (dynUtils.TryGetElement(this.Elements[count], out instance)) { if (instance.Symbol != symbol) instance.Symbol = symbol; //update the curve var locCurve = instance.Location as LocationCurve; locCurve.Curve = curve; } else { var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam) { RotateAngle = gamma }; instData.Add(beamData); } } else { var beamData = new FamilyInstanceCreationData(curve, symbol, dynRevitSettings.DefaultLevel, StructuralType.Beam) { RotateAngle = gamma }; instData.Add(beamData); } count++; } //trim the elements collection foreach (var e in this.Elements.Skip(count)) { this.DeleteElement(e); } FSharpList<Value> results = FSharpList<Value>.Empty; if (instData.Any()) { var ids = dynRevitSettings.Doc.Document.Create.NewFamilyInstances2(instData); //add our batch-created instances ids' //to the elements collection ids.ToList().ForEach(x=>Elements.Add(x)); } //add all of the instances results = Elements.Aggregate(results, (current, id) => FSharpList<Value>.Cons(Value.NewContainer(dynRevitSettings.Doc.Document.GetElement(id)), current)); results.Reverse(); return Value.NewList(results); }
public void CreateModelLine( XYZ p, XYZ q ) { if( p.IsAlmostEqualTo( q ) ) { throw new ArgumentException( "Expected two different points." ); } Line line = Line.CreateBound( p, q ); if( null == line ) { throw new Exception( "Geometry line creation failed." ); } _credoc.NewModelCurve( line, NewSketchPlanePassLine( line ) ); }
public Particle makeParticleFromXYZ(ElementId eid, double mass, XYZ position, bool fix) { bool found = false; for (int i = 0; i < particles.Count(); ++i) { if (eid != null && (particles[i].getElementID() != null)&& position!=null) { if (position.IsAlmostEqualTo(particles[i].getPosition())) { found = true; particles[i].setPosition(position); return particles[i]; } } } if (found == false)//if we did not find one make a new one { Particle part = new Particle(partID++, eid, mass, position, fix); particles.Add(part); return part; } return null; }
public Particle getParticleByXYZ(XYZ xyz) { for (int i = 0; i < particles.Count(); ++i) { if (xyz != null && particles.Count > 0 && (particles[i].getElementID() != null)) { if (xyz.IsAlmostEqualTo(particles[i].getPosition())) { return particles[i]; } } } return null; }
private static FamilyInstanceCreationData GetCreationData(Autodesk.Revit.DB.Curve curve, Autodesk.Revit.DB.XYZ upVector, Autodesk.Revit.DB.Level level, Autodesk.Revit.DB.Structure.StructuralType structuralType, Autodesk.Revit.DB.FamilySymbol symbol) { //calculate the desired rotation //we do this by finding the angle between the z axis //and vector between the start of the beam and the target point //both projected onto the start plane of the beam. var zAxis = new XYZ(0, 0, 1); var yAxis = new XYZ(0, 1, 0); //flatten the beam line onto the XZ plane //using the start's z coordinate var start = curve.GetEndPoint(0); var end = curve.GetEndPoint(1); var newEnd = new XYZ(end.X, end.Y, start.Z); //drop end point to plane //catch the case where the end is directly above //the start, creating a normal with zero length //in that case, use the Z axis XYZ planeNormal = newEnd.IsAlmostEqualTo(start) ? zAxis : (newEnd - start).Normalize(); double gamma = upVector.AngleOnPlaneTo(zAxis.IsAlmostEqualTo(planeNormal) ? yAxis : zAxis, planeNormal); return new FamilyInstanceCreationData(curve, symbol, level, structuralType) { RotateAngle = gamma }; }
/// <summary> /// Returns a handle for creation of an AdvancedBrep with AdvancedFace and assigns it to the file /// </summary> /// <param name="exporterIFC">exporter IFC</param> /// <param name="element">the element</param> /// <param name="options">exporter option</param> /// <param name="geomObject">the geometry object</param> /// <returns>the handle</returns> public static IFCAnyHandle ExportBodyAsAdvancedBrep(ExporterIFC exporterIFC, Element element, BodyExporterOptions options, GeometryObject geomObject) { IFCFile file = exporterIFC.GetFile(); Document document = element.Document; IFCAnyHandle advancedBrep = null; try { if (geomObject is Solid) { IList<IFCAnyHandle> edgeLoopList = new List<IFCAnyHandle>(); HashSet<IFCAnyHandle> cfsFaces = new HashSet<IFCAnyHandle>(); Solid geomSolid = geomObject as Solid; FaceArray faces = geomSolid.Faces; foreach (Face face in faces) { IList<IFCAnyHandle> orientedEdgeList = new List<IFCAnyHandle>(); IFCAnyHandle surface = null; // Use SortCurveLoops to collect the outerbound(s) with its list of innerbounds IList<IList<CurveLoop>> curveloopList = ExporterIFCUtils.SortCurveLoops(GetEdgesAsCurveLoops(face)); IList<HashSet<IFCAnyHandle>> boundsCollection = new List<HashSet<IFCAnyHandle>>(); // loop for each outerloop (and its list of innerloops foreach (IList<CurveLoop> curveloops in curveloopList) { foreach (CurveLoop curveloop in curveloops) { CurveLoopIterator curveloopIter = curveloop.GetCurveLoopIterator(); XYZ lastPoint = new XYZ(); bool first = true; bool unbounded = false; while (curveloopIter.MoveNext()) { IFCAnyHandle edgeCurve = null; bool orientation = true; bool sameSense = true; Curve currCurve = curveloopIter.Current; IFCAnyHandle edgeStart = null; IFCAnyHandle edgeEnd = null; if (currCurve.IsBound) { IFCAnyHandle edgeStartCP = XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(0), true); edgeStart = IFCInstanceExporter.CreateVertexPoint(file, edgeStartCP); IFCAnyHandle edgeEndCP = XYZtoIfcCartesianPoint(exporterIFC, currCurve.GetEndPoint(1), true); edgeEnd = IFCInstanceExporter.CreateVertexPoint(file, edgeEndCP); } else { unbounded = true; } // Detect the sense direction by the continuity of the last point in the previous curve to the first point of the current curve if (!unbounded) { if (first) { lastPoint = currCurve.GetEndPoint(1); sameSense = true; first = false; } else { if (lastPoint.IsAlmostEqualTo(currCurve.GetEndPoint(1))) { sameSense = false; lastPoint = currCurve.GetEndPoint(0); } else { sameSense = true; lastPoint = currCurve.GetEndPoint(1); } } } // if the Curve is a line, do the following edgeCurve = CreateEdgeCurveFromCurve(file, exporterIFC, currCurve, edgeStart, edgeEnd, sameSense); if (IFCAnyHandleUtil.IsNullOrHasNoValue(edgeCurve)) continue; IFCAnyHandle orientedEdge = IFCInstanceExporter.CreateOrientedEdge(file, edgeCurve, orientation); orientedEdgeList.Add(orientedEdge); } IFCAnyHandle edgeLoop = IFCInstanceExporter.CreateEdgeLoop(file, orientedEdgeList); edgeLoopList.Add(edgeLoop); // The list may contain outer edges and inner edges } // Process the edgelooplist bool orientationFB = true; //temp HashSet<IFCAnyHandle> bounds = new HashSet<IFCAnyHandle>(); IFCAnyHandle faceOuterBound = IFCInstanceExporter.CreateFaceOuterBound(file, edgeLoopList[0], orientationFB); bounds.Add(faceOuterBound); if (edgeLoopList.Count > 1) { orientationFB = false; //temp // Process inner bound for (int ii = 1; ii < edgeLoopList.Count; ++ii) { IFCAnyHandle faceBound = IFCInstanceExporter.CreateFaceBound(file, edgeLoopList[ii], orientationFB); bounds.Add(faceBound); } } // We collect the list of Outerbounds (plus their innerbounds) here // to create multiple AdvancedFaces from the same face if there are multiple faceouterbound boundsCollection.Add(bounds); } // process the face now if (face is PlanarFace) { PlanarFace plFace = face as PlanarFace; XYZ plFaceNormal = plFace.Normal; IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, plFace.Origin, true); IList<double> zaxis = new List<double>(); IList<double> refdir = new List<double>(); zaxis.Add(0.0); zaxis.Add(0.0); zaxis.Add(UnitUtil.ScaleLength(plFaceNormal.Z)); IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis); refdir.Add(UnitUtil.ScaleLength(plFaceNormal.X)); refdir.Add(0.0); refdir.Add(0.0); IFCAnyHandle refDirection = IFCInstanceExporter.CreateDirection(file, refdir); IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement3D(file, location, axis, refDirection); surface = IFCInstanceExporter.CreatePlane(file, position); } else if (face is CylindricalFace) { CylindricalFace cylFace = face as CylindricalFace; // get radius-x and radius-y and the position of the origin XYZ rad = UnitUtil.ScaleLength(cylFace.get_Radius(0)); double radius = rad.GetLength(); IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, cylFace.Origin, true); IList<double> zaxis = new List<double>(); IList<double> refdir = new List<double>(); zaxis.Add(0.0); zaxis.Add(0.0); zaxis.Add(UnitUtil.ScaleLength(cylFace.Axis.Z)); IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis); refdir.Add(UnitUtil.ScaleLength(cylFace.Axis.X)); refdir.Add(0.0); refdir.Add(0.0); IFCAnyHandle refDirection = IFCInstanceExporter.CreateDirection(file, refdir); IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement3D(file, location, axis, refDirection); surface = IFCInstanceExporter.CreateCylindricalSurface(file, position, radius); } else if (face is RevolvedFace) { RevolvedFace revFace = face as RevolvedFace; IFCAnyHandle sweptCurve; IList<double> zaxis = new List<double>(); IList<double> refdir = new List<double>(); zaxis.Add(0.0); zaxis.Add(0.0); zaxis.Add(UnitUtil.ScaleLength(revFace.Axis.Z)); IFCAnyHandle axis = IFCInstanceExporter.CreateDirection(file, zaxis); refdir.Add(UnitUtil.ScaleLength(revFace.Axis.X)); refdir.Add(0.0); refdir.Add(0.0); IFCAnyHandle location = XYZtoIfcCartesianPoint(exporterIFC, revFace.Origin, true); Curve curve = revFace.Curve; // If the base curve is an Arc if (curve is Arc) { Arc curveArc = curve as Arc; IFCAnyHandle curveLoc = XYZtoIfcCartesianPoint2D(exporterIFC, curveArc.Center, true); IList<double> direction = new List<double>(); direction.Add(UnitUtil.ScaleLength(curveArc.XDirection.X)); direction.Add(UnitUtil.ScaleLength(curveArc.YDirection.Y)); IFCAnyHandle dir = IFCInstanceExporter.CreateDirection(file, direction); IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement2D(file, curveLoc, null, dir); IFCAnyHandle circle = IFCInstanceExporter.CreateCircle(file, position, UnitUtil.ScaleLength(curveArc.Radius)); bool unbounded = false; IFCAnyHandle edgeStart = null; IFCAnyHandle edgeEnd = null; if (curve.IsBound) { edgeStart = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(0), true); edgeEnd = XYZtoIfcCartesianPoint(exporterIFC, curveArc.GetEndPoint(1), true); if (curveArc.GetEndPoint(0).IsAlmostEqualTo(curveArc.GetEndPoint(1))) unbounded = true; } else { unbounded = true; } IFCAnyHandle ifcCurve; string name = "ArcCurveBaseProfile"; if (unbounded) sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, circle); else { IFCData trim1data = IFCData.CreateIFCAnyHandle(edgeStart); HashSet<IFCData> trim1 = new HashSet<IFCData>(); trim1.Add(trim1data); IFCData trim2data = IFCData.CreateIFCAnyHandle(edgeEnd); HashSet<IFCData> trim2 = new HashSet<IFCData>(); trim2.Add(trim2data); bool senseAgreement = true; ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, circle, trim1, trim2, senseAgreement, IFCTrimmingPreference.Cartesian); sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ifcCurve); } } // If the base curve is an Ellipse else if (curve is Ellipse) { Ellipse curveEllipse = curve as Ellipse; IFCAnyHandle curveLoc = XYZtoIfcCartesianPoint2D(exporterIFC, curveEllipse.Center, true); IList<double> direction = new List<double>(); direction.Add(UnitUtil.ScaleLength(curveEllipse.XDirection.X)); direction.Add(UnitUtil.ScaleLength(curveEllipse.YDirection.Y)); IFCAnyHandle dir = IFCInstanceExporter.CreateDirection(file, direction); IFCAnyHandle position = IFCInstanceExporter.CreateAxis2Placement2D(file, curveLoc, null, dir); IFCAnyHandle ellipse = IFCInstanceExporter.CreateEllipse(file, position, UnitUtil.ScaleLength(curveEllipse.RadiusX), UnitUtil.ScaleLength(curveEllipse.RadiusY)); bool unbounded = false; IFCAnyHandle edgeStart = null; IFCAnyHandle edgeEnd = null; try { edgeStart = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(0), true); edgeEnd = XYZtoIfcCartesianPoint(exporterIFC, curveEllipse.GetEndPoint(1), true); if (curveEllipse.GetEndPoint(0).IsAlmostEqualTo(curveEllipse.GetEndPoint(1))) unbounded = true; } catch (Exception e) { if (e is Autodesk.Revit.Exceptions.ArgumentException) { unbounded = true; } else throw new ArgumentException("Edge Vertex"); } IFCAnyHandle ifcCurve; string name = "EllipseCurveBaseProfile"; if (unbounded) sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ellipse); else { IFCData trim1data = IFCData.CreateIFCAnyHandle(edgeStart); HashSet<IFCData> trim1 = new HashSet<IFCData>(); trim1.Add(trim1data); IFCData trim2data = IFCData.CreateIFCAnyHandle(edgeEnd); HashSet<IFCData> trim2 = new HashSet<IFCData>(); trim2.Add(trim2data); bool senseAgreement = true; ifcCurve = IFCInstanceExporter.CreateTrimmedCurve(file, ellipse, trim1, trim2, senseAgreement, IFCTrimmingPreference.Cartesian); sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, ifcCurve); } } // Any other type will be tessellated and is approximated using Polyline else { IList<XYZ> tessCurve = curve.Tessellate(); IList<IFCAnyHandle> polylineVertices = new List<IFCAnyHandle>(); foreach (XYZ vertex in tessCurve) { IFCAnyHandle ifcVert = XYZtoIfcCartesianPoint(exporterIFC, vertex, true); polylineVertices.Add(ifcVert); } string name = "TeseellatedBaseCurveProfile"; IFCAnyHandle polyLine = IFCInstanceExporter.CreatePolyline(file, polylineVertices); sweptCurve = IFCInstanceExporter.CreateArbitraryClosedProfileDef(file, IFCProfileType.Curve, name, polyLine); } IFCAnyHandle axisPosition = IFCInstanceExporter.CreateAxis1Placement(file, location, axis); surface = IFCInstanceExporter.CreateSurfaceOfRevolution(file, sweptCurve, null, axisPosition); } else if (face is ConicalFace) { ConicalFace conFace = face as ConicalFace; return null; // currently does not support this type of face } else if (face is RuledFace) { RuledFace ruledFace = face as RuledFace; return null; // currently does not support this type of face } else if (face is HermiteFace) { HermiteFace hermFace = face as HermiteFace; return null; // currently does not support this type of face } // create advancedFace bool sameSenseAF = true; // temp foreach (HashSet<IFCAnyHandle> theFaceBounds in boundsCollection) { IFCAnyHandle advancedFace = IFCInstanceExporter.CreateAdvancedFace(file, theFaceBounds, surface, sameSenseAF); cfsFaces.Add(advancedFace); } } // create advancedBrep IFCAnyHandle closedShell = IFCInstanceExporter.CreateClosedShell(file, cfsFaces); advancedBrep = IFCInstanceExporter.CreateAdvancedBrep(file, closedShell); } return advancedBrep; } catch { return null; } }
private static bool IsLoopValid(//double minOpeningValue, Face f, XYZ faceNormal, XYZ loopNormal, double loopArea) { return loopArea < f.Area && //loopArea < (minOpeningValue) && (loopNormal.IsAlmostEqualTo(faceNormal) || loopNormal.Negate().IsAlmostEqualTo(faceNormal)); }
/// <summary> /// Checks if two vectors are orthogonal or not. /// </summary> /// <param name="a">The one vector.</param> /// <param name="b">The other vector.</param> /// <returns>True if they are orthogonal, false if not.</returns> public static bool VectorsAreOrthogonal(XYZ a, XYZ b) { if (a == null || b == null) return false; if (a.IsAlmostEqualTo(XYZ.Zero) || b.IsAlmostEqualTo(XYZ.Zero)) return true; double ab = a.DotProduct(b); double aa = a.DotProduct(a); double bb = b.DotProduct(b); return (ab * ab < aa * AngleEps() * bb * AngleEps()) ? true : false; }