"""
BuildSketch
name: build_sketch.py
by: Gumyr
date: July 12th 2022
desc:
This python module is a library used to build planar sketches.
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
from build123d.build_enums import Mode
from build123d.geometry import Location, Plane
from build123d.topology import Compound, Edge, Face, ShapeList, Sketch, Wire
[docs]
class BuildSketch(Builder):
"""BuildSketch
The BuildSketch class is a subclass of Builder for building planar 2D
sketches (objects with area but not volume) from faces or lines.
It has an _obj property that returns the current sketch being built.
The sketch property consists of the sketch(es) applied to the input
workplanes while the sketch_local attribute is the sketch constructed
on Plane.XY. The class overrides the solids method of Builder since
they don't apply to lines.
Note that all sketch construction is done within sketch_local on Plane.XY.
When objects are added to the sketch they must be coplanar to Plane.XY,
usually handled automatically but may need user input for Edges and Wires
since their construction plane isn't always able to be determined.
Args:
workplanes (Union[Face, Plane, Location], optional): objects converted to
plane(s) to place the sketch on. Defaults to Plane.XY.
mode (Mode, optional): combination mode. Defaults to Mode.ADD.
"""
_tag = "BuildSketch" # Alternate for __class__.__name__
_obj_name = "sketch" # Name of primary instance variable
_shape = Face # Type of shapes being constructed
_sub_class = Sketch # Class of sketch/_obj
def __init__(
self,
*workplanes: Face | Plane | Location,
mode: Mode = Mode.ADD,
):
self.mode = mode
self._sketch_local: Sketch | None = None
self.pending_edges: ShapeList[Edge] = ShapeList()
super().__init__(*workplanes, mode=mode)
@property
def sketch_local(self) -> Sketch | None:
"""Get the builder's object"""
return self._sketch_local
@sketch_local.setter
def sketch_local(self, value: Sketch) -> None:
"""Set the builder's object"""
self._sketch_local = value
_obj = sketch_local # Alias _obj to sketch_local
@property
def sketch(self):
"""The global version of the sketch - may contain multiple sketches"""
workplanes = (
self.exit_workplanes
if self.exit_workplanes
else WorkplaneList._get_context().workplanes
)
global_objs = []
for plane in workplanes:
global_objs.append(plane.from_local_coords(self._obj))
return Sketch(Compound(global_objs).wrapped)
[docs]
def solids(self, *args):
"""solids() not implemented"""
raise NotImplementedError("solids() doesn't apply to BuildSketch")
[docs]
def solid(self, *args):
"""solid() not implemented"""
raise NotImplementedError("solid() doesn't apply to BuildSketch")
[docs]
def consolidate_edges(self) -> Wire | list[Wire]:
"""Unify pending edges into one or more Wires"""
wires = Wire.combine(self.pending_edges)
return wires if len(wires) > 1 else wires[0]
def _add_to_pending(self, *objects: Edge, face_plane: Plane | None = None):
"""Integrate a sequence of objects into existing builder object"""
if face_plane:
raise NotImplementedError("face_plane arg not supported for this method")
self.pending_edges.extend(objects)