Ejemplo n.º 1
0
    def __init__(self, wire, shape1, shape2=None):
        if wire.closed:
            raise TypeError('Closed wires are not supported.')

        shape1 = Shape.to_shape(shape1)
        shape2 = Shape.to_shape(shape2)

        # Split wire with shapes
        other_shape = Compound.by_shapes([shape1, shape2])
        split = SplitShapes(wire, other_shape)
        split_wire = split.shape.wires[0]

        # Get new vertices
        old_verts = ExploreWire(wire).ordered_vertices
        wire_exp = ExploreWire(split_wire)
        all_verts = wire_exp.ordered_vertices
        new_verts = [v for v in all_verts if v not in old_verts]

        # Find index of new vertices and use that to extract edges
        n = len(new_verts)
        if n == 2:
            i1 = all_verts.index(new_verts[0])
            i2 = all_verts.index(new_verts[1])
            ordered_edges = wire_exp.edges
            first_edges = ordered_edges[:i1]
            trimmed_edges = ordered_edges[i1:i2]
            last_edges = ordered_edges[i2:]
        elif n == 1:
            i1 = all_verts.index(new_verts[0])
            ordered_edges = wire_exp.edges
            first_edges = ordered_edges[:i1]
            trimmed_edges = []
            last_edges = ordered_edges[i1:]
        else:
            msg = 'Only one or two split locations are supported.'
            raise RuntimeError(msg)

        # Avoid circular imports
        from afem.topology.create import WireByEdges

        # Collect data and build trimmed wires
        self._first_wire = None
        self._trimmed_wire = None
        self._last_wire = None

        self._split_wire = split_wire
        if len(first_edges) > 0:
            self._first_wire = WireByEdges(*first_edges).wire
        if len(trimmed_edges) > 0:
            self._trimmed_wire = WireByEdges(*trimmed_edges).wire
        if len(last_edges) > 0:
            self._last_wire = WireByEdges(*last_edges).wire
        self._new_verts = new_verts
        self._verts = all_verts
Ejemplo n.º 2
0
 def __init__(self, shapes):
     topods_compound = TopoDS_Compound()
     builder = BRep_Builder()
     builder.MakeCompound(topods_compound)
     for shape in shapes:
         shape = Shape.to_shape(shape)
         if isinstance(shape, Shape):
             builder.Add(topods_compound, shape.object)
     self._cp = Compound(topods_compound)
Ejemplo n.º 3
0
    def __init__(self, shapes):
        results = []
        for shape in shapes:
            shape = Shape.to_shape(shape)
            ls = LinearProps(shape).length
            results.append((ls, shape))

        results.sort(key=lambda tup: tup[0])
        self._lengths = [data[0] for data in results]
        self._shapes = [data[1] for data in results]
Ejemplo n.º 4
0
    def __init__(self, shapes):
        results = []
        for shape in shapes:
            shape = Shape.to_shape(shape)
            a = SurfaceProps(shape).area
            results.append((a, shape))

        results.sort(key=lambda tup: tup[0])
        self._areas = [data[0] for data in results]
        self._shapes = [data[1] for data in results]
Ejemplo n.º 5
0
Archivo: join.py Proyecto: trelau/AFEM
    def __init__(self, parts, shape):
        parts = list(parts)

        shape2 = Shape.to_shape(shape)

        # Loop through each since since that seems to be more robust
        self._status = {}
        for part in parts:
            status = part.cut(shape2)
            self._status[part] = status
Ejemplo n.º 6
0
    def __init__(self, spine, profile):
        if isinstance(spine, Curve):
            spine = Wire.by_curve(spine)
        elif spine.is_edge:
            spine = Wire.by_edge(spine)

        if not spine.is_wire:
            raise TypeError('Spine is not a wire.')

        profile = Shape.to_shape(profile)
        self._tool = BRepOffsetAPI_MakePipe(spine.object, profile.object)

        self._tool.Build()
Ejemplo n.º 7
0
    def trim_u2(self, entity):
        """
        Trim the last parameter of the reference curve by interesting it with
        the entity.

        :param entity: The entity.
        :type entity: afem.geometry.entities.Geometry or
            afem.topology.entities.Shape

        :return: None.

        :raise RuntimeError: If an intersection with the reference curve cannot
            be found.
        """
        shape1 = Shape.to_shape(self.cref)
        shape2 = Shape.to_shape(entity)
        bop = IntersectShapes(shape1, shape2)
        if not bop.is_done:
            raise RuntimeError('Failed to intersect reference curve.')

        pnts = [v.point for v in bop.vertices]
        p = CheckGeom.nearest_point(self.cref.p2, pnts)
        self.set_p2(p)
