def brep_feat_local_revolution(event=None):
    S = BRepPrimAPI_MakeBox(400., 250., 300.).Shape()
    faces = list(TopologyExplorer(S).faces())
    F1 = faces[2]
    surf = BRep_Tool_Surface(F1)

    D = gp_OX()

    MW1 = BRepBuilderAPI_MakeWire()
    p1 = gp_Pnt2d(100., 100.)
    p2 = gp_Pnt2d(200., 100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW1.Add(BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2)).Edge())

    p1 = gp_Pnt2d(200., 100.)
    p2 = gp_Pnt2d(150., 200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW1.Add(BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2)).Edge())

    p1 = gp_Pnt2d(150., 200.)
    p2 = gp_Pnt2d(100., 100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW1.Add(BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2)).Edge())

    MKF1 = BRepBuilderAPI_MakeFace()
    MKF1.Init(surf, False, 1e-6)
    MKF1.Add(MW1.Wire())
    FP = MKF1.Face()
    breplib_BuildCurves3d(FP)
    MKrev = BRepFeat_MakeRevol(S, FP, F1, D, 1, True)
    F2 = faces[4]
    MKrev.Perform(F2)
    display.EraseAll()
    display.DisplayShape(MKrev.Shape())
    display.FitAll()
def extrusion(event=None):
    # Make a box
    Box = BRepPrimAPI_MakeBox(400., 250., 300.)
    S = Box.Shape()

    # Choose the first Face of the box
    F = next(TopologyExplorer(S).faces())
    surf = BRep_Tool_Surface(F)

    #  Make a plane from this face
    Pln = Geom_Plane.DownCast(surf)

    # Get the normal of this plane. This will be the direction of extrusion.
    D = Pln.Axis().Direction()

    # Inverse normal
    D.Reverse()

    # Create the 2D planar sketch
    MW = BRepBuilderAPI_MakeWire()
    p1 = gp_Pnt2d(200., -100.)
    p2 = gp_Pnt2d(100., -100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    Edge1 = BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2))
    MW.Add(Edge1.Edge())
    p1 = p2
    p2 = gp_Pnt2d(100., -200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    Edge2 = BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2))
    MW.Add(Edge2.Edge())
    p1 = p2
    p2 = gp_Pnt2d(200., -200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    Edge3 = BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2))
    MW.Add(Edge3.Edge())
    p1 = p2
    p2 = gp_Pnt2d(200., -100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    Edge4 = BRepBuilderAPI_MakeEdge(aline, surf, 0., p1.Distance(p2))
    MW.Add(Edge4.Edge())

    #  Build Face from Wire. NB: a face is required to generate a solid.
    MKF = BRepBuilderAPI_MakeFace()
    MKF.Init(surf, False, 1e-6)
    MKF.Add(MW.Wire())
    FP = MKF.Face()
    breplib_BuildCurves3d(FP)

    MKP = BRepFeat_MakePrism(S, FP, F, D, False, True)
    MKP.Perform(200.)
    # TODO MKP completes, seeing a split operation but no extrusion
    assert MKP.IsDone()
    res1 = MKP.Shape()

    display.EraseAll()
    display.DisplayColoredShape(res1, 'BLUE')
    display.FitAll()
Exemple #3
0
    def create_shape(self):
        d = self.declaration
        pln = gp_Pln(d.position.proxy, d.direction.proxy)

        curve = self.curve = Geom_Plane(pln)
        if d.bounds:
            u, v = d.bounds
            face = BRepBuilderAPI_MakeFace(pln, u.x, v.x, u.y, v.y)
        else:
            face = BRepBuilderAPI_MakeFace(pln)

        self.shape = face.Face()
Exemple #4
0
def heightmap_from_image(event=None):
    """ takes the heightmap from a jpeg file
    and apply a texture
    this example requires numpy/matplotlib
    """
    print("opening image")
    heightmap = Image.open('images/mountain_heightmap.jpg')
    heightmap.show()
    width = heightmap.size[0]
    height = heightmap.size[1]
    # create the gp_Pnt array
    print("parse image and fill in point array")
    for i in range(1, width):
        for j in range(1, height):
            # all 3 RGB values are equal, just take the first one
            # vertex 1
            height_value = heightmap.getpixel((i - 1, j - 1))[0]
            v1 = gp_Pnt(i, j, float(height_value) / 10)
            # vertex 2
            height_value = heightmap.getpixel((i, j - 1))[0]
            v2 = gp_Pnt(i + 1, j, float(height_value) / 10)
            # vertex 3
            height_value = heightmap.getpixel((i, j))[0]
            v3 = gp_Pnt(i + 1, j + 1, float(height_value) / 10)
            # vertex 4
            height_value = heightmap.getpixel((i - 1, j))[0]
            v4 = gp_Pnt(i, j + 1, float(height_value) / 10)
            # boundaries
            b1 = boundary_curve_from_2_points(v1, v2)
            b2 = boundary_curve_from_2_points(v2, v3)
            b3 = boundary_curve_from_2_points(v3, v4)
            b4 = boundary_curve_from_2_points(v4, v1)
            #
            bConstrainedFilling = GeomFill_ConstrainedFilling(8, 2)
            bConstrainedFilling.Init(b1, b2, b3, b4, False)
            srf1 = bConstrainedFilling.Surface()
            # make a face from this srf
            patch = BRepBuilderAPI_MakeFace()
            bounds = True
            toldegen = 1e-6
            patch.Init(srf1, bounds, toldegen)
            patch.Build()
            display.DisplayShape(patch.Face())
            # then create faces
        print("%s%%" % int(float(i) / width * 100))
        #display.process_events()
    display.FitAll()
    # finally display image
    heightmap.show()
Exemple #5
0
def add_wire_to_face(face, wire, reverse=False):
    '''
    apply a wire to a face
    use reverse to set the orientation of the wire to opposite
    @param face:
    @param wire:
    @param reverse:
    '''
    face = BRepBuilderAPI_MakeFace(face)
    if reverse:
        wire.Reverse()
    face.Add(wire)
    result = face.Face()
    face.Delete()
    return result
def split_edge_with_face(event=None):
    display.EraseAll()
    p0 = gp_Pnt()
    vnorm = gp_Dir(1, 0, 0)
    pln = gp_Pln(p0, vnorm)
    face = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10).Face()
    p1 = gp_Pnt(0, 0, 15)
    p2 = gp_Pnt(0, 0, -15)
    edge = BRepBuilderAPI_MakeEdge(p1, p2).Edge()
    # Initialize splitter
    splitter = BOPAlgo_Splitter()
    # Add the edge as an argument and the face as a tool. This will split
    # the edge with the face.
    splitter.AddArgument(edge)
    splitter.AddTool(face)
    splitter.Perform()

    edges = []
    exp = TopExp_Explorer(splitter.Shape(), TopAbs_EDGE)
    while exp.More():
        edges.append(exp.Current())
        exp.Next()
    print('Number of edges in split shape: ', len(edges))
    display.DisplayShape(edges[0], color='red')
    display.DisplayShape(edges[1], color='green')
    display.DisplayShape(edges[2], color='yellow')
    display.FitAll()
