/// <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); }
/// <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); }
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); }
/// <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(); }
/// <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); }