Beispiel #1
0
 def update(self) -> None:
     if not self._tainted:
         return
     center = self.center
     w2 = Vec2.from_deg_angle(self._angle, self._width / 2.0)
     h2 = Vec2.from_deg_angle(self._angle + 90, self._height / 2.0)
     self._corners = (
         center - w2 - h2,  # lower left
         center + w2 - h2,  # lower right
         center + w2 + h2,  # upper right
         center - w2 + h2,  # upper left
     )
     self._tainted = False
Beispiel #2
0
 def get_user_defined_text_location(self) -> Vec2:
     """Returns text midpoint for user defined dimension location."""
     measurement = self.measurement
     assert isinstance(measurement.user_location, Vec2)
     text_outside_horiz = (
         measurement.text_is_outside and measurement.text_outside_horizontal
     )
     text_inside_horiz = (
         measurement.text_is_inside and measurement.text_inside_horizontal
     )
     if text_outside_horiz or text_inside_horiz:
         hdist = self._total_text_width / 2.0
         if (
             measurement.vertical_placement == 0
         ):  # shift text horizontal if vertical centered
             hdist += self.arrows.arrow_size
         if measurement.user_location.x <= self.point_on_circle.x:
             hdist = -hdist
         vdist = measurement.text_vertical_distance()
         return measurement.user_location + Vec2((hdist, vdist))
     else:
         text_normal_vec = Vec2.from_deg_angle(
             measurement.text_rotation
         ).orthogonal()
         return (
             measurement.user_location
             + text_normal_vec * measurement.text_vertical_distance()
         )
Beispiel #3
0
    def get_default_text_location(self) -> Vec2:
        """Returns default text midpoint based on `text_valign` and
        `text_outside`
        """
        measurement = self.measurement
        if measurement.text_is_outside and measurement.text_outside_horizontal:
            hdist = self._total_text_width / 2.0
            if (
                measurement.vertical_placement == 0
            ):  # shift text horizontal if vertical centered
                hdist += self.arrows.arrow_size
            angle = self.dim_line_angle % 360.0  # normalize 0 .. 360
            if 90.0 < angle <= 270.0:
                hdist = -hdist
            return self.outside_default_defpoint + Vec2(
                (hdist, measurement.text_vertical_distance())
            )

        text_direction = Vec2.from_deg_angle(measurement.text_rotation)
        vertical_direction = text_direction.orthogonal(ccw=True)
        vertical_distance = measurement.text_vertical_distance()
        if measurement.text_is_inside:
            hdist = (self.radius - self.arrows.arrow_size) / 2.0
            text_midpoint = self.center + (self.dim_line_vec * hdist)
        else:
            hdist = (
                self._total_text_width / 2.0
                + self.arrows.arrow_size
                + measurement.text_gap
            )
            text_midpoint = self.point_on_circle + (self.dim_line_vec * hdist)
        return text_midpoint + (vertical_direction * vertical_distance)
Beispiel #4
0
    def extension_line_points(self,
                              start: Vec2,
                              end: Vec2,
                              text_above_extline=False) -> Tuple[Vec2, Vec2]:
        """
        Adjust start and end point of extension line by dimension variables DIMEXE, DIMEXO, DIMEXFIX, DIMEXLEN.

        Args:
            start: start point of extension line (measurement point)
            end: end point at dimension line
            text_above_extline: True if text is above and aligned with extension line

        Returns: adjusted start and end point

        """
        if start == end:
            direction = Vec2.from_deg_angle(self.ext_line_angle)
        else:
            direction = (end - start).normalize()
        if self.ext_line_fixed:
            start = end - (direction * self.ext_line_length)
        else:
            start = start + direction * self.ext_line_offset
        extension = self.ext_line_extension
        if text_above_extline:
            extension += self.dim_text_width
        end = end + direction * extension
        return start, end
Beispiel #5
0
def connection_point(arrow_name: str,
                     insert: 'Vertex',
                     scale: float = 1,
                     rotation: float = 0) -> Vec2:
    insert = Vec2(insert)
    if arrow_name in _Arrows.ORIGIN_ZERO:
        return insert
    else:
        return insert - Vec2.from_deg_angle(rotation, scale)
Beispiel #6
0
def connection_point(arrow_name: str,
                     insert: Vertex,
                     scale: float = 1.0,
                     rotation: float = 0.0) -> Vec2:
    """Returns the connection point for `arrow_name`. """
    insert = Vec2(insert)
    if ARROWS.arrow_name(arrow_name) in _Arrows.ORIGIN_ZERO:
        return insert
    else:
        return insert - Vec2.from_deg_angle(rotation, scale)