Exemple #7
0
    def display_geom(self,
                     geom,
                     rgb=None,
                     transparency=None,
                     material=Graphic3d_NOM_DEFAULT):
        """
        Display a geometric entity.

        :param geom: The geometry.
        :type geom: OCCT.gp.gp_Pnt or OCCT.Geom.Geom_Curve or
            OCCT.Geom.Geom_Surface
        :param rgb: The RGB color (r, g, b).
        :type rgb: collections.Sequence[float] or OCCT.Quantity.Quantity_Color
        :param float transparency: The transparency (0 to 1).
        :param OCCT.Graphic3d.Graphic3d_NameOfMaterial material: The material.

        :return: The AIS_Shape created for the geometry. Returns *None* if the
            entity cannot be converted to a shape.
        :rtype: OCCT.AIS.AIS_Shape or None
        """
        if isinstance(geom, gp_Pnt):
            shape = BRepBuilderAPI_MakeVertex(geom).Vertex()
        elif isinstance(geom, Geom_Curve):
            shape = BRepBuilderAPI_MakeEdge(geom).Edge()
        elif isinstance(geom, Geom_Surface):
            shape = BRepBuilderAPI_MakeFace(geom, 1.0e-7).Face()
        else:
            return None

        return self.display_shape(shape, rgb, transparency, material)
Exemple #8
0
    def display_geom(self,
                     geom,
                     color=None,
                     transparency=None,
                     material=None,
                     update=True):
        """ Display a geometric entity.

        Parameters
        ----------
        geom: OCCT.gp.gp_Pnt or OCCT.Geom.Geom_Curve or OCCT.Geom.Geom_Surface
            The shape to display
        color: enaml.color.Color
            An enaml color
        transparency: float
            The transparency (0 to 1).
        material: OCCT.Graphic3d.Graphic3d_NameOfMaterial
            The material.

        Returns
        -------
        result: AIS_Shape or None
            The AIS_Shape created for the geometry. Returns *None* if the
            entity cannot be converted to a shape.
        """
        if isinstance(geom, gp_Pnt):
            shape = BRepBuilderAPI_MakeVertex(geom).Vertex()
        elif isinstance(geom, Geom_Curve):
            shape = BRepBuilderAPI_MakeEdge(geom).Edge()
        elif isinstance(geom, Geom_Surface):
            shape = BRepBuilderAPI_MakeFace(geom, 1.0e-7).Face()
        else:
            return None

        return self.display_shape(shape, color, transparency, material, update)
def get_faceted_L_shape(x, y, z):
    pnt_A = gp_Pnt(x + 0, y + 0, z + 0)
    pnt_B = gp_Pnt(x +20, y + 0, z + 0)
    pnt_C = gp_Pnt(x +20, y +10, z + 0)
    pnt_D = gp_Pnt(x + 0, y +10, z + 0)
    pnt_E = gp_Pnt(x + 0, y + 0, z +20)
    pnt_F = gp_Pnt(x +10, y + 0, z +20)
    pnt_G = gp_Pnt(x +10, y +10, z +20)
    pnt_H = gp_Pnt(x +0, y +10, z +20)
    pnt_I = gp_Pnt(x +10, y + 0, z +10)
    pnt_J = gp_Pnt(x +10, y +10, z +10)
    pnt_K = gp_Pnt(x +20, y + 0, z +10)
    pnt_L = gp_Pnt(x +20, y +10, z +10)

    face_1 = make_face_from_4_points(pnt_A, pnt_B, pnt_C, pnt_D)
    face_2 = make_face_from_4_points(pnt_B, pnt_C, pnt_L, pnt_K)
    face_3 = make_face_from_4_points(pnt_E, pnt_F, pnt_G, pnt_H)
    face_4 = make_face_from_4_points(pnt_A, pnt_E, pnt_H, pnt_D)
    face_5 = make_face_from_4_points(pnt_G, pnt_F, pnt_I, pnt_J)
    face_6 = make_face_from_4_points(pnt_I, pnt_K, pnt_L, pnt_J)

    polygon_1 = BRepBuilderAPI_MakePolygon()
    polygon_1.Add(pnt_A)
    polygon_1.Add(pnt_B)
    polygon_1.Add(pnt_K)
    polygon_1.Add(pnt_I)
    polygon_1.Add(pnt_F)
    polygon_1.Add(pnt_E)
    polygon_1.Close()

    face_7 = BRepBuilderAPI_MakeFace(polygon_1.Wire()).Face()
    polygon_2 = BRepBuilderAPI_MakePolygon()
    polygon_2.Add(pnt_D)
    polygon_2.Add(pnt_H)
    polygon_2.Add(pnt_G)
    polygon_2.Add(pnt_J)
    polygon_2.Add(pnt_L)
    polygon_2.Add(pnt_C)
    polygon_2.Close()
    face_8 = BRepBuilderAPI_MakeFace(polygon_2.Wire()).Face()

    sew = BRepBuilderAPI_Sewing()
    for face in [face_1, face_2, face_3, face_4, face_5, face_6, face_7, face_8]:
        sew.Add(face)
    sew.Perform()

    return sew.SewedShape()
