Source code for declaracad.occ.impl.occ_offset

"""
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 Sep 27, 2016

@author: jrm
"""

from atom.api import set_default
from OCCT.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakeWire
from OCCT.BRepOffset import BRepOffset_Pipe, BRepOffset_RectoVerso, BRepOffset_Skin
from OCCT.BRepOffsetAPI import BRepOffsetAPI_MakeOffset, BRepOffsetAPI_MakeOffsetShape
from OCCT.GeomAbs import GeomAbs_Arc, GeomAbs_Intersection, GeomAbs_Tangent
from OCCT.TopoDS import TopoDS_Compound, TopoDS_Edge, TopoDS_Face, TopoDS_Wire

from declaracad.occ.algo import ProxyOffset, ProxyOffsetShape

from .occ_algo import OccOperation, coerce_shape
from .topology import Topology


[docs] class OccOffset(OccOperation, ProxyOffset): reference = set_default( "https://dev.opencascade.org/doc/refman/html/" "class_b_rep_offset_a_p_i___make_offset.html" ) offset_modes = { "skin": BRepOffset_Skin, "pipe": BRepOffset_Pipe, "recto_verso": BRepOffset_RectoVerso, } join_types = { "arc": GeomAbs_Arc, "tangent": GeomAbs_Tangent, "intersection": GeomAbs_Intersection, } def get_shape_to_offset(self): d = self.declaration if d.shape: return coerce_shape(d.shape) return self.get_first_child().shape def update_shape(self, change=None): d = self.declaration shape = Topology.cast_shape(self.get_shape_to_offset()) if d.disabled or d.offset == 0: self.shape = shape return if isinstance(shape, TopoDS_Edge): shape = BRepBuilderAPI_MakeWire(shape).Wire() elif isinstance(shape, TopoDS_Compound): topo = Topology(shape=shape) first, *others = topo.faces builder = BRepBuilderAPI_MakeFace(first) for face in others: builder.Add(face) shape = builder.Face() elif not isinstance(shape, (TopoDS_Wire, TopoDS_Face)): t = type(shape) raise TypeError(f"Unsupported child shape {t} when using planar mode") join_type = self.join_types[d.join_type] offset_shape = BRepOffsetAPI_MakeOffset(shape, join_type, not d.closed) offset_shape.Perform(d.offset, d.normal_distance) if not offset_shape.IsDone(): # Note: Lines cannot be offset as they have no plane of reference raise ValueError("Could not perform offset: %s" % d) result = Topology.cast_shape(offset_shape.Shape()) if d.as_face: if isinstance(result, TopoDS_Compound): topo = Topology(shape=result) first, *others = topo.wires builder = BRepBuilderAPI_MakeFace(first) for face in others: builder.Add(face) self.shape = builder.Face() else: self.shape = BRepBuilderAPI_MakeFace(result).Face() else: self.shape = result def set_shape(self, shape): self.update_shape() def set_offset(self, offset): self.update_shape() def set_offset_mode(self, mode): self.update_shape() def set_join_type(self, mode): self.update_shape() def set_intersection(self, enabled): self.update_shape() def set_as_face(self, enabled: bool): self.update_shape()
[docs] class OccOffsetShape(OccOffset, ProxyOffsetShape): reference = set_default( "https://dev.opencascade.org/doc/refman/html/" "class_b_rep_offset_a_p_i___make_offset_shape.html" ) def update_shape(self, change=None): d = self.declaration shape = self.get_shape_to_offset() offset_shape = BRepOffsetAPI_MakeOffsetShape() offset_shape.PerformByJoin( shape, d.offset, d.tolerance, self.offset_modes[d.offset_mode], d.intersection, False, self.join_types[d.join_type], ) self.shape = offset_shape.Shape()