Source code for declaracad.occ.impl.occ_fillet

"""
Copyright (c) 2016-2021, CodeLV.

Distributed under the terms of the GPL v3 License.

The full license is in the file LICENSE, distributed with this software.

Created on Dec 23, 2021

@author: jrm
"""

from atom.api import set_default
from OCCT.BRepBuilderAPI import BRepBuilderAPI_MakeFace
from OCCT.BRepFilletAPI import BRepFilletAPI_MakeFillet, BRepFilletAPI_MakeFillet2d
from OCCT.BRepTools import BRepTools
from OCCT.ChFi3d import ChFi3d_Polynomial, ChFi3d_QuasiAngular, ChFi3d_Rational
from OCCT.gp import gp_Pnt2d
from OCCT.ShapeFix import ShapeFix_Shape
from OCCT.TColgp import TColgp_Array1OfPnt2d
from OCCT.TopoDS import TopoDS_Face, TopoDS_Shape, TopoDS_Vertex, TopoDS_Wire

from declaracad.core.utils import log
from declaracad.occ.algo import ProxyFillet

from .occ_algo import OccOperation
from .topology import Topology


[docs] class OccFillet(OccOperation, ProxyFillet): reference = set_default( "https://dev.opencascade.org/doc/refman/html/" "class_b_rep_fillet_a_p_i___make_fillet.html" ) shape_types = { "rational": ChFi3d_Rational, "angular": ChFi3d_QuasiAngular, "polynomial": ChFi3d_Polynomial, } def update_shape(self, change=None): d = self.declaration # Get the shape to apply the fillet to child = self.get_first_child() # Ignore this operation if d.disabled: self.shape = child.shape return s = child.shape if isinstance(s, (TopoDS_Wire, TopoDS_Face)): shape = self.fillet_2d(child) else: shape = self.fillet_3d(child) if d.fix: fixer = ShapeFix_Shape(shape) if fixer.Perform(): shape = fixer.Shape() self.shape = shape def fillet_2d(self, child) -> TopoDS_Shape: d = self.declaration shape = child.shape was_wire = isinstance(shape, TopoDS_Wire) if was_wire: shape = BRepBuilderAPI_MakeFace(shape).Face() builder = BRepFilletAPI_MakeFillet2d(shape) operations = d.operations if d.operations else child.topology.vertices for item in operations: if isinstance(item, (tuple, list)) and len(item) == 2: r, v = item builder.AddFillet(v, r) elif isinstance(item, TopoDS_Vertex): builder.AddFillet(item, d.radius) else: log.warning(f"Invalid fillet {item}") shape = Topology.cast_shape(builder.Shape()) if was_wire: shape = BRepTools.OuterWire_(shape) return shape def fillet_3d(self, child) -> TopoDS_Shape: d = self.declaration fillet = BRepFilletAPI_MakeFillet(child.shape) operations = d.operations if d.operations else child.topology.edges for item in operations: if not isinstance(item, (list, tuple)): r = d.radius if isinstance(item, TopoDS_Face): for edge in Topology(shape=item).edges_from_face(item): fillet.Add(r, edge) elif isinstance(item, TopoDS_Wire): for edge in Topology(shape=item).edges_from_wire(item): fillet.Add(r, edge) else: fillet.Add(r, item) continue # If an array of points is create a changing radius fillet n = len(item) if n == 2 and isinstance(item[0], (list, tuple)): pts, edge = item array = TColgp_Array1OfPnt2d(1, len(pts)) for i, pt in enumerate(pts): array.SetValue(i + 1, gp_Pnt2d(*pt)) fillet.Add(array, edge) continue if n == 2: if isinstance(item[1], TopoDS_Face): r, face = item for edge in Topology(shape=face).edges_from_face(face): fillet.Add(r, edge) continue elif isinstance(item[1], TopoDS_Wire): r, wire = item for edge in Topology(shape=wire).edges_from_wire(wire): fillet.Add(r, edge) continue # custom radius or r1 and r2 radius fillets fillet.Add(*item) return fillet.Shape() def set_shape_type(self, shape_type): self.update_shape() def set_radius(self, r): self.update_shape() def set_operations(self, operations): self.update_shape()