Exemple #10
0
    def make_shape(self):
        # 1 - retrieve the data from the UIUC airfoil data page
        foil_dat_url = 'http://m-selig.ae.illinois.edu/ads/coord_seligFmt/%s.dat' % self.profile
        print("Connecting to m-selig, retrieving foil data")
        f = urllib2.urlopen(foil_dat_url)
        print("Building foil geometry")
        plan = gp_Pln(gp_Pnt(0., 0., 0.), gp_Dir(0., 0.,
                                                 1.))  # Z=0 plan / XY plan
        section_pts_2d = []

        for line in f.readlines()[1:]:  # The first line contains info only
            # 2 - do some cleanup on the data (mostly dealing with spaces)
            data = line.split()
            # 3 - create an array of points
            if len(data) == 2:  # two coordinates for each point
                section_pts_2d.append(
                    gp_Pnt2d(
                        float(data[0]) * self.chord,
                        float(data[1]) * self.chord))

        # 4 - use the array to create a spline describing the airfoil section
        spline_2d = Geom2dAPI_PointsToBSpline(
            point2d_list_to_TColgp_Array1OfPnt2d(section_pts_2d),
            len(section_pts_2d) - 1,  # order min
            len(section_pts_2d))  # order max
        spline = geomapi.To3d(spline_2d.Curve(), plan)

        # 5 - figure out if the trailing edge has a thickness or not,
        # and create a Face
        try:
            # first and last point of spline -> trailing edge
            trailing_edge = make_edge(
                gp_Pnt(section_pts_2d[0].X(), section_pts_2d[0].Y(), 0.0),
                gp_Pnt(section_pts_2d[-1].X(), section_pts_2d[-1].Y(), 0.0))
            face = BRepBuilderAPI_MakeFace(
                make_wire([make_edge(spline), trailing_edge]))
        except AssertionError:
            # the trailing edge segment could not be created, probably because
            # the points are too close
            # No need to build a trailing edge
            face = BRepBuilderAPI_MakeFace(make_wire(make_edge(spline)))

        # 6 - extrude the Face to create a Solid
        return BRepPrimAPI_MakePrism(
            face.Face(), gp_Vec(gp_Pnt(0., 0., 0.),
                                gp_Pnt(0., 0., self.span))).Shape()
Exemple #11
0
    def update_shape(self, change=None):
        d = self.declaration
        if d.wires:
            shapes = d.wires
        else:
            shapes = [c for c in self.children() if isinstance(c, OccShape)]
        if not shapes:
            raise ValueError(
                "No wires or children available to create a face!")

        convert = self.shape_to_face
        for i, s in enumerate(shapes):
            if i == 0:
                shape = BRepBuilderAPI_MakeFace(convert(s))
            else:
                shape.Add(convert(s))
        self.shape = shape.Face()
Exemple #12
0
 def __init__(self, pln, width, height, depth):
     w = width / 2.
     h = height / 2.
     gp_pln = pln.gp_pln
     topods_face = BRepBuilderAPI_MakeFace(gp_pln, -w, w, -h, h).Face()
     vn = pln.norm(0., 0.)
     vn.Normalize()
     vn.Scale(depth)
     self._solid = Solid(BRepPrimAPI_MakePrism(topods_face, vn).Shape())
Exemple #13
0
    def by_surface(surface):
        """
        Create a face by a surface.

        :param afem.geometry.entities.Surface surface: The surface.

        :return: The face.
        :rtype: afem.topology.entities.Face
        """
        return Face(BRepBuilderAPI_MakeFace(surface.object, 1.0e-7).Face())
Exemple #14
0
    def by_wire(wire):
        """
        Create a face by a planar wire.

        :param afem.topology.entities.Wire  wire: The wire.

        :return: The new face.
        :rtype: afem.topology.entities.Face
        """
        return Face(BRepBuilderAPI_MakeFace(wire.object, True).Face())
Exemple #15
0
 def update_shape(self, change=None):
     d = self.declaration
     if d.surface:
         surface = d.surface
     else:
         child = self.get_first_child()
         if child:
             surface = child.shape
         else:
             pln = gp_Pln(d.position.proxy, d.direction.proxy)
             surface = BRepBuilderAPI_MakeFace(pln).Face()
     half_space = BRepPrimAPI_MakeHalfSpace(surface, d.side.proxy)
     # Shape doesnt work see https://tracker.dev.opencascade.org/view.php?id=29969
     self.shape = half_space.Solid()
def vectorized_slicer(li):
    # Create Plane defined by a point and the perpendicular direction
    z_values, shape = li
    _slices = []
    for z in z_values:
        #print 'slicing index:', z, 'sliced by process:', os.getpid()
        plane = gp_Pln(gp_Pnt(0., 0., z), gp_Dir(0., 0., 1.))
        face = BRepBuilderAPI_MakeFace(plane).Shape()
        # Computes Shape/Plane intersection
        section = BRepAlgoAPI_Section(shape, face)
        section.Build()
        if section.IsDone():
            _slices.append(section.Shape())
    return _slices
def split_face_with_edge(event=None):
    display.EraseAll()
    p0 = gp_Pnt()
    vnorm = gp_Dir(1, 0, 0)
    pln = gp_Pln(p0, vnorm)
    face = BRepBuilderAPI_MakeFace(pln, -10, 10, -10, 10).Face()
    p1 = gp_Pnt(0, 0, 15)
    p2 = gp_Pnt(0, 0, -15)
    edge = BRepBuilderAPI_MakeEdge(p1, p2).Edge()
    # Initialize splitter
    splitter = BOPAlgo_Splitter()
    # Add the face as an argument and the edge as a tool. This will split
    # the face with the edge.
    splitter.AddArgument(face)
    splitter.AddTool(edge)
    splitter.Perform()
    display.DisplayShape(splitter.Shape())
    display.FitAll()
