Exemplo n.º 1
0
        /// <summary>
        /// Return geometry for a particular representation item.
        /// </summary>
        /// <param name="shapeEditScope">The shape edit scope.</param>
        /// <param name="lcs">Local coordinate system for the geometry, without scale.</param>
        /// <param name="scaledLcs">Local coordinate system for the geometry, including scale, potentially non-uniform.</param>
        /// <param name="guid">The guid of an element for which represntation is being created.</param>
        /// <returns>The created geometry.</returns>
        protected override IList <GeometryObject> CreateGeometryInternal(
            IFCImportShapeEditScope shapeEditScope, Transform lcs, Transform scaledLcs, string guid)
        {
            // since IFCAdvancedBrep must contain a closed shell, we set the BuildPreferenceType to be solid for now
            for (int pass = 0; pass < 2; pass++)
            {
                using (BuilderScope bs = shapeEditScope.InitializeBuilder(IFCShapeBuilderType.BrepBuilder))
                {
                    BrepBuilderScope brepBuilderScope = bs as BrepBuilderScope;

                    BRepType brepType = (pass == 0) ? BRepType.Solid : BRepType.OpenShell;
                    brepBuilderScope.StartCollectingFaceSet(brepType);

                    Outer.AllowInvalidFace = (pass == 0);
                    Outer.CreateShape(shapeEditScope, lcs, scaledLcs, guid);

                    IList <GeometryObject> geomObjs = null;
                    geomObjs = brepBuilderScope.CreateGeometry();

                    // We'll return only if we have geometry; otherwise we'll try again with looser validation, if we can.
                    if (geomObjs != null)
                    {
                        if (pass == 1)
                        {
                            Importer.TheLog.LogError(Id, "Some faces are missing from this Solid; reading in as an Open Shell instead.", false);
                        }
                        return(geomObjs);
                    }
                }
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Identifies if the solid is watertight. Is watertight if all edges are shared by two faces.
        /// </summary>
        /// <param name="solid"></param>
        /// <param name="brepType"></param>
        /// <returns>It true, the solid is watertight and defines a closed volume.</returns>
        public static bool IsWatertight(this Solid solid, out BRepType brepType)
        {
            brepType = BRepType.OpenShell;
            var volume     = solid.Volume;
            var watertight = IsWatertight(solid);

            if (watertight || System.Math.Abs(volume) > 1e-9)
            {
                brepType = volume < 0.0 ? BRepType.Void : BRepType.Solid;
            }

            return(watertight);
        }
Exemplo n.º 3
0
        private static GeometryObject ToRevitType(Autodesk.DesignScript.Geometry.Topology topology,
                                                  bool performHostUnitConversion,
                                                  BRepType type, ElementId materialId)
        {
            var faces       = topology.Faces.ToList();
            var brb         = new BRepBuilder(type);
            var edge2EdgeId = new Dictionary <Edge, BRepBuilderGeometryId>();

            //foreach face in solid/surface
            foreach (Face protoFace in faces)
            {
                using (var geom = protoFace.SurfaceGeometry())
                {
                    using (var ngeom = geom.ToNurbsSurface())
                    {
                        bool flipped = false;
                        // Check if the nurbs surface has flipped compared to the original surface
                        if (geom.NormalAtParameter(.5, .5).Dot(ngeom.NormalAtParameter(.5, .5)) < 0)
                        {
                            flipped = true;
                        }

                        // Create Revit nurbs surface
                        var bbface = BRepBuilderSurfaceGeometry.CreateNURBSSurface(ngeom.DegreeU, ngeom.DegreeV,
                                                                                   ngeom.UKnots(), ngeom.VKnots(), ngeom.ControlPoints().SelectMany(x => x.Select(y => y.ToXyz(performHostUnitConversion))).ToList(),
                                                                                   ngeom.Weights().SelectMany(x => x).ToList(),
                                                                                   false,
                                                                                   null);

                        // Add face
                        var faceId = brb.AddFace(bbface, flipped);

                        // Set material
                        if (materialId != null)
                        {
                            brb.SetFaceMaterialId(faceId, materialId);
                        }

                        // add loops and connected edges
                        foreach (var loop in protoFace.Loops)
                        {
                            var loopId = brb.AddLoop(faceId);

                            foreach (var coedge in loop.CoEdges)
                            {
                                var edge = coedge.Edge;
                                BRepBuilderGeometryId edgeId;
                                if (edge2EdgeId.ContainsKey(edge))
                                {
                                    edgeId = edge2EdgeId[edge];
                                }
                                else
                                {
                                    var curve = edge.CurveGeometry;
                                    // Revit is already projecting edges onto the surface after checking for loop consistency
                                    // and is quite forgiving even when we use the nurbs surface instead of
                                    // the original surface.
                                    //
                                    // But there are cases when edges ends up slightly outside one of the surfaces and Revit fails.
                                    //
                                    // This is something that we can be improve going forward.
                                    edgeId            = brb.AddEdge(BRepBuilderEdgeGeometry.Create(curve.ToRevitType(performHostUnitConversion)));
                                    edge2EdgeId[edge] = edgeId;
                                }
                                brb.AddCoEdge(loopId, edgeId, coedge.Reversed);
                            }

                            brb.FinishLoop(loopId);
                        }

                        brb.FinishFace(faceId);
                    }
                }
            }

            //clean up everything
            edge2EdgeId.ToList().ForEach(x => x.Key.Dispose());
            faces.ForEach(x => x.Dispose());

            // Get result
            var outcome   = brb.Finish();
            var converted = brb.GetResult();

            return(converted);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Start collecting faces to create a BRep solid.
 /// </summary>
 /// <param name="brepType">The expected type of the geometry being built.</param>
 public void StartCollectingFaceSet(BRepType brepType)
 {
     BrepBuilder = new BRepBuilder(brepType);
     BrepBuilder.SetAllowShortEdges();
 }
Exemplo n.º 5
0
 /// <summary>
 /// Start collecting faces to create a BRep solid.
 /// </summary>
 /// <param name="brepType">The expected type of the geometry being built.</param>
 public void StartCollectingFaceSet(BRepType brepType)
 {
     BrepBuilder = new BRepBuilder(brepType);
 }