def __init__(self, shape, geom=True): self._check = BRepCheck_Analyzer(shape.object, geom) self._invalid = [] self._errors = [] if not self._check.IsValid(): self._invalid = _invalid_subshapes(shape, self._check, self._errors)
def is_valid(self): analyse = BRepCheck_Analyzer(self) ok = analyse.IsValid() if ok: return True else: return False
class CheckShape(object): """ Check shape and its sub-shapes for errors. :param afem.topology.entities.Shape shape: The shape. :param bool geom: Option to check geometry in additional to topology. """ def __init__(self, shape, geom=True): self._check = BRepCheck_Analyzer(shape.object, geom) self._invalid = [] self._errors = [] if not self._check.IsValid(): self._invalid = _invalid_subshapes(shape, self._check, self._errors) @property def is_valid(self): """ :return: *True* if the shape and all of its sub-shapes are valid, *False* if not. :rtype: bool """ return self._check.IsValid() @property def invalid_shapes(self): """ :return: List of invalid shapes. :rtype: list(afem.topology.entities.Shape) """ return self._invalid def print_errors(self): """ Print the errors. :return: None. """ for msg in self._errors: print(msg) def log_errors(self): """ Log the errors at the "info" level. :return: None. """ for msg in self._errors: logger.info(msg) def is_subshape_valid(self, shape): """ Check if a sub-shape of the original shape is valid. :param afem.topology.entities.Shape shape: The sub-shape. :return: *True* if valid, *False* if not. """ return self._check.IsValid(shape.object)
def is_valid(cls, shape): """ Check the shape for errors. :param OCCT.TopoDS.TopoDS_Shape shape: The shape. :return: *True* if valid, *False* if not. :rtype: bool """ return BRepCheck_Analyzer(shape, True).IsValid()
def limit_tolerance(shape, tol=1.0e-7, styp=Shape.SHAPE): """ Limit tolerances in a shape. :param afem.topology.entities.Shape shape: The shape. :param float tol: Target tolerance. :param OCCT.TopAbs.TopAbs_ShapeEnum styp: The level of shape to set (i.e., only vertices, only edges, only faces, or all shapes). :return: *True* if the shape is valid after limiting tolerance, *False* if not. :rtype: bool """ # Limit tolerance then fix in case of invalid tolerances _fix_tol.LimitTolerance(shape.object, tol, tol, styp) ShapeFix_Shape(shape.object).Perform() return BRepCheck_Analyzer(shape.object, False).IsValid()
def _build_solid(compound, divide_closed): """ Method to try and build a valid solid from an OpenVSP component. """ # Get all the faces in the compound. The surfaces must be split. Discard # any with zero area. top_exp = TopExp_Explorer(compound, TopAbs_FACE) faces = [] while top_exp.More(): shape = top_exp.Current() face = CheckShape.to_face(shape) fprop = GProp_GProps() BRepGProp.SurfaceProperties_(face, fprop, 1.0e-7) a = fprop.Mass() if a <= 1.0e-7: top_exp.Next() continue faces.append(face) top_exp.Next() # Replace any planar B-Spline surfaces with planes non_planar_faces = [] planar_faces = [] for f in faces: hsrf = BRep_Tool.Surface_(f) try: is_pln = GeomLib_IsPlanarSurface(hsrf, 1.0e-7) if is_pln.IsPlanar(): w = ShapeAnalysis.OuterWire_(f) # Fix the wire because they are usually degenerate edges in # the planar end caps. builder = BRepBuilderAPI_MakeWire() for e in ExploreShape.get_edges(w): if LinearProps(e).length > 1.0e-7: builder.Add(e) w = builder.Wire() fix = ShapeFix_Wire() fix.Load(w) geom_pln = Geom_Plane(is_pln.Plan()) fix.SetSurface(geom_pln) fix.FixReorder() fix.FixConnected() fix.FixEdgeCurves() fix.FixDegenerated() w = fix.WireAPIMake() # Build the planar face fnew = BRepBuilderAPI_MakeFace(w, True).Face() planar_faces.append(fnew) else: non_planar_faces.append(f) except RuntimeError: non_planar_faces.append(f) # Make a compound of the faces shape = CreateShape.compound(non_planar_faces + planar_faces) # Split closed faces if divide_closed: divide = ShapeUpgrade_ShapeDivideClosed(shape) divide.Perform() shape = divide.Result() # Sew shape sew = BRepBuilderAPI_Sewing(1.0e-7) sew.Load(shape) sew.Perform() sewn_shape = sew.SewedShape() if sewn_shape.ShapeType() == TopAbs_FACE: face = sewn_shape sewn_shape = TopoDS_Shell() builder = BRep_Builder() builder.MakeShell(sewn_shape) builder.Add(sewn_shape, face) # Attempt to unify planar domains unify_shp = ShapeUpgrade_UnifySameDomain(sewn_shape, False, True, False) unify_shp.Build() shape = unify_shp.Shape() # Make solid shell = ExploreShape.get_shells(shape)[0] solid = ShapeFix_Solid().SolidFromShell(shell) # Limit tolerance FixShape.limit_tolerance(solid) # Check shape validity check_shp = BRepCheck_Analyzer(solid, True) if check_shp.IsValid(): return solid, True, [] else: invalid_shapes = _topods_iterator_check(solid, check_shp) return solid, False, invalid_shapes