def make_loft(elements, ruled=False, tolerance=TOLERANCE, continuity=GeomAbs_C2, check_compatibility=True): from OCCT.BRepOffsetAPI import BRepOffsetAPI_ThruSections sections = BRepOffsetAPI_ThruSections(False, ruled, tolerance) for i in elements: if isinstance(i, TopoDS_Wire): sections.AddWire(i) elif isinstance(i, TopoDS_Vertex): sections.AddVertex(i) else: raise TypeError('elements is a list of TopoDS_Wire or TopoDS_Vertex, found a %s fool' % i.__class__) sections.CheckCompatibility(check_compatibility) sections.SetContinuity(continuity) sections.Build() with assert_isdone(sections, 'failed lofting'): te = ShapeToTopology() loft = te(sections.Shape()) return loft
class LoftShape(object): """ Loft a shape using a sequence of sections. :param sections: The sections of the loft. These are usually wires but the first and last section can be vertices. Edges are converted to wires before adding to the loft tool. :type sections: collections.Sequence(afem.topology.entities.Vertex or afem.topology.entities.Edge or afem.topology.entities.Wire) :param bool is_solid: If *True* the tool will build a solid, otherwise it will build a shell. :param bool make_ruled: If *True* the faces between sections will be ruled surfaces, otherwise they are smoothed out by approximation. :param float pres3d: Defines the precision for the approximation algorithm. :param bool check_compatibility: Option to check the orientation of the sections to avoid twisted results and update to have the same number of edges. :param bool use_smoothing: Option to use approximation algorithm. :param OCCT.Approx.Approx_ParametrizationType par_type: Parametrization type. :param OCCT.GeomAbs.GeomAbs_Shape continuity: The desired continuity. :param int max_degree: The maximum degree for the approximation algorithm. :raise TypeError: If any of the sections cannot be added to the tool because they are of the wrong type. """ def __init__(self, sections, is_solid=False, make_ruled=False, pres3d=1.0e-6, check_compatibility=None, use_smoothing=None, par_type=None, continuity=None, max_degree=None): self._tool = BRepOffsetAPI_ThruSections(is_solid, make_ruled, pres3d) if check_compatibility is not None: self._tool.CheckCompatibility(check_compatibility) if use_smoothing is not None: self._tool.SetSmoothing(use_smoothing) if par_type is not None: self._tool.SetParType(par_type) if continuity is not None: self._tool.SetContinuity(continuity) if max_degree is not None: self._tool.SetMaxDegree(max_degree) for section in sections: if section.is_vertex: self._tool.AddVertex(section.object) elif section.is_edge: wire = Wire.by_edge(section) self._tool.AddWire(wire.object) elif section.is_wire: self._tool.AddWire(section.object) else: raise TypeError('Invalid shape type in loft.') self._tool.Build() @property def is_done(self): """ :return: *True* if done, *False* if not. :rtype: bool """ return self._tool.IsDone() @property def shape(self): """ :return: The lofted shape. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.Shape()) @property def first_shape(self): """ :return: The first/bottom shape of the loft if a solid was constructed. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.FirstShape()) @property def last_shape(self): """ :return: The last/top shape of the loft if a solid was constructed. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.LastShape()) @property def max_degree(self): """ :return: The max degree used in the approximation algorithm :rtype: int """ return self._tool.MaxDegree() def generated_face(self, edge): """ Get a face(s) generated by the edge. If the ruled option was used, then this returns each face generated by the edge. If the smoothing option was used, then this returns the face generated by the edge. :param afem.topology.entities.Edge edge: The edge. :return: The face(s) generated by the edge. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.GeneratedFace(edge.object))