Ejemplo n.º 8
0
def shape_of_entity(entity):
    """
    Get the shape of the entity. This method is useful if method inputs can
    either be a part or a shape. If the entity is already a shape it will be
    returned. If the entity is part the shape of the part will be returned. If
    the entity is a curve or surface then it will be converted to a shape.

    :param entity: The entity.
    :type entity: afem.geometry.entities.Geometry or
        afem.topology.entities.Shape or afem.base.entities.ShapeHolder

    :return: The shape.
    :rtype: afem.topology.entities.Shape
    """
    if isinstance(entity, ShapeHolder):
        return entity.shape
    else:
        return Shape.to_shape(entity)
Ejemplo n.º 9
0
    def transfer(self, *shapes):
        """
        Transfer and add the shapes to the exported entities.

        :param afem.topology.entities.Shape shapes: The shape(s).

        :return: *True* if shape was transferred, *False* if not.
        :rtype: bool
        """
        added_shape = False
        for shape in shapes:
            shape = Shape.to_shape(shape)
            if not shape:
                continue
            status = self._writer.Transfer(shape.object, STEPControl_AsIs)
            if int(status) < int(IFSelect_RetError):
                added_shape = True
        return added_shape
Ejemplo n.º 10
0
    def discard_by_dmin(self, entity, dmin):
        """
        Discard shapes of the part using a shape and a distance. If the
        distance between a shape of the part and the given shape is less
        than *dmin*, then the shape is removed. Edges are checked
        for curve parts and faces are checked for surface parts.

        :param entity: The shape.
        :type entity: afem.topology.entities.Shape or
            afem.geometry.entities.Geometry
        :param float dmin: The minimum distance.

        :return: *True* if shapes were discarded, *False* if not.
        :rtype: bool

        :raise TypeError: If this part is not a curve or surface part.
        """
        entity = Shape.to_shape(entity)

        if isinstance(self, CurvePart):
            shapes = self.shape.edges
        elif isinstance(self, SurfacePart):
            shapes = self.shape.faces
        else:
            msg = 'Invalid part type in discard operation.'
            raise TypeError(msg)

        rebuild = RebuildShapeWithShapes(self._shape)

        modified = False
        for part_shape in shapes:
            dmin_ = DistanceShapeToShape(entity, part_shape).dmin
            if dmin > dmin_:
                rebuild.remove(part_shape)
                modified = True

        if not modified:
            return False

        new_shape = rebuild.apply()
        self.set_shape(new_shape)
        return True
Ejemplo n.º 11
0
 def __init__(self, shape1, shape2, deflection=1.0e-7):
     shape1 = Shape.to_shape(shape1)
     shape2 = Shape.to_shape(shape2)
     self._tool = BRepExtrema_DistShapeShape(shape1.object, shape2.object,
                                             deflection,
                                             Extrema_ExtFlag_MIN)
Ejemplo n.º 12
0
    def extract_curve(self, u1, v1, u2, v2, basis_shape=None):
        """
        Extract a trimmed curve within the reference surface between the
        parameters.

        :param float u1: First u-parameter.
        :param float v1: First v-parameter.
        :param float u2: Second u-parameter.
        :param float v2: Second v-parameter.
        :param basis_shape: The shape that will be used to intersect with
            the reference shape. If not provided a plane will be
            created using the *extract_plane()* method. The parameters
            should create points that are on or very near the intersection
            between these two shapes. If they are not they will be projected to
            the intersection which could yield unanticipated results.
        :type basis_shape: afem.geometry.entities.Surface or
            afem.topology.entities.Shape

        :return: The curve.
        :rtype: afem.geometry.entities.TrimmedCurve

        :raise RuntimeError: If method fails.
        """
        p1 = self.eval(u1, v1)
        p2 = self.eval(u2, v2)

        if basis_shape is None:
            basis_shape = self.extract_plane(u1, v1, u2, v2)
        basis_shape = Shape.to_shape(basis_shape)

        bop = IntersectShapes(basis_shape, self.sref_shape, approximate=True)
        shape = bop.shape

        edges = shape.edges
        builder = WiresByConnectedEdges(edges)
        if builder.nwires == 0:
            msg = 'Failed to extract any curves.'
            raise RuntimeError(msg)

        if builder.nwires == 1:
            wire = builder.wires[0]
        else:
            dist = DistancePointToShapes(p1, builder.wires)
            wire = dist.nearest_shape
        crv = wire.curve

        proj = ProjectPointToCurve(p1, crv)
        if not proj.success:
            msg = 'Failed to project point to reference curve.'
            raise RuntimeError(msg)
        u1c = proj.nearest_param

        proj = ProjectPointToCurve(p2, crv)
        if not proj.success:
            msg = 'Failed to project point to reference curve.'
            raise RuntimeError(msg)
        u2c = proj.nearest_param

        if u1c > u2c:
            crv.reverse()
            u1c, u2c = crv.reversed_u(u1c), crv.reversed_u(u2c)

        return TrimmedCurve.by_parameters(crv, u1c, u2c)