def revolved_cut(base):
    # Define 7 points
    face_points = TColgp_Array1OfPnt(1, 7)
    face_inner_radius = 0.6

    pts = [
        gp_Pnt(face_inner_radius - 0.05, 0.0, -0.05),
        gp_Pnt(face_inner_radius - 0.10, 0.0, -0.025),
        gp_Pnt(face_inner_radius - 0.10, 0.0, 0.025),
        gp_Pnt(face_inner_radius + 0.10, 0.0, 0.025),
        gp_Pnt(face_inner_radius + 0.10, 0.0, -0.025),
        gp_Pnt(face_inner_radius + 0.05, 0.0, -0.05),
        gp_Pnt(face_inner_radius - 0.05, 0.0, -0.05),
    ]

    for n, i in enumerate(pts):
        face_points.SetValue(n + 1, i)

    # Use these points to create edges and add these edges to a wire
    hexwire = BRepBuilderAPI_MakeWire()

    for i in range(1, 7):
        hexedge = BRepBuilderAPI_MakeEdge(face_points.Value(i),
                                          face_points.Value(i + 1)).Edge()
        hexwire.Add(hexedge)

    # Turn the wire into a 6 sided face
    hexface = BRepBuilderAPI_MakeFace(hexwire.Wire()).Face()

    # Revolve the face around an axis
    revolve_axis = gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1))
    revolved_shape = BRepPrimAPI_MakeRevol(hexface, revolve_axis).Shape()

    # Move the generated shape
    move = gp_Trsf()
    move.SetTranslation(gp_Pnt(0, 0, 0), gp_Pnt(0, 0, sin(0.5)))
    moved_shape = BRepBuilderAPI_Transform(revolved_shape, move, False).Shape()

    # Remove the revolved shape
    cut = BRepAlgoAPI_Cut(base, moved_shape).Shape()
    return cut
def brep_feat_rib(event=None):
    mkw = BRepBuilderAPI_MakeWire()

    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(0., 0., 0.), gp_Pnt(200., 0.,
                                                           0.)).Edge())
    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(200., 0., 0.), gp_Pnt(200., 0.,
                                                             50.)).Edge())
    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(200., 0., 50.), gp_Pnt(50., 0.,
                                                              50.)).Edge())
    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(50., 0., 50.), gp_Pnt(50., 0.,
                                                             200.)).Edge())
    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(50., 0., 200.), gp_Pnt(0., 0.,
                                                              200.)).Edge())
    mkw.Add(
        BRepBuilderAPI_MakeEdge(gp_Pnt(0., 0., 200.), gp_Pnt(0., 0.,
                                                             0.)).Edge())

    S = BRepPrimAPI_MakePrism(
        BRepBuilderAPI_MakeFace(mkw.Wire()).Face(),
        gp_Vec(gp_Pnt(0., 0., 0.), gp_Pnt(0., 100., 0.)))
    display.EraseAll()
    #    display.DisplayShape(S.Shape())

    W = BRepBuilderAPI_MakeWire(
        BRepBuilderAPI_MakeEdge(gp_Pnt(50., 45., 100.), gp_Pnt(100., 45.,
                                                               50.)).Edge())

    aplane = Geom_Plane(0., 1., 0., -45.)

    aform = BRepFeat_MakeLinearForm(S.Shape(), W.Wire(), aplane,
                                    gp_Vec(0., 10., 0.), gp_Vec(0., 0., 0.), 1,
                                    True)
    aform.Perform()
    display.DisplayShape(aform.Shape())
    display.FitAll()
Exemple #20
0
def revolved_shape():
    """ demonstrate how to create a revolved shape from an edge

    adapted from algotopia.com's opencascade_basic tutorial:
    http://www.algotopia.com/contents/opencascade/opencascade_basic

    """
    face_inner_radius = 0.6
    # point to create an edge from
    edg_points = [
        gp_Pnt(face_inner_radius - 0.05, 0.0, -0.05),
        gp_Pnt(face_inner_radius - 0.10, 0.0, -0.025),
        gp_Pnt(face_inner_radius - 0.10, 0.0, 0.025),
        gp_Pnt(face_inner_radius + 0.10, 0.0, 0.025),
        gp_Pnt(face_inner_radius + 0.10, 0.0, -0.025),
        gp_Pnt(face_inner_radius + 0.05, 0.0, -0.05),
        gp_Pnt(face_inner_radius - 0.05, 0.0, -0.05),
    ]

    # aggregate edges in wire
    hexwire = BRepBuilderAPI_MakeWire()

    for i in range(6):
        hexedge = BRepBuilderAPI_MakeEdge(edg_points[i],
                                          edg_points[i + 1]).Edge()
        hexwire.Add(hexedge)

    hexwire_wire = hexwire.Wire()
    # face from wire
    hexface = BRepBuilderAPI_MakeFace(hexwire_wire).Face()
    revolve_axis = gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1))
    # create revolved shape
    revolved_shape_ = BRepPrimAPI_MakeRevol(hexface, revolve_axis,
                                            math.radians(90.)).Shape()

    # render wire & revolved shape
    display.DisplayShape([revolved_shape_, hexwire_wire])
    display.FitAll()
    start_display()
Exemple #21
0
def build_points_network(bspl_srf):
    """ Creates a list of gp_Pnt points from a bspline surface
    """
    # first create a face
    face = BRepBuilderAPI_MakeFace(bspl_srf, 1e-6).Face()
    # get face uv bounds
    umin, umax, vmin, vmax = shapeanalysis_GetFaceUVBounds(face)
    print(umin, umax, vmin, vmax)

    pnts = []
    sas = ShapeAnalysis_Surface(bspl_srf)

    u = umin
    while u < umax:
        v = vmin
        while v < vmax:
            p = sas.Value(u, v)
            print("u=", u, " v=", v, "->X=", p.X(), " Y=", p.Y(), " Z=", p.Z())
            pnts.append(p)
            v += 0.1
        u += 0.1
    return pnts
def brepfeat_prism(event=None):
    box = BRepPrimAPI_MakeBox(400, 250, 300).Shape()
    faces = TopologyExplorer(box).faces()

    for i in range(5):
        face = next(faces)

    srf = BRep_Tool_Surface(face)

    c = gp_Circ2d(gp_Ax2d(gp_Pnt2d(200, 130), gp_Dir2d(1, 0)), 75)

    circle = Geom2d_Circle(c)

    wire = BRepBuilderAPI_MakeWire()
    wire.Add(BRepBuilderAPI_MakeEdge(circle, srf, 0., pi).Edge())
    wire.Add(BRepBuilderAPI_MakeEdge(circle, srf, pi, 2. * pi).Edge())
    wire.Build()

    display.DisplayShape(wire.Wire())

    mkf = BRepBuilderAPI_MakeFace()
    mkf.Init(srf, False, 1e-6)
    mkf.Add(wire.Wire())
    mkf.Build()

    new_face = mkf.Face()
    breplib_BuildCurves3d(new_face)

    display.DisplayShape(new_face)

    prism = BRepFeat_MakeDPrism(box, mkf.Face(), face, 100, True, True)

    prism.Perform(400)
    assert prism.IsDone()
    display.EraseAll()
    display.DisplayShape(prism.Shape())
    display.DisplayColoredShape(wire.Wire(), 'RED')
    display.FitAll()
