public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; doc = uidoc.Document; sel = uidoc.Selection; Reference rf = sel.PickObject(ObjectType.Face, "Select Face"); Element ele = doc.GetElement(rf); GeometryObject geoobject = ele.GetGeometryObjectFromReference(rf); PlanarFace face = geoobject as PlanarFace; Plane plane = face.Faceby3pointPlane(); XYZ direction = face.ComputeNormal(UV.Zero); using (Transaction tran = new Transaction(doc, "Set view by face")) { tran.Start(); SketchPlane skt = SketchPlane.Create(doc, plane); View3D view3d = doc.ActiveView as View3D; view3d.OrientTo(plane.Normal); doc.ActiveView.SketchPlane = skt; uidoc.RefreshActiveView(); uidoc.ShowElements(ele.Id); tran.Commit(); } return(Result.Succeeded); }
Stream(ArrayList data, PlanarFace face) { data.Add(new Snoop.Data.ClassSeparator(typeof(PlanarFace))); data.Add(new Snoop.Data.Xyz("Origin", face.Origin)); data.Add(new Snoop.Data.Xyz("Normal", face.ComputeNormal(UV.Zero))); }
public static XYZ CheckComputeNormal(this PlanarFace planarFace, Transform transform) { XYZ p1 = planarFace.ComputeNormal(UV.Zero); XYZ p1project = transform.OfVector(p1).Normalize(); return(p1project); }
/// <summary> /// <summary> /// Determines if the Normal of the PlanarFace is flipped. /// </summary> /// <param name="planarFace">The planar face.</param> /// <returns>True if the normal is flipped.</returns> public static bool IsPlanarFaceNormalFlipped(PlanarFace planarFace) { XYZ planarFaceNormal = planarFace.Normal; XYZ faceNormal = planarFace.ComputeNormal(new UV(0, 0)); return MathUtil.VectorsAreParallel2(planarFaceNormal, faceNormal) == -1; }
private void Stream(ArrayList data, PlanarFace face) { data.Add(new Snoop.Data.ClassSeparator(typeof(PlanarFace))); data.Add(new Snoop.Data.Xyz("Origin", face.Origin)); data.Add(new Snoop.Data.Xyz("Normal", face.ComputeNormal(UV.Zero))); }
/// <summary> /// 找到Extrusion中指定法向的平面。如果有多个平面的法向都是指定的法向,则返回第一个找到的平面。 /// Given a solid, find a planar face with the given normal (version 2) /// this is a slightly enhanced version which checks if the face is on the given reference plane. /// </summary> /// <param name="refPlane">除了验证平面的法向外,还可以额外验证一下指定法向的平面是否是在指定的参考平面上。即要同时满足normal与ReferencePlane两个条件。 /// additionally, we want to check if the face is on the reference plane</param> /// <remarks></remarks> public static PlanarFace FindFace(Extrusion aSolid, XYZ normal, ReferencePlane refPlane = null) { //' get the geometry object of the given element //' Options op = new Options(); op.ComputeReferences = true; // Dim geomObjs As GeometryObjectArray = aSolid.Geometry(op).Objects //' loop through the array and find a face with the given normal //' foreach (GeometryObject geomObj in aSolid.get_Geometry(op)) { if (geomObj is Solid) //' solid is what we are interested in. { Solid pSolid = (Solid)geomObj; FaceArray faces = pSolid.Faces; foreach (Face pFace in faces) { if (pFace is PlanarFace) { PlanarFace pPlanarFace = (PlanarFace)pFace; if (!(pPlanarFace == null)) { //' check to see if they have same normal if (pPlanarFace.ComputeNormal(new UV(0, 0)).IsAlmostEqualTo(normal)) { if (refPlane == null) { return(pPlanarFace); //' we found the face. } else { //' additionally, we want to check if the face is on the reference plane //' get a point on the face. Any point will do. Edge pEdge = pPlanarFace.EdgeLoops.get_Item(0).get_Item(0); XYZ pt = pEdge.Evaluate(0.0); //' is the point on the reference plane bool res = Convert.ToBoolean(IsPointOnPlane(pt, refPlane.GetPlane())); if (res) { return(pPlanarFace); //' we found the face } } } } } } } else if (geomObj is GeometryInstance) { //' will come back later as needed. } else if (geomObj is Curve) { //' will come nack later as needed. } else if (geomObj is Mesh) { //' will come back later as needed. } else { //' what else do we have } } //' if we come here, we did not find any. return(null); }
public static bool IsVertical(PlanarFace f) { return(IsHorizontal(f.ComputeNormal(new UV(f.Origin.X, f.Origin.Y)))); }
/// <summary> /// Attempts to create a clipping, recess, or opening from a collection of faces. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="cuttingElement">The cutting element. This will help determine whether to use a clipping or opening in boundary cases.</param> /// <param name="extrusionBasePlane">The plane of the extrusion base.</param> /// <param name="extrusionDirection">The extrusion direction.</param> /// <param name="faces">The collection of faces.</param> /// <param name="range">The valid range of the extrusion.</param> /// <param name="origBodyRepHnd">The original body representation.</param> /// <returns>The new body representation. If the clipping completely clips the extrusion, this will be null. Otherwise, this /// will be the clipped representation if a clipping was done, or the original representation if not.</returns> public static IFCAnyHandle ProcessFaceCollection(ExporterIFC exporterIFC, Element cuttingElement, Plane extrusionBasePlane, XYZ extrusionDirection, ICollection <Face> faces, IFCRange range, IFCAnyHandle origBodyRepHnd) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(origBodyRepHnd)) { return(null); } bool polygonalOnly = ExporterCacheManager.ExportOptionsCache.ExportAs2x2; IList <CurveLoop> outerCurveLoops = new List <CurveLoop>(); IList <Plane> outerCurveLoopPlanes = new List <Plane>(); IList <bool> boundaryIsPolygonal = new List <bool>(); bool allPlanes = true; UV faceOriginUV = new UV(0, 0); foreach (Face face in faces) { FaceBoundaryType faceBoundaryType; CurveLoop curveLoop = GetOuterFaceBoundary(face, null, polygonalOnly, out faceBoundaryType); outerCurveLoops.Add(curveLoop); boundaryIsPolygonal.Add(faceBoundaryType == FaceBoundaryType.Polygonal); if (face is PlanarFace) { PlanarFace planarFace = face as PlanarFace; XYZ faceOrigin = planarFace.Origin; XYZ faceNormal = planarFace.ComputeNormal(faceOriginUV); Plane plane = new Plane(faceNormal, faceOrigin); outerCurveLoopPlanes.Add(plane); if (!curveLoop.IsCounterclockwise(faceNormal)) { curveLoop.Flip(); } } else { outerCurveLoopPlanes.Add(null); allPlanes = false; } } if (allPlanes) { int numFaces = faces.Count; // Special case: one face is a clip plane. if (numFaces == 1) { return(ProcessClippingFace(exporterIFC, outerCurveLoops[0], outerCurveLoopPlanes[0], extrusionBasePlane, extrusionDirection, range, false, origBodyRepHnd)); } KeyValuePair <bool, bool> clipsExtrusionEnds = CollectionClipsExtrusionEnds(outerCurveLoops, extrusionDirection, range); if (clipsExtrusionEnds.Key == true || clipsExtrusionEnds.Value == true) { // Don't clip for a door, window or opening. if (CreateOpeningForCategory(cuttingElement)) { throw new Exception("Unhandled opening."); } ICollection <int> facesToSkip = new HashSet <int>(); bool clipStart = (clipsExtrusionEnds.Key == true); bool clipBoth = (clipsExtrusionEnds.Key == true && clipsExtrusionEnds.Value == true); if (!clipBoth) { for (int ii = 0; ii < numFaces; ii++) { double slant = outerCurveLoopPlanes[ii].Normal.DotProduct(extrusionDirection); if (!MathUtil.IsAlmostZero(slant)) { if (clipStart && (slant > 0.0)) { throw new Exception("Unhandled clip plane direction."); } if (!clipStart && (slant < 0.0)) { throw new Exception("Unhandled clip plane direction."); } } else { facesToSkip.Add(ii); } } } else { // If we are clipping both the start and end of the extrusion, we have to make sure all of the clipping // planes have the same a non-negative dot product relative to one another. int clipOrientation = 0; for (int ii = 0; ii < numFaces; ii++) { double slant = outerCurveLoopPlanes[ii].Normal.DotProduct(extrusionDirection); if (!MathUtil.IsAlmostZero(slant)) { if (slant > 0.0) { if (clipOrientation < 0) { throw new Exception("Unhandled clipping orientations."); } clipOrientation = 1; } else { if (clipOrientation > 0) { throw new Exception("Unhandled clipping orientations."); } clipOrientation = -1; } } else { facesToSkip.Add(ii); } } } IFCAnyHandle newBodyRepHnd = origBodyRepHnd; for (int ii = 0; ii < numFaces; ii++) { if (facesToSkip.Contains(ii)) { continue; } newBodyRepHnd = ProcessClippingFace(exporterIFC, outerCurveLoops[ii], outerCurveLoopPlanes[ii], extrusionBasePlane, extrusionDirection, range, true, newBodyRepHnd); if (newBodyRepHnd == null) { return(null); } } return(newBodyRepHnd); } } bool unhandledCases = true; if (unhandledCases) { throw new Exception("Unhandled opening or clipping."); } // We will attempt to "sew" the faces, and see what we have left over. Depending on what we have, we have an opening, recess, or clipping. IList <Edge> boundaryEdges = new List <Edge>(); foreach (Face face in faces) { EdgeArrayArray faceBoundaries = face.EdgeLoops; // We only know how to deal with the outer loop; we'll throw if we have multiple boundaries. if (faceBoundaries.Size != 1) { throw new Exception("Can't process faces with inner boundaries."); } EdgeArray faceBoundary = faceBoundaries.get_Item(0); foreach (Edge edge in faceBoundary) { if (edge.get_Face(0) == null || edge.get_Face(1) == null) { boundaryEdges.Add(edge); } } } return(origBodyRepHnd); }