Beispiel #7
0
    def get_default_text_location(self) -> Vec2:
        """ Returns default text midpoint based on `self.text_valign` and `self.text_outside` """
        if self.text_outside and self.text_outside_horizontal:
            return super().get_default_text_location()

        text_direction = Vec2.from_deg_angle(self.text_rotation)
        vertical_direction = text_direction.orthogonal(ccw=True)
        vertical_distance = self.text_vertical_distance()
        if self.text_inside:
            text_midpoint = self.center
        else:
            hdist = self.dim_text_width / 2. + self.arrow_size + self.text_gap
            text_midpoint = self.point_on_circle + (self.dim_line_vec * hdist)
        return text_midpoint + (vertical_direction * vertical_distance)
Beispiel #8
0
    def vertices(self, a: Iterable[float]) -> Iterable[Vec2]:
        """ Yields vertices on arc for angles in iterable `a` in WCS as location
        vectors.

        Args:
            a: angles in the range from 0 to 360 in degrees, arc goes
                counter clockwise around the z-axis, WCS x-axis = 0 deg.

        """
        center = self.center
        radius = self.radius

        for angle in a:
            yield center + Vec2.from_deg_angle(angle, radius)
Beispiel #9
0
 def get_user_defined_text_location(self) -> Vec2:
     """ Returns text midpoint for user defined dimension location. """
     text_outside_horiz = self.text_outside and self.text_outside_horizontal
     text_inside_horiz = self.text_inside and self.text_inside_horizontal
     if text_outside_horiz or text_inside_horiz:
         hdist = self.dim_text_width / 2
         if self.vertical_placement == 0:  # shift text horizontal if vertical centered
             hdist += self.arrow_size
         if self.user_location.x <= self.point_on_circle.x:
             hdist = -hdist
         vdist = self.text_vertical_distance()
         return self.user_location + Vec2((hdist, vdist))
     else:
         text_normal_vec = Vec2.from_deg_angle(self.text_rotation).orthogonal()
         return self.user_location + text_normal_vec * self.text_vertical_distance()
Beispiel #10
0
    def default_text_location(self) -> Vec2:
        """Calculate default text location in UCS based on `self.text_halign`,
        `self.text_valign` and `self.text_outside`

        """
        start = self.dim_line_start
        end = self.dim_line_end
        measurement = self.measurement
        halign = measurement.text_halign
        # positions the text above and aligned with the first/second extension line
        ext_lines = self.extension_lines
        if halign in (3, 4):
            # horizontal location
            hdist = measurement.text_gap + measurement.text_height / 2.0
            hvec = self.dim_line_vec * hdist
            location = (start if halign == 3 else end) - hvec
            # vertical location
            vdist = ext_lines.extension_above + self._total_text_width / 2.0
            location += Vec2.from_deg_angle(
                self.ext_line_angle).normalize(vdist)
        else:
            # relocate outside text to center location
            if measurement.text_is_outside:
                halign = 0

            if halign == 0:
                location = self.dim_line_center  # center of dimension line
            else:
                hdist = (self._total_text_width / 2.0 +
                         self.arrows.arrow_size + measurement.text_gap)
                if (halign == 1
                    ):  # positions the text next to the first extension line
                    location = start + (self.dim_line_vec * hdist)
                else:  # positions the text next to the second extension line
                    location = end - (self.dim_line_vec * hdist)

            if measurement.text_is_outside:  # move text up
                vdist = (ext_lines.extension_above + measurement.text_gap +
                         measurement.text_height / 2.0)
            else:
                # distance from extension line to text midpoint
                vdist = measurement.text_vertical_distance()
            location += self.dim_line_vec.orthogonal().normalize(vdist)

        return location