def round_tooth(wedge):
    round_x = 2.6
    round_z = 0.06 * pitch
    round_radius = pitch

    # Determine where the circle used for rounding has to start and stop
    p2d_1 = gp_Pnt2d(top_radius - round_x, 0)
    p2d_2 = gp_Pnt2d(top_radius, round_z)

    # Construct the rounding circle
    round_circle = GccAna_Circ2d2TanRad(p2d_1, p2d_2, round_radius, 0.01)
    if (round_circle.NbSolutions() != 2):
        sys.exit(-2)

    round_circle_2d_1 = round_circle.ThisSolution(1)
    round_circle_2d_2 = round_circle.ThisSolution(2)

    if (round_circle_2d_1.Position().Location().Coord()[1] >= 0):
        round_circle_2d = round_circle_2d_1
    else:
        round_circle_2d = round_circle_2d_2

    # Remove the arc used for rounding
    trimmed_circle = GCE2d_MakeArcOfCircle(round_circle_2d, p2d_1, p2d_2).Value()

    # Calculate extra points used to construct lines
    p1 = gp_Pnt(p2d_1.X(), 0, p2d_1.Y())
    p2 = gp_Pnt(p2d_2.X(), 0, p2d_2.Y())
    p3 = gp_Pnt(p2d_2.X() + 1, 0, p2d_2.Y())
    p4 = gp_Pnt(p2d_2.X() + 1, 0, p2d_1.Y() - 1)
    p5 = gp_Pnt(p2d_1.X(), 0, p2d_1.Y() - 1)

    # Convert the arc and four extra lines into 3D edges
    plane = gp_Pln(gp_Ax3(gp_Origin(), gp_DY().Reversed(), gp_DX()))
    arc1 = BRepBuilderAPI_MakeEdge(geomapi_To3d(trimmed_circle, plane)).Edge()
    lin1 = BRepBuilderAPI_MakeEdge(p2, p3).Edge()
    lin2 = BRepBuilderAPI_MakeEdge(p3, p4).Edge()
    lin3 = BRepBuilderAPI_MakeEdge(p4, p5).Edge()
    lin4 = BRepBuilderAPI_MakeEdge(p5, p1).Edge()

    # Make a wire composed of the edges
    round_wire = BRepBuilderAPI_MakeWire(arc1)
    round_wire.Add(lin1)
    round_wire.Add(lin2)
    round_wire.Add(lin3)
    round_wire.Add(lin4)

    # Turn the wire into a face
    round_face = BRepBuilderAPI_MakeFace(round_wire.Wire()).Shape()

    # Revolve the face around the Z axis over the tooth angle
    rounding_cut_1 = BRepPrimAPI_MakeRevol(round_face, gp_OZ(), tooth_angle).Shape()

    # Construct a mirrored copy of the first cutting shape
    mirror = gp_Trsf()
    mirror.SetMirror(gp_XOY())
    mirrored_cut_1 = BRepBuilderAPI_Transform(rounding_cut_1, mirror, True).Shape()

    # and translate it so that it ends up on the other side of the wedge
    translate = gp_Trsf()
    translate.SetTranslation(gp_Vec(0, 0, thickness))
    rounding_cut_2 = BRepBuilderAPI_Transform(mirrored_cut_1, translate, False).Shape()

    # Cut the wedge using the first and second cutting shape
    cut_1 = BRepAlgoAPI_Cut(wedge, rounding_cut_1).Shape()
    cut_2 = BRepAlgoAPI_Cut(cut_1, rounding_cut_2).Shape()

    return cut_2
# create edges
e0 = BRepBuilderAPI_MakeEdge(v1, v4).Edge()
e1 = BRepBuilderAPI_MakeEdge(v4, v2).Edge()
e2 = BRepBuilderAPI_MakeEdge(v4, v3).Edge()
e3 = BRepBuilderAPI_MakeEdge(v2, v1).Edge()
e4 = BRepBuilderAPI_MakeEdge(v3, v2).Edge()
e5 = BRepBuilderAPI_MakeEdge(v3, v1).Edge()

# create wires
w0 = BRepBuilderAPI_MakeWire(e5, e3, e4).Wire()
w1 = BRepBuilderAPI_MakeWire(e1, e3, e0).Wire()
w2 = BRepBuilderAPI_MakeWire(e0, e5, e2).Wire()
w3 = BRepBuilderAPI_MakeWire(e2, e4, e1).Wire()

# then create faces
f0 = BRepBuilderAPI_MakeFace(w0).Face()
f1 = BRepBuilderAPI_MakeFace(w1).Face()
f2 = BRepBuilderAPI_MakeFace(w2).Face()
f3 = BRepBuilderAPI_MakeFace(w3).Face()

# sew the faces together to create a shell
sew = BRepBuilderAPI_Sewing()
sew.Add(f0)
sew.Add(f1)
sew.Add(f2)
sew.Add(f3)
sew.Perform()
tetrahedron_shell = sew.SewedShape()

