"""
BuildLine
name: build_line.py
by: Gumyr
date: July 12th 2022
desc:
This python module is a library used to build lines in three dimensional space.
license:
Copyright 2022 Gumyr
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import annotations
from typing import Union
from build123d.build_common import Builder, WorkplaneList, logger
from build123d.build_enums import Mode
from build123d.geometry import Location, Plane
from build123d.topology import Curve, Edge, Face
[docs]
class BuildLine(Builder):
"""BuildLine
The BuildLine class is a subclass of Builder for building lines (objects
with length but not area or volume). It has an _obj property that returns
the current line being built. The class overrides the faces and solids methods
of Builder since they don't apply to lines.
BuildLine only works with a single workplane which is used to convert tuples
as inputs to global coordinates. For example:
.. code::
with BuildLine(Plane.YZ) as radius_arc:
RadiusArc((1, 2), (2, 1), 1)
creates an arc from global points (0, 1, 2) to (0, 2, 1). Note that points
entered as Vector(x, y, z) are considered global and are not localized.
The workplane is also used to define planes parallel to the workplane that
arcs are created on.
Args:
workplane (Union[Face, Plane, Location], optional): plane used when local
coordinates are used and when creating arcs. Defaults to Plane.XY.
mode (Mode, optional): combination mode. Defaults to Mode.ADD.
"""
_tag = "BuildLine" # Alternate for __class__.__name__
_obj_name = "line" # Name of primary instance variable
_shape = Edge # Type of shapes being constructed
_sub_class = Curve # Class of line/_obj
def __init__(
self,
workplane: Face | Plane | Location = Plane.XY,
mode: Mode = Mode.ADD,
):
self._line: Curve | None = None
super().__init__(workplane, mode=mode)
if len(self.workplanes) > 1:
raise ValueError("BuildLine only accepts one workplane")
@property
def line(self) -> Curve | None:
"""Get the current line"""
return self._line
@line.setter
def line(self, value: Curve) -> None:
"""Set the current line"""
self._line = value
_obj = line # Alias _obj to line
def __exit__(self, exception_type, exception_value, traceback):
"""Upon exiting restore context and send object to parent"""
self._current.reset(self._reset_tok)
if (
self.builder_parent is not None
and self.mode != Mode.PRIVATE
and self.line is not None
):
logger.debug(
"Transferring object(s) to %s", type(self.builder_parent).__name__
)
self.builder_parent._add_to_context(self.line, mode=self.mode)
self.exit_workplanes = WorkplaneList._get_context().workplanes
# Now that the object has been transferred, it's safe to remove any (non-default)
# workplanes that were created then exit
if self.workplanes:
self.workplanes_context.__exit__(None, None, None)
logger.info("Exiting %s", type(self).__name__)
[docs]
def faces(self, *args):
"""faces() not implemented"""
raise NotImplementedError("faces() doesn't apply to BuildLine")
[docs]
def face(self, *args):
"""face() not implemented"""
raise NotImplementedError("face() doesn't apply to BuildLine")
[docs]
def solids(self, *args):
"""solids() not implemented"""
raise NotImplementedError("solids() doesn't apply to BuildLine")
[docs]
def solid(self, *args):
"""solid() not implemented"""
raise NotImplementedError("solid() doesn't apply to BuildLine")
def _add_to_pending(self, *objects: Edge | Face, face_plane: Plane | None = None):
"""_add_to_pending not implemented"""
raise NotImplementedError("_add_to_pending doesn't apply to BuildLine")