示例#1
0
        /***************************************************/

        private static void AddLoop(this BRepBuilder brep, BRepBuilderGeometryId face, XYZ normal, ICurve curve, bool external)
        {
            CurveLoop cl = new CurveLoop();

            foreach (ICurve sp in curve.ISubParts())
            {
                foreach (Curve cc in sp.IToRevitCurves())
                {
                    cl.Append(cc);
                }
            }

            if (external != cl.IsCounterclockwise(normal))
            {
                cl.Flip();
            }

            BRepBuilderGeometryId loop = brep.AddLoop(face);

            foreach (Curve cc in cl)
            {
                BRepBuilderGeometryId edge = brep.AddEdge(BRepBuilderEdgeGeometry.Create(cc));
                brep.AddCoEdge(loop, edge, false);
            }

            brep.FinishLoop(loop);
        }
        /// <summary>
        /// Determines if curve loop is counterclockwise.
        /// </summary>
        /// <param name="curveLoop">
        /// The curveLoop.
        /// </param>
        /// <param name="normal">
        /// The normal.
        /// </param>
        /// <returns>
        /// Returns true only if the loop is counterclockwise, false otherwise.
        /// </returns>
        public static bool IsIFCLoopCCW(CurveLoop curveLoop, XYZ normal)
        {
            if (curveLoop == null)
                throw new Exception("CurveLoop is null.");

            // If loop is not suitable for ccw evaluation an exception is thrown
            return curveLoop.IsCounterclockwise(normal);
        }
示例#3
0
        /// <summary>
        ///  1 过滤器筛选元素 2 通过区域锁定元素 3 使用clipper进行裁剪
        /// </summary>
        public void RegionCalcution(Document doc, CurveArray controlRegionBaseWall)
        {
            #region 获取目标region内的元素
            ElementCategoryFilter detailGroupFilter = new ElementCategoryFilter(BuiltInCategory.OST_IOSDetailGroups);
            //ElementCategoryFilter modelGroupFilter = new ElementCategoryFilter(BuiltInCategory.OST_IOSModelGroups);
            ElementCategoryFilter detailComponentsFilter = new ElementCategoryFilter(BuiltInCategory.OST_DetailComponents);
            ElementCategoryFilter linesFilter            = new ElementCategoryFilter(BuiltInCategory.OST_Lines);
            ElementCategoryFilter genericModel           = new ElementCategoryFilter(BuiltInCategory.OST_GenericModel);
            LogicalOrFilter       logicalOrFilter        = new LogicalOrFilter(new List <ElementFilter>()
            {
                detailGroupFilter, detailComponentsFilter, linesFilter, genericModel
            });

            List <Element> allTarEles = (new FilteredElementCollector(doc, doc.ActiveView.Id)).WherePasses(logicalOrFilter).WhereElementIsNotElementType().ToElements().ToList();
            List <Element> selEles    = _Methods.GetTarlElesByRegion(doc, controlRegionBaseWall, allTarEles);
            #endregion

            #region 筛选 地库_地库外墙线圈中的目标元素 障碍物 主次道路中线 处理地库_地库外墙线退距 默认800mm

            #region 基于各属性进行目标元素抓取
            CurveArray roadCurves     = new CurveArray();
            CurveArray mainRoadCurves = RegionConditionGrab(doc, selEles, out roadCurves);

            #endregion

            CurveLoop baseWallLoop = new CurveLoop();
            bool      isLoop       = _Methods.IsCurveLoop(controlRegionBaseWall, out baseWallLoop);

            CurveArrArray baseWallCurveArrArray = new CurveArrArray();
            XYZ           normal             = new XYZ(0, 0, 1);
            double        offsetDistance     = 0;
            bool          isCounterclockwise = baseWallLoop.IsCounterclockwise(normal);//curveloop内外偏移的依据
            if (isCounterclockwise)
            {
                offsetDistance = -CMD.basementWall_offset_distance;
            }
            else if (!isCounterclockwise)
            {
                offsetDistance = CMD.basementWall_offset_distance;
            }

            CurveLoop  curveLoop      = CurveLoop.CreateViaOffset(baseWallLoop, offsetDistance, normal);
            CurveArray _controlRegion = _Methods.CurveLoopToCurveArray(curveLoop);
            baseWallCurveArrArray.Append(_controlRegion);
            #endregion

            #region clipper最后图形处理 得到各个可停车区域region
            Paths basementWallPath = clipper_methods.Paths_xyzToPaths(_Methods.GetUniqueXYZFromCurves(baseWallCurveArrArray));
            Paths roadRegion       = HandleMainRoadSpace(mainRoadCurves, roadCurves, CMD.Wd_main, CMD.Wd);
            Paths canPlacedRegion  = clipper_methods.RegionCropctDifference(basementWallPath, roadRegion);//得到可停车区域
            this.parkingRegionsPoints = clipper_methods.PathsToPaths_xyz(canPlacedRegion);

            List <List <Line> > listLines = _Methods.GetListClosedtLineFromListPoints(this.parkingRegionsPoints);
            this.parkingCurveArrArray = _Methods.ListLinesToCurveArrArray(listLines);
            #endregion
        }
示例#4
0
        private CurveArray ConvertLoopToArray(CurveLoop loop)
        {
            CurveArray a = new CurveArray();

            if (loop.IsCounterclockwise(XYZ.BasisZ))
            {
                loop.Flip();
            }
            foreach (Curve c in loop)
            {
                a.Append(c);
            }

            return(a);
        }
        /// <returns>true if the curve loop is clockwise, false otherwise.</returns>
        private static bool SafeIsCurveLoopClockwise(CurveLoop curveLoop, XYZ dir)
        {
            if (curveLoop == null)
                return false;

            if (curveLoop.IsOpen())
                return false;

            if ((curveLoop.Count() == 1) && !(curveLoop.First().IsBound))
                return false;

            return !curveLoop.IsCounterclockwise(dir);
        }
示例#6
0
        /// <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);
        }