Beispiel #11
0
    def add_text(self,
                 text: str,
                 pos: Vector,
                 rotation: float,
                 dxfattribs: dict = None) -> None:
        """
        Add TEXT (DXF R12) or MTEXT (DXF R2000+) entity to the dimension BLOCK.

        Args:
            text: text as string
            pos: insertion location in UCS
            rotation: rotation angle in degrees in UCS (x-axis is 0 degrees)
            dxfattribs: additional or overridden DXF attributes

        """
        attribs = self.default_attributes()
        attribs['style'] = self.text_style_name
        attribs['color'] = self.text_color
        if self.requires_extrusion:
            attribs['extrusion'] = self.ucs.uz

        if self.supports_dxf_r2000:
            text_direction = self.ucs.to_wcs(
                Vec2.from_deg_angle(rotation)) - self.ucs.origin
            attribs['text_direction'] = text_direction
            attribs['char_height'] = self.text_height
            attribs['insert'] = self.wcs(pos)
            attribs['attachment_point'] = self.text_attachment_point

            if self.supports_dxf_r2007:
                if self.text_fill:
                    attribs['box_fill_scale'] = self.text_box_fill_scale
                    attribs['bg_fill_color'] = self.text_fill_color
                    attribs['bg_fill'] = 3 if self.text_fill == 1 else 1

            if dxfattribs:
                attribs.update(dxfattribs)
            self.block.add_mtext(text, dxfattribs=attribs)
        else:
            attribs['rotation'] = self.ucs.to_ocs_angle_deg(rotation)
            attribs['height'] = self.text_height
            if dxfattribs:
                attribs.update(dxfattribs)
            dxftext = self.block.add_text(text, dxfattribs=attribs)
            dxftext.set_pos(self.ocs(pos), align='MIDDLE_CENTER')
Beispiel #12
0
def quick_mtext_horizontal(name: str):
    doc = ezdxf.new(DXFVERSION, setup=True)
    mleaderstyle = doc.mleader_styles.duplicate_entry("Standard", "EZDXF")
    mleaderstyle.set_mtext_style("OpenSans")  # type: ignore
    msp = doc.modelspace()
    target_point = Vec2(40, 15)
    msp.add_circle(
        target_point, radius=0.5, dxfattribs=GfxAttribs(color=colors.RED)
    )

    for angle in [45, 135, 225, -45]:
        ml_builder = msp.add_multileader_mtext("EZDXF")
        ml_builder.quick_leader(
            "Line1\nLine2",
            target=target_point,
            segment1=Vec2.from_deg_angle(angle, 14),
        )

    doc.set_modelspace_vport(60, center=(10, 5))
    doc.saveas(OUTDIR / f"{name}_{DXFVERSION}.dxf")
Beispiel #13
0
    def get_default_text_location(self) -> Vec2:
        """ Returns default text midpoint based on `self.text_valign` and `self.text_outside` """
        if self.text_outside and self.text_outside_horizontal:
            hdist = self.dim_text_width / 2.
            if self.vertical_placement == 0:  # shift text horizontal if vertical centered
                hdist += self.arrow_size
            angle = self.dim_line_angle % 360.  # normalize 0 .. 360
            if 90 < angle <= 270:
                hdist = -hdist
            return self.outside_default_defpoint + Vec2((hdist, self.text_vertical_distance()))

        text_direction = Vec2.from_deg_angle(self.text_rotation)
        vertical_direction = text_direction.orthogonal(ccw=True)
        vertical_distance = self.text_vertical_distance()
        if self.text_inside:
            hdist = (self.measurement - self.arrow_size) / 2
            text_midpoint = self.center + (self.dim_line_vec * hdist)
        else:
            hdist = self.dim_text_width / 2. + self.arrow_size + self.text_gap
            text_midpoint = self.point_on_circle + (self.dim_line_vec * hdist)
        return text_midpoint + (vertical_direction * vertical_distance)
def single_triangle(pos, rotation, fill):
    if not hasattr(single_triangle, "counter"):
        single_triangle.counter = 0
    single_triangle.counter += 1

    block_name = "triangle" + str(single_triangle.counter)
    shape_test = doc.blocks.new(name=block_name)
    points = [Vec2.from_deg_angle((360 / 3) * n) for n in range(3)]
    points.append(points[0])
    if (fill):
        hatch = shape_test.add_hatch(color=1)
        hatch.paths.add_polyline_path(points)
    else:
        points.append(points[0])
        shape_test.add_lwpolyline(points, dxfattribs={'color': 1})

    msp.add_blockref(block_name,
                     pos,
                     dxfattribs={
                         'rotation': rotation,
                         'xscale': 9,
                         'yscale': 9
                     })
Beispiel #15
0
 def start_point(self) -> 'Vec2':
     """ start point of arc as :class:`Vec2`. """
     return self.center + Vec2.from_deg_angle(self.start_angle, self.radius)
Beispiel #16
0
def sort_projected_points(points: Iterable['Vertex'],
                          angle: float = 0) -> List[Vec2]:
    direction = Vec2.from_deg_angle(angle)
    projected_vectors = [(direction.project(Vec2(p)), p) for p in points]
    return [p for projection, p in sorted(projected_vectors)]
Beispiel #17
0
 def end_point(self) -> 'Vec2':
     """ end point of arc as :class:`Vec2`. """
     return self.center + Vec2.from_deg_angle(self.end_angle, self.radius)