# display the result
display, start_display, add_menu, add_function_to_menu = init_display()
def brep_feat_extrusion_protrusion(event=None):
    # Extrusion
    S = BRepPrimAPI_MakeBox(400., 250., 300.).Shape()
    faces = TopologyExplorer(S).faces()
    F = next(faces)
    surf1 = BRep_Tool_Surface(F)

    Pl1 = Geom_Plane.DownCast(surf1)

    D1 = Pl1.Pln().Axis().Direction().Reversed()
    MW = BRepBuilderAPI_MakeWire()
    p1, p2 = gp_Pnt2d(200., -100.), gp_Pnt2d(100., -100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW.Add(BRepBuilderAPI_MakeEdge(aline, surf1, 0., p1.Distance(p2)).Edge())

    p1, p2 = gp_Pnt2d(100., -100.), gp_Pnt2d(100., -200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW.Add(BRepBuilderAPI_MakeEdge(aline, surf1, 0., p1.Distance(p2)).Edge())

    p1, p2 = gp_Pnt2d(100., -200.), gp_Pnt2d(200., -200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW.Add(BRepBuilderAPI_MakeEdge(aline, surf1, 0., p1.Distance(p2)).Edge())

    p1, p2 = gp_Pnt2d(200., -200.), gp_Pnt2d(200., -100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW.Add(BRepBuilderAPI_MakeEdge(aline, surf1, 0., p1.Distance(p2)).Edge())

    MKF = BRepBuilderAPI_MakeFace()
    MKF.Init(surf1, False, 1e-6)
    MKF.Add(MW.Wire())
    FP = MKF.Face()
    breplib_BuildCurves3d(FP)

    display.EraseAll()
    MKP = BRepFeat_MakePrism(S, FP, F, D1, 0, True)
    MKP.PerformThruAll()

    res1 = MKP.Shape()
    display.DisplayShape(res1)

    # Protrusion
    next(faces)
    F2 = next(faces)
    surf2 = BRep_Tool_Surface(F2)
    Pl2 = Geom_Plane.DownCast(surf2)
    D2 = Pl2.Pln().Axis().Direction().Reversed()
    MW2 = BRepBuilderAPI_MakeWire()
    p1, p2 = gp_Pnt2d(100., 100.), gp_Pnt2d(200., 100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW2.Add(BRepBuilderAPI_MakeEdge(aline, surf2, 0., p1.Distance(p2)).Edge())

    p1, p2 = gp_Pnt2d(200., 100.), gp_Pnt2d(150., 200.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW2.Add(BRepBuilderAPI_MakeEdge(aline, surf2, 0., p1.Distance(p2)).Edge())

    p1, p2 = gp_Pnt2d(150., 200.), gp_Pnt2d(100., 100.)
    aline = GCE2d_MakeLine(p1, p2).Value()
    MW2.Add(BRepBuilderAPI_MakeEdge(aline, surf2, 0., p1.Distance(p2)).Edge())

    MKF2 = BRepBuilderAPI_MakeFace()
    MKF2.Init(surf2, False, 1e-6)
    MKF2.Add(MW2.Wire())
    MKF2.Build()

    FP = MKF2.Face()
    breplib_BuildCurves3d(FP)
    MKP2 = BRepFeat_MakePrism(res1, FP, F2, D2, 0, True)
    MKP2.PerformThruAll()
    display.EraseAll()

    trf = gp_Trsf()
    trf.SetTranslation(gp_Vec(0, 0, 300))
    gtrf = gp_GTrsf()
    gtrf.SetTrsf(trf)
    tr = BRepBuilderAPI_GTransform(MKP2.Shape(), gtrf, True)

    fused = BRepAlgoAPI_Fuse(tr.Shape(), MKP2.Shape())
    fused.Build()

    display.DisplayShape(fused.Shape())
    display.FitAll()
def build_tooth():
    base_center = gp_Pnt2d(pitch_circle_radius + (tooth_radius - roller_radius), 0)
    base_circle = gp_Circ2d(gp_Ax2d(base_center, gp_Dir2d()), tooth_radius)
    trimmed_base = GCE2d_MakeArcOfCircle(base_circle,
                                         M_PI - (roller_contact_angle / 2.),
                                         M_PI).Value()
    trimmed_base.Reverse()  # just a trick
    p0 = trimmed_base.StartPoint()
    p1 = trimmed_base.EndPoint()

    # Determine the center of the profile circle
    x_distance = cos(roller_contact_angle / 2.) * (profile_radius + tooth_radius)
    y_distance = sin(roller_contact_angle / 2.) * (profile_radius + tooth_radius)
    profile_center = gp_Pnt2d(pitch_circle_radius - x_distance, y_distance)

    # Construct the profile circle gp_Circ2d
    profile_circle = gp_Circ2d(gp_Ax2d(profile_center, gp_Dir2d()),
                               profile_center.Distance(p1))
    geom_profile_circle = GCE2d_MakeCircle(profile_circle).Value()

    # Construct the outer circle gp_Circ2d
    outer_circle = gp_Circ2d(gp_Ax2d(gp_Pnt2d(0, 0), gp_Dir2d()), top_radius)
    geom_outer_circle = GCE2d_MakeCircle(outer_circle).Value()

    inter = Geom2dAPI_InterCurveCurve(geom_profile_circle, geom_outer_circle)
    num_points = inter.NbPoints()
    assert isinstance(p1, gp_Pnt2d)
    if num_points == 2:
        if p1.Distance(inter.Point(1)) < p1.Distance(inter.Point(2)):
            p2 = inter.Point(1)
        else:
            p2 = inter.Point(2)
    elif num_points == 1:
        p2 = inter.Point(1)
    else:
        sys.exit(-1)

    # Trim the profile circle and mirror
    trimmed_profile = GCE2d_MakeArcOfCircle(profile_circle, p1, p2).Value()

    # Calculate the outermost point
    p3 = gp_Pnt2d(cos(tooth_angle / 2.) * top_radius,
                  sin(tooth_angle / 2.) * top_radius)

    # and use it to create the third arc
    trimmed_outer = GCE2d_MakeArcOfCircle(outer_circle, p2, p3).Value()

    # Mirror and reverse the three arcs
    mirror_axis = gp_Ax2d(gp_Origin2d(), gp_DX2d().Rotated(tooth_angle / 2.))

    mirror_base = Geom2d_TrimmedCurve.DownCast(trimmed_base.Copy())
    mirror_profile = Geom2d_TrimmedCurve.DownCast(trimmed_profile.Copy())
    mirror_outer = Geom2d_TrimmedCurve.DownCast(trimmed_outer.Copy())

    mirror_base.Mirror(mirror_axis)
    mirror_profile.Mirror(mirror_axis)
    mirror_outer.Mirror(mirror_axis)

    mirror_base.Reverse()
    mirror_profile.Reverse()
    mirror_outer.Reverse()

    # Replace the two outer arcs with a single one
    outer_start = trimmed_outer.StartPoint()
    outer_mid = trimmed_outer.EndPoint()
    outer_end = mirror_outer.EndPoint()

    outer_arc = GCE2d_MakeArcOfCircle(outer_start, outer_mid, outer_end).Value()

    # Create an arc for the inside of the wedge
    inner_circle = gp_Circ2d(gp_Ax2d(gp_Pnt2d(0, 0), gp_Dir2d()),
                             top_radius - roller_diameter)
    inner_start = gp_Pnt2d(top_radius - roller_diameter, 0)
    inner_arc = GCE2d_MakeArcOfCircle(inner_circle, inner_start, tooth_angle).Value()
    inner_arc.Reverse()

    # Convert the 2D arcs and two extra lines to 3D edges
    plane = gp_Pln(gp_Origin(), gp_DZ())
    arc1 = BRepBuilderAPI_MakeEdge(geomapi_To3d(trimmed_base, plane)).Edge()
    arc2 = BRepBuilderAPI_MakeEdge(geomapi_To3d(trimmed_profile, plane)).Edge()
    arc3 = BRepBuilderAPI_MakeEdge(geomapi_To3d(outer_arc, plane)).Edge()
    arc4 = BRepBuilderAPI_MakeEdge(geomapi_To3d(mirror_profile, plane)).Edge()
    arc5 = BRepBuilderAPI_MakeEdge(geomapi_To3d(mirror_base, plane)).Edge()

    p4 = mirror_base.EndPoint()
    p5 = inner_arc.StartPoint()

    lin1 = BRepBuilderAPI_MakeEdge(gp_Pnt(p4.X(), p4.Y(), 0),
                                   gp_Pnt(p5.X(), p5.Y(), 0)).Edge()
    arc6 = BRepBuilderAPI_MakeEdge(geomapi_To3d(inner_arc, plane)).Edge()

    p6 = inner_arc.EndPoint()
    lin2 = BRepBuilderAPI_MakeEdge(gp_Pnt(p6.X(), p6.Y(), 0),
                                   gp_Pnt(p0.X(), p0.Y(), 0)).Edge()

    wire = BRepBuilderAPI_MakeWire(arc1)
    wire.Add(arc2)
    wire.Add(arc3)
    wire.Add(arc4)
    wire.Add(arc5)
    wire.Add(lin1)
    wire.Add(arc6)
    wire.Add(lin2)

    face = BRepBuilderAPI_MakeFace(wire.Wire())

    wedge = BRepPrimAPI_MakePrism(face.Shape(), gp_Vec(0.0, 0.0, thickness))

    return wedge.Shape()
Exemple #27
0
aBRespTrsf = BRepBuilderAPI_Transform(aWire.Wire(), aTrsf)

# Get the mirrored shape back out of the transformation and convert back to a wire
aMirroredShape = aBRespTrsf.Shape()

# A wire instead of a generic shape now
aMirroredWire = topods.Wire(aMirroredShape)

# Combine the two constituent wires
mkWire = BRepBuilderAPI_MakeWire()
mkWire.Add(aWire.Wire())
mkWire.Add(aMirroredWire)
myWireProfile = mkWire.Wire()

# The face that we'll sweep to make the prism
myFaceProfile = BRepBuilderAPI_MakeFace(myWireProfile)

# We want to sweep the face along the Z axis to the height
aPrismVec = gp_Vec(0, 0, height)
myBody = BRepPrimAPI_MakePrism(myFaceProfile.Face(), aPrismVec)

# Add fillets to all edges through the explorer
mkFillet = BRepFilletAPI_MakeFillet(myBody.Shape())
anEdgeExplorer = TopExp_Explorer(myBody.Shape(), TopAbs_EDGE)

while anEdgeExplorer.More():
    anEdge = topods.Edge(anEdgeExplorer.Current())
    mkFillet.Add(thickness / 12.0, anEdge)

    anEdgeExplorer.Next()
Exemple #28
0
def _process_unsplit_wing(compound, divide_closed, reloft, tol):
    # Process a wing that was generated without "Split Surfs" option.

    faces = compound.faces
    if len(faces) != 1:
        return None, None
    face = faces[0]

    # Get the surface.
    master_surf = face.surface
    # master_surf = NurbsSurface(master_surf.object)
    uknots, vknots = master_surf.uknots, master_surf.vknots
    vsplit = master_surf.local_to_global_param('v', 0.5)

    # Segment off the end caps and the trailing edges.
    u1, u2 = uknots[1], uknots[-2]
    v1, v2 = vknots[1], vknots[-2]
    s1 = master_surf.copy()
    s1.segment(u1, u2, v1, v2)

    # Reloft the surface by tessellating a curve at each spanwise knot. This
    # enforces C1 continuity but assumes linear spanwise wing which may not
    # support blending wing sections in newer versions of OpenVSP. Also, since
    # the tessellated curves may not match up to the wing end caps making
    # sewing unreliable, flat end caps are assumed.
    if reloft:
        s1 = _reloft_wing_surface(s1, tol)

        # Generate new flat end caps using isocurves at the root and tip of
        # this new surface
        c0 = s1.v_iso(s1.v1)
        c1 = s1.v_iso(s1.v2)
        e0 = Edge.by_curve(c0)
        e1 = Edge.by_curve(c1)
        w0 = Wire.by_edge(e0)
        w1 = Wire.by_edge(e1)
        f0 = Face.by_wire(w0)
        f1 = Face.by_wire(w1)

        # Make faces of surfaces
        f = Face.by_surface(s1)
        new_faces = [f, f0, f1]
    else:
        # Reparamterize knots in spanwise direction to be chord length instead
        # of uniform. Use isocurve at quarter-chord to determine knot values.
        # This only works as long as surfaces are linear.
        c0 = s1.u_iso(s1.u1)
        c0.segment(vsplit, c0.u2)
        qc_u = PointFromParameter(c0, vsplit, 0.25 * c0.length).parameter
        c = s1.v_iso(qc_u)
        pnts = [c.eval(u) for u in c.knots]
        new_uknots = geom_utils.chord_parameters(pnts, 0., 1.)
        s1.set_uknots(new_uknots)

        # Segment off end caps
        u1, u2 = uknots[0], uknots[1]
        v1, v2 = vknots[1], vsplit
        s2 = master_surf.copy()
        s2.segment(u1, u2, v1, v2)

        u1, u2 = uknots[0], uknots[1]
        v1, v2 = vsplit, vknots[-2]
        s3 = master_surf.copy()
        s3.segment(u1, u2, v1, v2)

        u1, u2 = uknots[-2], uknots[-1]
        v1, v2 = vknots[1], vsplit
        s4 = master_surf.copy()
        s4.segment(u1, u2, v1, v2)

        u1, u2 = uknots[-2], uknots[-1]
        v1, v2 = vsplit, vknots[-2]
        s5 = master_surf.copy()
        s5.segment(u1, u2, v1, v2)

        # Make faces of surfaces
        new_faces = []
        for s in [s1, s2, s3, s4, s5]:
            f = Face.by_surface(s)
            new_faces.append(f)

    # Segment off TE.
    u1, u2 = uknots[0], uknots[-1]
    v1, v2 = vknots[0], vknots[1]
    s6 = master_surf.copy()
    s6.segment(u1, u2, v1, v2)

    u1, u2 = uknots[0], uknots[-1]
    v1, v2 = vknots[-2], vknots[-1]
    s7 = master_surf.copy()
    s7.segment(u1, u2, v1, v2)

    # Split the TE surface at each u-knot.
    usplits = occ_utils.to_tcolstd_hseq_real(uknots[1:-1])

    split = ShapeUpgrade_SplitSurface()
    split.Init(s6.object)
    split.SetUSplitValues(usplits)
    split.Perform()
    comp_surf1 = split.ResSurfaces()

    split = ShapeUpgrade_SplitSurface()
    split.Init(s7.object)
    split.SetUSplitValues(usplits)
    split.Perform()
    comp_surf2 = split.ResSurfaces()

    # For each patch in the composite surfaces create a face.
    for i in range(1, comp_surf1.NbUPatches() + 1):
        for j in range(1, comp_surf1.NbVPatches() + 1):
            hpatch = comp_surf1.Patch(i, j)
            f = BRepBuilderAPI_MakeFace(hpatch, 0.).Face()
            new_faces.append(f)

    for i in range(1, comp_surf2.NbUPatches() + 1):
        for j in range(1, comp_surf2.NbVPatches() + 1):
            hpatch = comp_surf2.Patch(i, j)
            f = BRepBuilderAPI_MakeFace(hpatch, 0.).Face()
            new_faces.append(f)

    # Put all faces into a compound a generate solid.
    new_compound = Compound.by_shapes(new_faces)

    return _build_solid(new_compound, divide_closed)
Exemple #29
0
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
def cut_out(base):
    outer = gp_Circ2d(gp_OX2d(), top_radius - 1.75 * roller_diameter)
    inner = gp_Circ2d(gp_OX2d(), center_radius + 0.75 * roller_diameter)

    geom_outer = GCE2d_MakeCircle(outer).Value()
    geom_inner = GCE2d_MakeCircle(inner).Value()
    geom_inner.Reverse()

    base_angle = (2. * M_PI) / mounting_hole_count
    hole_angle = atan(hole_radius / mounting_radius)
    correction_angle = 3 * hole_angle

    left = gp_Lin2d(gp_Origin2d(), gp_DX2d())
    right = gp_Lin2d(gp_Origin2d(), gp_DX2d())
    left.Rotate(gp_Origin2d(), correction_angle)
    right.Rotate(gp_Origin2d(), base_angle - correction_angle)

    geom_left = GCE2d_MakeLine(left).Value()
    geom_right = GCE2d_MakeLine(right).Value()

    inter_1 = Geom2dAPI_InterCurveCurve(geom_outer, geom_left)
    inter_2 = Geom2dAPI_InterCurveCurve(geom_outer, geom_right)
    inter_3 = Geom2dAPI_InterCurveCurve(geom_inner, geom_right)
    inter_4 = Geom2dAPI_InterCurveCurve(geom_inner, geom_left)

    if inter_1.Point(1).X() > 0:
        p1 = inter_1.Point(1)
    else:
        p1 = inter_1.Point(2)

    if inter_2.Point(1).X() > 0:
        p2 = inter_2.Point(1)
    else:
        p2 = inter_2.Point(2)

    if inter_3.Point(1).X() > 0:
        p3 = inter_3.Point(1)
    else:
        p3 = inter_3.Point(2)

    if inter_4.Point(1).X() > 0:
        p4 = inter_4.Point(1)
    else:
        p4 = inter_4.Point(2)

    trimmed_outer = GCE2d_MakeArcOfCircle(outer, p1, p2).Value()
    trimmed_inner = GCE2d_MakeArcOfCircle(inner, p4, p3).Value()

    plane = gp_Pln(gp_Origin(), gp_DZ())

    arc1 = BRepBuilderAPI_MakeEdge(geomapi_To3d(trimmed_outer, plane)).Edge()

    lin1 = BRepBuilderAPI_MakeEdge(gp_Pnt(p2.X(), p2.Y(), 0),
                                   gp_Pnt(p3.X(), p3.Y(), 0)).Edge()

    arc2 = BRepBuilderAPI_MakeEdge(geomapi_To3d(trimmed_inner, plane)).Edge()

    lin2 = BRepBuilderAPI_MakeEdge(gp_Pnt(p4.X(), p4.Y(), 0),
                                   gp_Pnt(p1.X(), p1.Y(), 0)).Edge()

    cutout_wire = BRepBuilderAPI_MakeWire(arc1)
    cutout_wire.Add(lin1)
    cutout_wire.Add(arc2)
    cutout_wire.Add(lin2)

    # Turn the wire into a face
    cutout_face = BRepBuilderAPI_MakeFace(cutout_wire.Wire())
    filleted_face = BRepFilletAPI_MakeFillet2d(cutout_face.Face())

    explorer = BRepTools_WireExplorer(cutout_wire.Wire())
    while explorer.More():
        vertex = explorer.CurrentVertex()
        filleted_face.AddFillet(vertex, roller_radius)
        explorer.Next()

    cutout = BRepPrimAPI_MakePrism(filleted_face.Shape(),
                                   gp_Vec(0.0, 0.0, thickness)).Shape()

    result = base
    rotate = gp_Trsf()
    for i in range(0, mounting_hole_count):
        rotate.SetRotation(gp_OZ(), i * 2. * M_PI / mounting_hole_count)
        rotated_cutout = BRepBuilderAPI_Transform(cutout, rotate, True)

        result = BRepAlgoAPI_Cut(result,
                                 rotated_cutout.Shape()).Shape()

    return result