Documentation rebuilt - removed cadquery dependency

This commit is contained in:
Roger Maitland 2022-10-28 11:00:53 -04:00
parent c12c52d8f1
commit cdfa27949d
27 changed files with 348 additions and 416 deletions

View file

@ -118,8 +118,3 @@ a fully custom selection:
lambda v: (v.Y == 0.0 or v.Y == height) and -width / 2 < v.X < width / 2, lambda v: (v.Y == 0.0 or v.Y == height) and -width / 2 < v.X < width / 2,
din.vertices(), din.vertices(),
) )
One can sort by all of the following attributes:
.. autoclass:: build_common.SortBy
:noindex:

View file

@ -6,16 +6,11 @@ API Reference
Selector Methods Selector Methods
**************** ****************
.. py:module:: build_common .. automethod:: build_common::Builder.vertices
.. automethod:: build_common::Builder.faces
.. automethod:: Builder.vertices .. automethod:: build_common::Builder.edges
.. automethod:: Builder.faces .. automethod:: build_common::Builder.wires
.. automethod:: Builder.edges .. automethod:: build_part::BuildPart.solids
.. automethod:: Builder.wires
.. py:module:: build_part
.. automethod:: BuildPart.solids
***** *****
Enums Enums
@ -62,17 +57,6 @@ Operations
.. autoclass:: Scale .. autoclass:: Scale
.. autoclass:: Split .. autoclass:: Split
.. _shape_list:
=========
ShapeList
=========
.. py:module:: build_common
.. autoclass:: ShapeList
:members:
********* *********
BuildLine BuildLine
********* *********
@ -155,18 +139,3 @@ Operations
.. autoclass:: Revolve .. autoclass:: Revolve
.. autoclass:: Section .. autoclass:: Section
.. autoclass:: Sweep .. autoclass:: Sweep
*****************
Geometric Objects
*****************
.. py:module:: build_common
:noindex:
.. _axis:
.. autoclass:: Axis
.. autoclass:: Rotation
*************
Shape Objects
*************

View file

@ -6,9 +6,9 @@ Cheat Sheet
.. card:: Stateful Contexts .. card:: Stateful Contexts
| :class:`~build_line.BuildLine` :class:`~build_part.BuildPart` :class:`~build_sketch.BuildSketch` | :class:`~build_line::BuildLine` :class:`~build_part::BuildPart` :class:`~build_sketch::BuildSketch`
| :class:`~build_common.GridLocations` :class:`~build_common.HexLocations` :class:`~build_common.Locations` :class:`~build_common.PolarLocations` | :class:`~build_common::GridLocations` :class:`~build_common::HexLocations` :class:`~build_common::Locations` :class:`~build_common::PolarLocations`
| :class:`~build_common.Workplanes` | :class:`~build_common::Workplanes`
.. card:: Objects .. card:: Objects
@ -16,43 +16,43 @@ Cheat Sheet
.. grid-item-card:: 1D - BuildLine .. grid-item-card:: 1D - BuildLine
| :class:`~build_generic.Add` | :class:`~build_generic::Add`
| :class:`~build_line.CenterArc` | :class:`~build_line::CenterArc`
| :class:`~build_line.Helix` | :class:`~build_line::Helix`
| :class:`~build_line.Line` | :class:`~build_line::Line`
| :class:`~build_line.PolarLine` | :class:`~build_line::PolarLine`
| :class:`~build_line.Polyline` | :class:`~build_line::Polyline`
| :class:`~build_line.RadiusArc` | :class:`~build_line::RadiusArc`
| :class:`~build_line.SagittaArc` | :class:`~build_line::SagittaArc`
| :class:`~build_line.Spline` | :class:`~build_line::Spline`
| :class:`~build_line.SagittaArc` | :class:`~build_line::SagittaArc`
| :class:`~build_line.TangentArc` | :class:`~build_line::TangentArc`
| :class:`~build_line.ThreePointArc` | :class:`~build_line::ThreePointArc`
.. grid-item-card:: 2D - BuildSketch .. grid-item-card:: 2D - BuildSketch
| :class:`~build_generic.Add` | :class:`~build_generic::Add`
| :class:`~build_sketch.Circle` | :class:`~build_sketch::Circle`
| :class:`~build_sketch.Ellipse` | :class:`~build_sketch::Ellipse`
| :class:`~build_sketch.Polygon` | :class:`~build_sketch::Polygon`
| :class:`~build_sketch.Rectangle` | :class:`~build_sketch::Rectangle`
| :class:`~build_sketch.RegularPolygon` | :class:`~build_sketch::RegularPolygon`
| :class:`~build_sketch.SlotArc` | :class:`~build_sketch::SlotArc`
| :class:`~build_sketch.SlotCenterPoint` | :class:`~build_sketch::SlotCenterPoint`
| :class:`~build_sketch.SlotCenterToCenter` | :class:`~build_sketch::SlotCenterToCenter`
| :class:`~build_sketch.SlotOverall` | :class:`~build_sketch::SlotOverall`
| :class:`~build_sketch.Text` | :class:`~build_sketch::Text`
| :class:`~build_sketch.Trapezoid` | :class:`~build_sketch::Trapezoid`
.. grid-item-card:: 3D - BuildPart .. grid-item-card:: 3D - BuildPart
| :class:`~build_generic.Add` | :class:`~build_generic::Add`
| :class:`~build_part.Box` | :class:`~build_part::Box`
| :class:`~build_part.Cone` | :class:`~build_part::Cone`
| :class:`~build_part.Cylinder` | :class:`~build_part::Cylinder`
| :class:`~build_part.Sphere` | :class:`~build_part::Sphere`
| :class:`~build_part.Torus` | :class:`~build_part::Torus`
| :class:`~build_part.Wedge` | :class:`~build_part::Wedge`
.. card:: Operations .. card:: Operations
@ -60,37 +60,37 @@ Cheat Sheet
.. grid-item-card:: 1D - BuildLine .. grid-item-card:: 1D - BuildLine
| :class:`~build_generic.BoundingBox` | :class:`~build_generic::BoundingBox`
| :class:`~build_sketch.BuildFace` | :class:`~build_sketch::BuildFace`
| :class:`~build_sketch.BuildHull` | :class:`~build_sketch::BuildHull`
| :class:`~build_generic.Chamfer` | :class:`~build_generic::Chamfer`
| :class:`~build_generic.Mirror` | :class:`~build_generic::Mirror`
| :class:`~build_generic.Offset` | :class:`~build_generic::Offset`
| :class:`~build_generic.Scale` | :class:`~build_generic::Scale`
| :class:`~build_generic.Split` | :class:`~build_generic::Split`
.. grid-item-card:: 2D - BuildSketch .. grid-item-card:: 2D - BuildSketch
| :class:`~build_generic.Fillet` | :class:`~build_generic::Fillet`
| :class:`~build_generic.Mirror` | :class:`~build_generic::Mirror`
| :class:`~build_generic.Offset` | :class:`~build_generic::Offset`
| :class:`~build_generic.Scale` | :class:`~build_generic::Scale`
| :class:`~build_generic.Split` | :class:`~build_generic::Split`
.. grid-item-card:: 3D - BuildPart .. grid-item-card:: 3D - BuildPart
| :class:`~build_part.CounterBoreHole` | :class:`~build_part::CounterBoreHole`
| :class:`~build_part.CounterSinkHole` | :class:`~build_part::CounterSinkHole`
| :class:`~build_part.Extrude` | :class:`~build_part::Extrude`
| :class:`~build_part.Hole` | :class:`~build_part::Hole`
| :class:`~build_part.Loft` | :class:`~build_part::Loft`
| :class:`~build_generic.Fillet` | :class:`~build_generic::Fillet`
| :class:`~build_generic.Mirror` | :class:`~build_generic::Mirror`
| :class:`~build_generic.Offset` | :class:`~build_generic::Offset`
| :class:`~build_part.Revolve` | :class:`~build_part::Revolve`
| :class:`~build_generic.Scale` | :class:`~build_generic::Scale`
| :class:`~build_part.Section` | :class:`~build_part::Section`
| :class:`~build_generic.Split` | :class:`~build_generic::Split`
.. card:: Selectors .. card:: Selectors
@ -98,69 +98,69 @@ Cheat Sheet
.. grid-item-card:: 1D - BuildLine .. grid-item-card:: 1D - BuildLine
| :meth:`~build_common.Builder.vertices` | :meth:`~build_common::Builder.vertices`
| :meth:`~build_common.Builder.edges` | :meth:`~build_common::Builder.edges`
| :meth:`~build_common.Builder.wires` | :meth:`~build_common::Builder.wires`
.. grid-item-card:: 2D - BuildSketch .. grid-item-card:: 2D - BuildSketch
| :meth:`~build_common.Builder.vertices` | :meth:`~build_common::Builder.vertices`
| :meth:`~build_common.Builder.edges` | :meth:`~build_common::Builder.edges`
| :meth:`~build_common.Builder.wires` | :meth:`~build_common::Builder.wires`
| :meth:`~build_common.Builder.faces` | :meth:`~build_common::Builder.faces`
.. grid-item-card:: 3D - BuildPart .. grid-item-card:: 3D - BuildPart
| :meth:`~build_common.Builder.vertices` | :meth:`~build_common::Builder.vertices`
| :meth:`~build_common.Builder.edges` | :meth:`~build_common::Builder.edges`
| :meth:`~build_common.Builder.wires` | :meth:`~build_common::Builder.wires`
| :meth:`~build_common.Builder.faces` | :meth:`~build_common::Builder.faces`
| :meth:`~build_part.BuildPart.solids` | :meth:`~build_part::BuildPart.solids`
.. card:: Selector Operators .. card:: Selector Operators
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| Operator | Operand | Method | | Operator | Operand | Method |
+==========+============================================================+====================================================+ +==========+==============================================================+====================================================+
| > | :class:`~build_common.SortBy`, :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.sort_by` | | > | :class:`~build_enums::SortBy`, :class:`~build_common::Axis` | :meth:`~direct_api::ShapeList.sort_by` |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| < | :class:`~build_common.SortBy`, :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.sort_by` | | < | :class:`~build_enums::SortBy`, :class:`~build_common::Axis` | :meth:`~direct_api::ShapeList.sort_by` |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| >> | :class:`~build_common.SortBy`, :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.sort_by`\[-1\] | | >> | :class:`~build_enums::SortBy`, :class:`~build_common::Axis` | :meth:`~direct_api::ShapeList.sort_by`\[-1\] |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| << | :class:`~build_common.SortBy`, :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.sort_by`\[0\] | | << | :class:`~build_enums::SortBy`, :class:`~build_common::Axis` | :meth:`~direct_api::ShapeList.sort_by`\[0\] |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| % | :class:`~build_common.GeomType` | :meth:`~build_common.ShapeList.filter_by_type` | | % | :class:`~build_enums::GeomType` | :meth:`~direct_api::ShapeList.filter_by_type` |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| \| | :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.filter_by_axis` | | \| | :class:`~direct_api::Axis` | :meth:`~direct_api::ShapeList.filter_by_axis` |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| [] | | python indexing / slicing | | [] | | python indexing / slicing |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
| | :class:`~build_common.Axis` | :meth:`~build_common.ShapeList.filter_by_position` | | | :class:`~direct_api::Axis` | :meth:`~direct_api::ShapeList.filter_by_position` |
+----------+------------------------------------------------------------+----------------------------------------------------+ +----------+--------------------------------------------------------------+----------------------------------------------------+
.. card:: Enums .. card:: Enums
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.FontStyle` | REGULAR, BOLD, ITALIC | | :class:`~build_enums::FontStyle` | REGULAR, BOLD, ITALIC |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.GeomType` | BEZIER, BSPLINE, CIRCLE, CONE, CYLINDER, ELLIPSE, EXTRUSION, HYPERBOLA, LINE, OFFSET, OTHER, PARABOLA, PLANE, REVOLUTION, SPHERE, TORUS | | :class:`~build_enums::GeomType` | BEZIER, BSPLINE, CIRCLE, CONE, CYLINDER, ELLIPSE, EXTRUSION, HYPERBOLA, LINE, OFFSET, OTHER, PARABOLA, PLANE, REVOLUTION, SPHERE, TORUS |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Halign` | CENTER, LEFT, RIGHT | | :class:`~build_enums::Halign` | CENTER, LEFT, RIGHT |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Keep` | TOP, BOTTOM, BOTH | | :class:`~build_enums::Keep` | TOP, BOTTOM, BOTH |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Kind` | ARC, INTERSECTION, TANGENT | | :class:`~build_enums::Kind` | ARC, INTERSECTION, TANGENT |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Mode` | ADD, SUBTRACT, INTERSECT, REPLACE, PRIVATE | | :class:`~build_enums::Mode` | ADD, SUBTRACT, INTERSECT, REPLACE, PRIVATE |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Select` | ALL, LAST | | :class:`~build_enums::Select` | ALL, LAST |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.SortBy` | LENGTH, RADIUS, AREA, VOLUME, DISTANCE | | :class:`~build_enums::SortBy` | LENGTH, RADIUS, AREA, VOLUME, DISTANCE |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Transition` | RIGHT, ROUND, TRANSFORMED | | :class:`~build_enums::Transition` | RIGHT, ROUND, TRANSFORMED |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Until` | NEXT, LAST | | :class:`~build_enums::Until` | NEXT, LAST |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| :class:`~build_common.Valign` | CENTER, TOP, BOTTOM | | :class:`~build_enums::Valign` | CENTER, TOP, BOTTOM |
+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+

View file

@ -44,7 +44,7 @@ extensions = [
"sphinx.ext.autodoc", "sphinx.ext.autodoc",
"sphinx_autodoc_typehints", "sphinx_autodoc_typehints",
"sphinx.ext.doctest", "sphinx.ext.doctest",
"sphinx_design" "sphinx_design",
] ]
# Napoleon settings # Napoleon settings
@ -69,10 +69,10 @@ autodoc_typehints = ["signature"]
autodoc_default_options = { autodoc_default_options = {
"members": True, "members": True,
"undoc-members": True, "undoc-members": True,
"member-order": "bysource", "member-order": "alphabetical",
} }
autodoc_mock_imports = ["cadquery", "pkg_resources", "OCP"] # autodoc_mock_imports = ["OCP"]
# Sphinx settings # Sphinx settings
add_module_names = False add_module_names = False

BIN
docs/conicalProjection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
docs/flatProjection.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

View file

@ -38,7 +38,7 @@ used in CadQuery 2.x.
Overview Overview
######## ########
build123d uses the standard python context manager - e.g. the `with` statement often used when build123d uses the standard python context manager - e.g. the ``with`` statement often used when
working with files - as a builder of the object under construction. Once the object is complete working with files - as a builder of the object under construction. Once the object is complete
it can be extracted from the builders and used in other ways: for example exported as a STEP it can be extracted from the builders and used in other ways: for example exported as a STEP
file or used in an Assembly. There are three builders available: file or used in an Assembly. There are three builders available:
@ -64,8 +64,8 @@ The three builders work together in a hierarchy as follows:
... ...
... ...
where `my_line` will be added to `my_sketch` once the line is complete and `my_sketch` will be where ``my_line`` will be added to ``my_sketch`` once the line is complete and ``my_sketch`` will be
added to `my_part` once the sketch is complete. added to ``my_part`` once the sketch is complete.
As an example, consider the design of a simple bearing pillow block: As an example, consider the design of a simple bearing pillow block:
@ -87,6 +87,7 @@ Table Of Contents
tutorials.rst tutorials.rst
advantages.rst advantages.rst
api_reference.rst api_reference.rst
direct_api_reference.rst
================== ==================
Indices and tables Indices and tables

View file

@ -149,10 +149,13 @@ to retrieve the global locations relative to the current workplane(s) as follows
Each of the contexts are described in detail below: Each of the contexts are described in detail below:
.. autoclass:: Locations .. py:module:: build_common
.. autoclass:: GridLocations :noindex:
.. autoclass:: HexLocations
.. autoclass:: PolarLocations .. autoclass:: build_common::Locations
.. autoclass:: build_common::GridLocations
.. autoclass:: build_common::HexLocations
.. autoclass:: build_common::PolarLocations
**************** ****************
Operation Inputs Operation Inputs

BIN
docs/projectText.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View file

@ -1,8 +1,8 @@
# Defining the exact version will make sure things don't break # Defining the exact version will make sure things don't break
sphinx==4.2.0 sphinx==5.3.0
sphinx_rtd_theme==1.0.0 sphinx_rtd_theme
readthedocs-sphinx-search==0.1.1 readthedocs-sphinx-search
sphinx_autodoc_typehints==1.12.0 sphinx_autodoc_typehints==1.12.0
-e git+https://github.com/gumyr/cq_warehouse.git#egg=cq_warehouse --pre cadquery-ocp
-e git+https://github.com/gumyr/build123d.git#egg=build123d -e git+https://github.com/gumyr/build123d.git#egg=build123d
sphinx_design sphinx_design

View file

@ -48,13 +48,13 @@ The following tables describes the build123d selectors:
The operand types are: Axis, SortBy, and GeomType. An Axis is a base object with an origin and a The operand types are: Axis, SortBy, and GeomType. An Axis is a base object with an origin and a
direction with several predefined values such as ``Axis.X``, ``Axis.Y``, and ``Axis.Z``; however, direction with several predefined values such as ``Axis.X``, ``Axis.Y``, and ``Axis.Z``; however,
any Axis could be used as an operand (e.g. ``Axis((1,2,3),(0.5,0,-0.5))`` is valid) - see any Axis could be used as an operand (e.g. ``Axis((1,2,3),(0.5,0,-0.5))`` is valid) - see
:class:`~build_common.Axis` for a complete description. SortBy and GeomType are python :class:`~direct_api::Axis` for a complete description. SortBy and GeomType are python
Enum class described here: Enum class described here:
:class:`~build_common.GeomType` :class:`~build_enums::GeomType`
BEZIER, BSPLINE, CIRCLE, CONE, CYLINDER, ELLIPSE, EXTRUSION, HYPERBOLA, LINE, OFFSET, OTHER, BEZIER, BSPLINE, CIRCLE, CONE, CYLINDER, ELLIPSE, EXTRUSION, HYPERBOLA, LINE, OFFSET, OTHER,
PARABOLA, PLANE, REVOLUTION, SPHERE, TORUS PARABOLA, PLANE, REVOLUTION, SPHERE, TORUS
:class:`~build_common.SortBy` :class:`~build_enums::SortBy`
LENGTH, RADIUS, AREA, VOLUME, DISTANCE LENGTH, RADIUS, AREA, VOLUME, DISTANCE
@ -64,7 +64,7 @@ ShapeList Class
The builders include methods to extract Edges, Faces, Solids, Vertices, or Wires from the objects The builders include methods to extract Edges, Faces, Solids, Vertices, or Wires from the objects
they are building. All of these methods return objects of a subclass of `list`, a `ShapeList` with they are building. All of these methods return objects of a subclass of `list`, a `ShapeList` with
custom filtering and sorting methods and operations as follows. The full ShapeList API is can be custom filtering and sorting methods and operations as follows. The full ShapeList API is can be
found in :ref:`API Reference/ShapeList <shape_list>`. found in :class:`~direct_api::ShapeList`.
Custom Sorting and Filtering Custom Sorting and Filtering
---------------------------- ----------------------------

BIN
docs/slotted_cylinder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
docs/thickenFace.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View file

@ -53,8 +53,7 @@ Step 3a: Extract Faces from a part
The first sub-step is the extraction of all of the Faces from the part that we're The first sub-step is the extraction of all of the Faces from the part that we're
building. The ``BuildPart`` instance was assigned the identifier ``example`` so building. The ``BuildPart`` instance was assigned the identifier ``example`` so
``example.faces()`` will extract all of the Faces from that part into a custom ``example.faces()`` will extract all of the Faces from that part into a custom
python ``list`` - a ``ShapeList`` (see python ``list`` - a ``ShapeList`` (see :class:`~direct_api::ShapeList` for a full description).
:ref:`API Reference/ShapeList <shape_list>` for a full description).
Step 3b: Get top Face Step 3b: Get top Face
--------------------- ---------------------

View file

@ -1,5 +1,6 @@
import build123d as bd import build123d as bd
from cadquery import exporters
# from cadquery import exporters
with bd.BuildPart() as bp: with bd.BuildPart() as bp:
bd.Box(3, 3, 3) bd.Box(3, 3, 3)

View file

@ -25,7 +25,6 @@ license:
limitations under the License. limitations under the License.
""" """
from build123d import * from build123d import *
import cadquery as cq
with BuildSketch() as logo_text: with BuildSketch() as logo_text:
Text("123d", fontsize=10, valign=Valign.BOTTOM) Text("123d", fontsize=10, valign=Valign.BOTTOM)
@ -68,27 +67,27 @@ with BuildLine() as extension_lines:
Add(*arrow_left.line) Add(*arrow_left.line)
with Locations(l2 @ 0.5): with Locations(l2 @ 0.5):
Add(*arrow_left.line, rotation=180.0) Add(*arrow_left.line, rotation=180.0)
Line(l1 @ 0.5, l1 @ 0.5 + cq.Vector(dim_line_length, 0)) Line(l1 @ 0.5, l1 @ 0.5 + Vector(dim_line_length, 0))
Line(l2 @ 0.5, l2 @ 0.5 - cq.Vector(dim_line_length, 0)) Line(l2 @ 0.5, l2 @ 0.5 - Vector(dim_line_length, 0))
# Precisely center the build Faces # Precisely center the build Faces
with BuildSketch() as build: with BuildSketch() as build:
with Locations( with Locations(
(l1 @ 0.5 + l2 @ 0.5) / 2 (l1 @ 0.5 + l2 @ 0.5) / 2
- cq.Vector((build_vertices[-1].X + build_vertices[0].X) / 2, 0) - Vector((build_vertices[-1].X + build_vertices[0].X) / 2, 0)
): ):
Add(build_text.sketch) Add(build_text.sketch)
logo = cq.Assembly(None, name="logo") # logo = Assembly(None, name="logo")
logo.add(one.wires()[0], name="one") # logo.add(one.wires()[0], name="one")
logo.add(two.sketch, name="two") # logo.add(two.sketch, name="two")
logo.add(three_d.part, name="three_d") # logo.add(three_d.part, name="three_d")
for line in extension_lines.line: # for line in extension_lines.line:
logo.add(line) # logo.add(line)
logo.add(build.sketch, name="build") # logo.add(build.sketch, name="build")
if False: if False:
logo.save("logo.step") logo.save("logo.step")
cq.exporters.export( exporters.export(
logo.toCompound(), logo.toCompound(),
"logo.svg", "logo.svg",
opt={ opt={

View file

@ -1,7 +1,7 @@
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: build123d Name: build123d
Version: 0.1.0 Version: 0.1.0
Summary: An cadquery prototype programming library Summary: A CAD programming library
Home-page: https://github.com/gumyr/build123d Home-page: https://github.com/gumyr/build123d
Author: Gumyr Author: Gumyr
Author-email: gumyr9@gmail.com Author-email: gumyr9@gmail.com

View file

@ -2,27 +2,19 @@ README.md
pyproject.toml pyproject.toml
setup.cfg setup.cfg
src/build123d/__init__.py src/build123d/__init__.py
src/build123d/abstract_operations.py
src/build123d/build_common.py src/build123d/build_common.py
src/build123d/build_enums.py
src/build123d/build_generic.py src/build123d/build_generic.py
src/build123d/build_line.py src/build123d/build_line.py
src/build123d/build_part.py src/build123d/build_part.py
src/build123d/build_sketch.py src/build123d/build_sketch.py
src/build123d/builder_base_class.py
src/build123d/direct_api.py
src/build123d/geom.py
src/build123d/hull.py src/build123d/hull.py
src/build123d/jupyter_tools.py
src/build123d.egg-info/PKG-INFO src/build123d.egg-info/PKG-INFO
src/build123d.egg-info/SOURCES.txt src/build123d.egg-info/SOURCES.txt
src/build123d.egg-info/dependency_links.txt src/build123d.egg-info/dependency_links.txt
src/build123d.egg-info/top_level.txt src/build123d.egg-info/top_level.txt
src/build123d/occ_impl/__init__.py
src/build123d/occ_impl/geom.py
src/build123d/occ_impl/jupyter_tools.py
src/build123d/occ_impl/shapes.py
src/build123d/occ_impl/exporters/__init__.py
src/build123d/occ_impl/exporters/amf.py
src/build123d/occ_impl/exporters/assembly.py
src/build123d/occ_impl/exporters/dxf.py
src/build123d/occ_impl/exporters/json.py
src/build123d/occ_impl/exporters/svg.py
src/build123d/occ_impl/exporters/utils.py
src/build123d/occ_impl/exporters/vtk.py
src/build123d/occ_impl/importers/__init__.py
src/build123d/occ_impl/importers/dxf.py

View file

@ -1,10 +1,10 @@
from .build_common import * from build123d.build_common import *
from .build_line import * from build123d.build_line import *
from .build_sketch import * from build123d.build_sketch import *
from .build_part import * from build123d.build_part import *
from .build_generic import * from build123d.build_generic import *
from .abstract_operations import * from build123d.abstract_operations import *
from .direct_api import * from build123d.direct_api import *
__all__ = [ __all__ = [
# Measurement Units # Measurement Units

View file

@ -8,10 +8,6 @@ date: July 12th 2022
desc: desc:
This python module is a library used to build 3D parts. This python module is a library used to build 3D parts.
TODO:
- Update Vector so it can be initialized with a Vertex or Location
- Update VectorLike to include a Vertex and Location
license: license:
Copyright 2022 Gumyr Copyright 2022 Gumyr
@ -33,11 +29,10 @@ from __future__ import annotations
import contextvars import contextvars
from itertools import product from itertools import product
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from math import radians, sqrt, pi from math import sqrt, pi
from typing import Iterable, Union from typing import Iterable, Union
from enum import Enum, auto
import logging import logging
from .build_enums import ( from build123d.build_enums import (
Select, Select,
Kind, Kind,
Keep, Keep,
@ -51,7 +46,7 @@ from .build_enums import (
GeomType, GeomType,
) )
from .direct_api import ( from build123d.direct_api import (
Edge, Edge,
Wire, Wire,
Vector, Vector,
@ -67,11 +62,6 @@ from .direct_api import (
ShapeList, ShapeList,
) )
from OCP.gp import gp_Pnt, gp_Ax1, gp_Dir, gp_Trsf
from OCP.BRepTools import BRepTools
from OCP.TopAbs import TopAbs_ShapeEnum
from OCP.TopoDS import TopoDS_Iterator
# Create a build123d logger to distinguish these logs from application logs. # Create a build123d logger to distinguish these logs from application logs.
# If the user doesn't configure logging, all build123d logs will be discarded. # If the user doesn't configure logging, all build123d logs will be discarded.
logging.getLogger("build123d").addHandler(logging.NullHandler()) logging.getLogger("build123d").addHandler(logging.NullHandler())
@ -96,53 +86,6 @@ IN = 25.4 * MM
FT = 12 * IN FT = 12 * IN
def validate_inputs(validating_class, builder_context, objects: Shape = None):
"""Validate that objects/operations and parameters apply"""
if not objects:
objects = []
# Check for builder / object matches
if not builder_context:
builder_dict = {
"build123d.build_line": "BuildLine()",
"build123d.build_sketch": "BuildSketch()",
"build123d.build_part": "BuildPart()",
"build123d.build_generic": "BuildLine() | BuildSketch() | BuildPart()",
}
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't have an active builder, "
f"did you miss a with {builder_dict[validating_class.__module__]}:"
)
if not (
validating_class.__module__
in [builder_context.__module__, "build123d.build_generic"]
):
raise RuntimeError(
f"{builder_context.__class__.__name__} doesn't have a "
f"{validating_class.__class__.__name__} object or operation"
)
# Check for valid object inputs
for obj in objects:
if obj is None:
pass
elif isinstance(obj, Builder):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept Builders as input,"
f" did you intend <{obj.__class__.__name__}>.{obj._obj_name}?"
)
elif isinstance(obj, list):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept {type(obj).__name__},"
f" did you intend *{obj}?"
)
elif not isinstance(obj, Shape):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept {type(obj).__name__},"
f" did you intend <keyword>={obj}?"
)
class Builder(ABC): class Builder(ABC):
"""Builder """Builder
@ -642,3 +585,50 @@ class Workplanes(WorkplaneList):
else: else:
raise ValueError(f"Workplanes does not accept {type(obj)}") raise ValueError(f"Workplanes does not accept {type(obj)}")
super().__init__(self.workplanes) super().__init__(self.workplanes)
def validate_inputs(validating_class, builder_context, objects: Shape = None):
"""Validate that objects/operations and parameters apply"""
if not objects:
objects = []
# Check for builder / object matches
if not builder_context:
builder_dict = {
"build123d.build_line": "BuildLine()",
"build123d.build_sketch": "BuildSketch()",
"build123d.build_part": "BuildPart()",
"build123d.build_generic": "BuildLine() | BuildSketch() | BuildPart()",
}
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't have an active builder, "
f"did you miss a with {builder_dict[validating_class.__module__]}:"
)
if not (
validating_class.__module__
in [builder_context.__module__, "build123d.build_generic"]
):
raise RuntimeError(
f"{builder_context.__class__.__name__} doesn't have a "
f"{validating_class.__class__.__name__} object or operation"
)
# Check for valid object inputs
for obj in objects:
if obj is None:
pass
elif isinstance(obj, Builder):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept Builders as input,"
f" did you intend <{obj.__class__.__name__}>.{obj._obj_name}?"
)
elif isinstance(obj, list):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept {type(obj).__name__},"
f" did you intend *{obj}?"
)
elif not isinstance(obj, Shape):
raise RuntimeError(
f"{validating_class.__class__.__name__} doesn't accept {type(obj).__name__},"
f" did you intend <keyword>={obj}?"
)

View file

@ -28,8 +28,8 @@ license:
""" """
from typing import Union from typing import Union
import logging import logging
from .build_enums import Mode, Kind, Keep from build123d.build_enums import Mode, Kind, Keep
from .direct_api import ( from build123d.direct_api import (
Edge, Edge,
Wire, Wire,
Vector, Vector,

View file

@ -28,8 +28,8 @@ license:
import inspect import inspect
from math import sin, cos, radians, sqrt from math import sin, cos, radians, sqrt
from typing import Union, Iterable from typing import Union, Iterable
from .build_enums import Select, Mode from build123d.build_enums import Select, Mode
from .direct_api import ( from build123d.direct_api import (
Edge, Edge,
Wire, Wire,
Vector, Vector,
@ -40,7 +40,7 @@ from .direct_api import (
Face, Face,
Plane, Plane,
) )
from .build_common import Builder, logger, validate_inputs from build123d.build_common import Builder, logger, validate_inputs
class BuildLine(Builder): class BuildLine(Builder):

View file

@ -34,8 +34,8 @@ from warnings import warn
from math import radians, tan, sqrt from math import radians, tan, sqrt
from typing import Union, Iterable from typing import Union, Iterable
from OCP.gp import gp_Pln, gp_Lin from OCP.gp import gp_Pln, gp_Lin
from .build_enums import Mode, Until, Select, Transition from build123d.build_enums import Mode, Until, Select, Transition
from .direct_api import ( from build123d.direct_api import (
Edge, Edge,
Wire, Wire,
Vector, Vector,
@ -53,7 +53,7 @@ from .direct_api import (
Shell, Shell,
) )
from .build_common import ( from build123d.build_common import (
Builder, Builder,
logger, logger,
validate_inputs, validate_inputs,
@ -669,12 +669,7 @@ class Revolve(Compound):
"axis must be in the same plane as the face to revolve" "axis must be in the same plane as the face to revolve"
) )
new_solid = Solid.revolve( new_solid = Solid.revolve(profile, angle, axis)
profile,
angle,
axis.position,
axis.position + axis.direction,
)
new_solids.extend( new_solids.extend(
[ [
new_solid.moved(location) new_solid.moved(location)

View file

@ -41,9 +41,9 @@ license:
import inspect import inspect
from math import pi, sin, cos, tan, radians from math import pi, sin, cos, tan, radians
from typing import Union from typing import Union
from cadquery.hull import find_hull from build123d.hull import find_hull
from .build_enums import Mode, FontStyle, Halign, Valign from build123d.build_enums import Mode, FontStyle, Halign, Valign
from .direct_api import ( from build123d.direct_api import (
Edge, Edge,
Wire, Wire,
Vector, Vector,
@ -55,7 +55,7 @@ from .direct_api import (
Plane, Plane,
Axis, Axis,
) )
from .build_common import ( from build123d.build_common import (
Builder, Builder,
logger, logger,
validate_inputs, validate_inputs,

View file

@ -1,9 +1,15 @@
"""
TODO:
- Update Vector so it can be initialized with a Vertex or Location
- Update VectorLike to include a Vertex and Location
"""
from __future__ import annotations from __future__ import annotations
import math from math import pi, sqrt, inf, radians
import warnings import warnings
import logging import logging
import sys
import copy import copy
import warnings
from typing import ( from typing import (
Optional, Optional,
Tuple, Tuple,
@ -18,25 +24,24 @@ from typing import (
TypeVar, TypeVar,
cast as tcast, cast as tcast,
) )
from .build_enums import ( from typing_extensions import Literal
Select, from io import BytesIO
Kind, from build123d.build_enums import (
Keep,
Mode,
Transition,
FontStyle,
Halign,
Valign,
Until,
SortBy, SortBy,
GeomType, GeomType,
PositionMode, PositionMode,
FrameMethod, FrameMethod,
Direction, Direction,
CenterOf, CenterOf,
Kind,
Transition,
FontStyle,
Halign,
Valign,
GeomType,
AngularDirection,
) )
from typing_extensions import Literal
from io import BytesIO
from vtkmodules.vtkCommonDataModel import vtkPolyData from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkFiltersCore import vtkTriangleFilter, vtkPolyDataNormals from vtkmodules.vtkFiltersCore import vtkTriangleFilter, vtkPolyDataNormals
@ -279,20 +284,6 @@ from OCP.BRepMesh import BRepMesh_IncrementalMesh
from OCP.TopoDS import TopoDS_Shape from OCP.TopoDS import TopoDS_Shape
from OCP.TopLoc import TopLoc_Location from OCP.TopLoc import TopLoc_Location
from math import pi, sqrt, inf
import warnings
from .build_enums import (
Select,
Kind,
Keep,
Transition,
FontStyle,
Halign,
Valign,
GeomType,
AngularDirection,
)
TOLERANCE = 1e-6 TOLERANCE = 1e-6
TOL = 1e-2 TOL = 1e-2
@ -677,7 +668,7 @@ class Vector:
""" """
return Vector( return Vector(
gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OX_s(), math.pi * angle / 180) gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OX_s(), pi * angle / 180)
) )
def rotate_y(self, angle: float) -> Vector: def rotate_y(self, angle: float) -> Vector:
@ -692,7 +683,7 @@ class Vector:
""" """
return Vector( return Vector(
gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OY_s(), math.pi * angle / 180) gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OY_s(), pi * angle / 180)
) )
def rotate_z(self, angle: float) -> Vector: def rotate_z(self, angle: float) -> Vector:
@ -707,7 +698,7 @@ class Vector:
""" """
return Vector( return Vector(
gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OZ_s(), math.pi * angle / 180) gp_Vec(self.X, self.Y, self.Z).Rotated(gp.OZ_s(), pi * angle / 180)
) )
@ -812,7 +803,7 @@ class Axis:
bool: axes are coaxial bool: axes are coaxial
""" """
return self.wrapped.IsCoaxial( return self.wrapped.IsCoaxial(
other.wrapped, angular_tolerance * (math.pi / 180), linear_tolerance other.wrapped, angular_tolerance * (pi / 180), linear_tolerance
) )
def is_normal(self, other: Axis, angular_tolerance: float = 1e-5) -> bool: def is_normal(self, other: Axis, angular_tolerance: float = 1e-5) -> bool:
@ -828,7 +819,7 @@ class Axis:
Returns: Returns:
bool: axes are normal bool: axes are normal
""" """
return self.wrapped.IsNormal(other.wrapped, angular_tolerance * (math.pi / 180)) return self.wrapped.IsNormal(other.wrapped, angular_tolerance * (pi / 180))
def is_opposite(self, other: Axis, angular_tolerance: float = 1e-5) -> bool: def is_opposite(self, other: Axis, angular_tolerance: float = 1e-5) -> bool:
"""are axes opposite """are axes opposite
@ -844,9 +835,7 @@ class Axis:
Returns: Returns:
bool: axes are opposite bool: axes are opposite
""" """
return self.wrapped.IsOpposite( return self.wrapped.IsOpposite(other.wrapped, angular_tolerance * (pi / 180))
other.wrapped, angular_tolerance * (math.pi / 180)
)
def is_parallel(self, other: Axis, angular_tolerance: float = 1e-5) -> bool: def is_parallel(self, other: Axis, angular_tolerance: float = 1e-5) -> bool:
"""are axes parallel """are axes parallel
@ -862,9 +851,7 @@ class Axis:
Returns: Returns:
bool: axes are parallel bool: axes are parallel
""" """
return self.wrapped.IsParallel( return self.wrapped.IsParallel(other.wrapped, angular_tolerance * (pi / 180))
other.wrapped, angular_tolerance * (math.pi / 180)
)
def angle_between(self, other: Axis) -> float: def angle_between(self, other: Axis) -> float:
"""calculate angle between axes """calculate angle between axes
@ -1120,7 +1107,7 @@ class Location:
else: else:
t, ax, angle = args t, ax, angle = args
transform.SetRotation( transform.SetRotation(
gp_Ax1(Vector().to_pnt(), Vector(ax).to_dir()), angle * math.pi / 180.0 gp_Ax1(Vector().to_pnt(), Vector(ax).to_dir()), angle * pi / 180.0
) )
transform.SetTranslationPart(Vector(t).wrapped) transform.SetTranslationPart(Vector(t).wrapped)
@ -1160,9 +1147,7 @@ class Location:
Location as String Location as String
""" """
position_str = ", ".join((f"{v:.2f}" for v in self.to_tuple()[0])) position_str = ", ".join((f"{v:.2f}" for v in self.to_tuple()[0]))
orientation_str = ", ".join( orientation_str = ", ".join((f"{180*v/pi:.2f}" for v in self.to_tuple()[1]))
(f"{180*v/math.pi:.2f}" for v in self.to_tuple()[1])
)
return f"(p=({position_str}), o=({orientation_str}))" return f"(p=({position_str}), o=({orientation_str}))"
def __str__(self): def __str__(self):
@ -1174,9 +1159,7 @@ class Location:
Location as String Location as String
""" """
position_str = ", ".join((f"{v:.2f}" for v in self.to_tuple()[0])) position_str = ", ".join((f"{v:.2f}" for v in self.to_tuple()[0]))
orientation_str = ", ".join( orientation_str = ", ".join((f"{180*v/pi:.2f}" for v in self.to_tuple()[1]))
(f"{180*v/math.pi:.2f}" for v in self.to_tuple()[1])
)
return f"Location: (position=({position_str}), orientation=({orientation_str}))" return f"Location: (position=({position_str}), orientation=({orientation_str}))"
def position(self): def position(self):
@ -1212,17 +1195,11 @@ class Rotation(Location):
# Compute rotation matrix. # Compute rotation matrix.
rot_x = gp_Trsf() rot_x = gp_Trsf()
rot_x.SetRotation( rot_x.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), radians(about_x))
gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(1, 0, 0)), math.radians(about_x)
)
rot_y = gp_Trsf() rot_y = gp_Trsf()
rot_y.SetRotation( rot_y.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0)), radians(about_y))
gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 1, 0)), math.radians(about_y)
)
rot_z = gp_Trsf() rot_z = gp_Trsf()
rot_z.SetRotation( rot_z.SetRotation(gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), radians(about_z))
gp_Ax1(gp_Pnt(0, 0, 0), gp_Dir(0, 0, 1)), math.radians(about_z)
)
super().__init__(Location(rot_x * rot_y * rot_z).wrapped) super().__init__(Location(rot_x * rot_y * rot_z).wrapped)
@ -1924,12 +1901,18 @@ class Shape:
def __init__(self, obj: TopoDS_Shape): def __init__(self, obj: TopoDS_Shape):
self.wrapped = downcast(obj) self.wrapped = downcast(obj)
self.for_construction = False self.for_construction: bool = False
# Helps identify this solid through the use of an ID # Helps identify this solid through the use of an ID
self.label = "" self.label: str = ""
def clean(self) -> Shape: def clean(self) -> Shape:
"""clean - remove internal edges""" """clean
Remove internal edges
Returns:
Shape: Original object with extraneous internal edges removed
"""
# Try BRepTools.RemoveInternals here # Try BRepTools.RemoveInternals here
upgrader = ShapeUpgrade_UnifySameDomain(self.wrapped, True, True, True) upgrader = ShapeUpgrade_UnifySameDomain(self.wrapped, True, True, True)
upgrader.AllowInternalEdges(False) upgrader.AllowInternalEdges(False)
@ -1979,25 +1962,25 @@ class Shape:
angular_tolerance: float = 0.1, angular_tolerance: float = 0.1,
ascii: bool = False, ascii: bool = False,
) -> bool: ) -> bool:
"""Exports a shape to a specified STL file. """Export STL
Exports a shape to a specified STL file.
Args: Args:
file_name: The path and file name to write the STL output to. file_name (str): The path and file name to write the STL output to.
tolerance: A linear deflection setting which limits the distance between a curve and its tessellation. tolerance (float, optional): A linear deflection setting which limits the distance
Setting this value too low will result in large meshes that can consume computing resources. between a curve and its tessellation. Setting this value too low will result in
Setting the value too high can result in meshes with a level of detail that is too low. large meshes that can consume computing resources. Setting the value too high can
Default is 1e-3, which is a good starting point for a range of cases. result in meshes with a level of detail that is too low. The default is a good
angular_tolerance: Angular deflection setting which limits the angle between subsequent segments in a polyline. Default is 0.1. starting point for a range of cases. Defaults to 1e-3.
ascii: Export the file as ASCII (True) or binary (False) STL format. Default is binary. angular_tolerance (float, optional): Angular deflection setting which limits the angle
file_name: str: between subsequent segments in a polyline. Defaults to 0.1.
tolerance: float: (Default value = 1e-3) ascii (bool, optional): Export the file as ASCII (True) or binary (False) STL format.
angular_tolerance: float: (Default value = 0.1) Defaults to False (binary).
ascii: bool: (Default value = False)
Returns: Returns:
bool: Success
""" """
mesh = BRepMesh_IncrementalMesh( mesh = BRepMesh_IncrementalMesh(
self.wrapped, tolerance, True, angular_tolerance self.wrapped, tolerance, True, angular_tolerance
) )
@ -3049,7 +3032,7 @@ class Shape:
Note that projection may result in text distortion depending on Note that projection may result in text distortion depending on
the shape at a position along the path. the shape at a position along the path.
.. image:: project_text.png .. image:: projectText.png
Args: Args:
txt: Text to be rendered txt: Text to be rendered
@ -3123,6 +3106,29 @@ class Shape:
Find the largest fillet radius for the given Shape and edges with a Find the largest fillet radius for the given Shape and edges with a
recursive binary search. recursive binary search.
Example:
max_fillet_radius = my_shape.max_fillet(shape_edges)
max_fillet_radius = my_shape.max_fillet(shape_edges, tolerance=0.5, max_iterations=8)
Args:
edge_list (Iterable[Edge]): a sequence of Edge objects, which must belong to this solid
tolerance (float, optional): maximum error from actual value. Defaults to 0.1.
max_iterations (int, optional): maximum number of recursive iterations. Defaults to 10.
Raises:
RuntimeError: failed to find the max value
ValueError: the provided Shape is invalid
Returns:
float: maximum fillet radius
"""
"""Find Maximum Fillet Size
Find the largest fillet radius for the given Shape and edges with a
recursive binary search.
Args: Args:
edge_list(Iterable[Edge]): a list of Edge objects, which must belong to this solid edge_list(Iterable[Edge]): a list of Edge objects, which must belong to this solid
tolerance(float, optional): maximum error from actual value. Defaults to 0.1. tolerance(float, optional): maximum error from actual value. Defaults to 0.1.
@ -3130,10 +3136,6 @@ class Shape:
Returns: Returns:
float: maximum fillet radius float: maximum fillet radius
As an example:
max_fillet_radius = my_shape.max_fillet(shape_edges)
or:
max_fillet_radius = my_shape.max_fillet(shape_edges, tolerance=0.5, max_iterations=8)
Raises: Raises:
RuntimeError: failed to find the max value RuntimeError: failed to find the max value
@ -3686,7 +3688,7 @@ class Plane:
# NB: this is not a geometric Vector # NB: this is not a geometric Vector
rotate = Vector(rotate) rotate = Vector(rotate)
# Convert to radians. # Convert to radians.
rotate = rotate.multiply(math.pi / 180.0) rotate = rotate.multiply(pi / 180.0)
# Compute rotation matrix. # Compute rotation matrix.
t1 = gp_Trsf() t1 = gp_Trsf()
@ -3957,7 +3959,7 @@ class Compound(Shape, Mixin3D):
position_on_path + face_bottom_center.X / path_length position_on_path + face_bottom_center.X / path_length
) )
wire_tangent = text_path.tangent_at(relative_position_on_wire) wire_tangent = text_path.tangent_at(relative_position_on_wire)
wire_angle = -180 * Vector(1, 0, 0).get_signed_angle(wire_tangent) / math.pi wire_angle = -180 * Vector(1, 0, 0).get_signed_angle(wire_tangent) / pi
wire_position = text_path.position_at(relative_position_on_wire) wire_position = text_path.position_at(relative_position_on_wire)
return orig_face.translate(wire_position - face_bottom_center).rotate( return orig_face.translate(wire_position - face_bottom_center).rotate(
@ -4386,19 +4388,17 @@ class Edge(Shape, Mixin1D):
def make_three_point_arc( def make_three_point_arc(
cls, v1: VectorLike, v2: VectorLike, v3: VectorLike cls, v1: VectorLike, v2: VectorLike, v3: VectorLike
) -> Edge: ) -> Edge:
"""Makes a three point arc through the provided points """Three Point Arc
Makes a three point arc through the provided points
Args: Args:
cls: param v1: start vector v1 (VectorLike): start point
v2: middle vector v2 (VectorLike): middle point
v3: end vector v3 (VectorLike): end point
v1: VectorLike:
v2: VectorLike:
v3: VectorLike:
Returns: Returns:
an edge object through the three points Edge: a circular arc through the three points
""" """
circle_geom = GC_MakeArcOfCircle( circle_geom = GC_MakeArcOfCircle(
Vector(v1).to_pnt(), Vector(v2).to_pnt(), Vector(v3).to_pnt() Vector(v1).to_pnt(), Vector(v2).to_pnt(), Vector(v3).to_pnt()
@ -4407,24 +4407,23 @@ class Edge(Shape, Mixin1D):
return cls(BRepBuilderAPI_MakeEdge(circle_geom).Edge()) return cls(BRepBuilderAPI_MakeEdge(circle_geom).Edge())
@classmethod @classmethod
def make_tangent_arc(cls, v1: VectorLike, v2: VectorLike, v3: VectorLike) -> Edge: def make_tangent_arc(
"""Makes a tangent arc from point v1, in the direction of v2 and ends at cls, start: VectorLike, tangent: VectorLike, end: VectorLike
v3. ) -> Edge:
"""Tangent Arc
Makes a tangent arc from point v1, in the direction of v2 and ends at v3.
Args: Args:
cls: param v1: start vector start (VectorLike): start point
v2: tangent vector tangent (VectorLike): start tangent
v3: end vector end (VectorLike): end point
v1: VectorLike:
v2: VectorLike:
v3: VectorLike:
Returns: Returns:
an edge Edge: circular arc
""" """
circle_geom = GC_MakeArcOfCircle( circle_geom = GC_MakeArcOfCircle(
Vector(v1).to_pnt(), Vector(v2).wrapped, Vector(v3).to_pnt() Vector(start).to_pnt(), Vector(tangent).wrapped, Vector(end).to_pnt()
).Value() ).Value()
return cls(BRepBuilderAPI_MakeEdge(circle_geom).Edge()) return cls(BRepBuilderAPI_MakeEdge(circle_geom).Edge())
@ -4931,22 +4930,18 @@ class Face(Shape):
Non-planar faces are thickened both towards and away from the center of the sphere. Non-planar faces are thickened both towards and away from the center of the sphere.
Args: Args:
depth: Amount to thicken face(s), can be positive or negative. depth (float): Amount to thicken face(s), can be positive or negative.
direction: The direction vector can be used to direction (Vector, optional): The direction vector can be used to
indicate which way is 'up', potentially flipping the face normal direction indicate which way is 'up', potentially flipping the face normal direction
such that many faces with different normals all go in the same direction such that many faces with different normals all go in the same direction
(direction need only be +/- 90 degrees from the face normal). Defaults to None. (direction need only be +/- 90 degrees from the face normal). Defaults to None.
depth: float:
direction: Vector: (Default value = None)
Returns:
: The resulting Solid object
Raises: Raises:
RuntimeError: Opencascade internal failures RuntimeError: Opencascade internal failures
Returns:
Solid: The resulting Solid object
""" """
# Check to see if the normal needs to be flipped # Check to see if the normal needs to be flipped
adjusted_depth = depth adjusted_depth = depth
if direction is not None: if direction is not None:
@ -5653,8 +5648,7 @@ class Solid(Shape, Mixin3D):
cls, cls,
section: Union[Face, Wire], section: Union[Face, Wire],
angle: float, angle: float,
axis_start: VectorLike, axis: Axis,
axis_end: VectorLike,
inner_wires: list[Wire] = [], inner_wires: list[Wire] = [],
) -> Solid: ) -> Solid:
"""Revolve """Revolve
@ -5664,8 +5658,7 @@ class Solid(Shape, Mixin3D):
Args: Args:
section (Union[Face,Wire]): cross section section (Union[Face,Wire]): cross section
angle (float): the angle to revolve through angle (float): the angle to revolve through
axis_start (VectorLike): the start point of the axis of rotation axis (Axis): rotation Axis
axis_end (VectorLike): the end point of the axis of rotation
inner_wires (list[Wire], optional): holes - only used if section is of type Wire. inner_wires (list[Wire], optional): holes - only used if section is of type Wire.
Defaults to []. Defaults to [].
@ -5677,12 +5670,9 @@ class Solid(Shape, Mixin3D):
else: else:
section_face = section section_face = section
v1 = Vector(axis_start)
v2 = Vector(axis_end)
v2 = v2 - v1
revol_builder = BRepPrimAPI_MakeRevol( revol_builder = BRepPrimAPI_MakeRevol(
section_face.wrapped, section_face.wrapped,
gp_Ax1(v1.to_pnt(), v2.to_dir()), axis.wrapped,
angle * DEG2RAD, angle * DEG2RAD,
True, True,
) )

View file

@ -2,9 +2,7 @@ from typing import List, Tuple, Union, Iterable, Set
from math import pi, sin, cos, atan2, sqrt, inf, degrees from math import pi, sin, cos, atan2, sqrt, inf, degrees
from numpy import lexsort, argmin, argmax from numpy import lexsort, argmin, argmax
from .occ_impl.shapes import Edge, Wire from build123d import Edge, Wire, Vector
from .occ_impl.geom import Vector
""" """
Convex hull for line segments and circular arcs based on Convex hull for line segments and circular arcs based on
@ -91,20 +89,20 @@ def convert_and_validate(edges: Iterable[Edge]) -> Tuple[List[Arc], List[Point]]
points: Set[Point] = set() points: Set[Point] = set()
for e in edges: for e in edges:
gt = e.geomType() gt = e.geom_type()
if gt == "LINE": if gt == "LINE":
p1 = e.startPoint() p1 = e.start_point()
p2 = e.endPoint() p2 = e.end_point()
points.update((Point(p1.x, p1.y), Point(p2.x, p2.y))) points.update((Point(p1.X, p1.Y), Point(p2.X, p2.Y)))
elif gt == "CIRCLE": elif gt == "CIRCLE":
c = e.arcCenter() c = e.arc_center()
r = e.radius() r = e.radius()
a1, a2 = e._bounds() a1, a2 = e._bounds()
arcs.add(Arc(Point(c.x, c.y), r, a1, a2)) arcs.add(Arc(Point(c.X, c.Y), r, a1, a2))
else: else:
raise ValueError("Unsupported geometry {gt}") raise ValueError("Unsupported geometry {gt}")
@ -186,12 +184,12 @@ def _pt_arc(p: Point, a: Arc) -> Tuple[float, float, float, float]:
r = a.r r = a.r
xc, yc = a.c.x, a.c.y xc, yc = a.c.x, a.c.y
dx, dy = x - xc, y - yc dx, dy = x - xc, y - yc
l = sqrt(dx ** 2 + dy ** 2) l = sqrt(dx**2 + dy**2)
x1 = r ** 2 / l ** 2 * dx - r / l ** 2 * sqrt(l ** 2 - r ** 2) * dy + xc x1 = r**2 / l**2 * dx - r / l**2 * sqrt(l**2 - r**2) * dy + xc
y1 = r ** 2 / l ** 2 * dy + r / l ** 2 * sqrt(l ** 2 - r ** 2) * dx + yc y1 = r**2 / l**2 * dy + r / l**2 * sqrt(l**2 - r**2) * dx + yc
x2 = r ** 2 / l ** 2 * dx + r / l ** 2 * sqrt(l ** 2 - r ** 2) * dy + xc x2 = r**2 / l**2 * dx + r / l**2 * sqrt(l**2 - r**2) * dy + xc
y2 = r ** 2 / l ** 2 * dy - r / l ** 2 * sqrt(l ** 2 - r ** 2) * dx + yc y2 = r**2 / l**2 * dy - r / l**2 * sqrt(l**2 - r**2) * dx + yc
return x1, y1, x2, y2 return x1, y1, x2, y2
@ -257,7 +255,7 @@ def arc_arc(a1: Arc, a2: Arc) -> Tuple[float, Segment]:
else: else:
dx = xc2 - xc1 dx = xc2 - xc1
dy = yc2 - yc1 dy = yc2 - yc1
l = sqrt(dx ** 2 + dy ** 2) l = sqrt(dx**2 + dy**2)
dx /= l dx /= l
dy /= l dy /= l
@ -339,7 +337,7 @@ def finalize_hull(hull: Hull) -> Wire:
for el_p, el, el_n in zip(hull, hull[1:], hull[2:]): for el_p, el, el_n in zip(hull, hull[1:], hull[2:]):
if isinstance(el, Segment): if isinstance(el, Segment):
rv.append(Edge.makeLine(Vector(el.a.x, el.a.y), Vector(el.b.x, el.b.y))) rv.append(Edge.make_line(Vector(el.a.x, el.a.y), Vector(el.b.x, el.b.y)))
elif ( elif (
isinstance(el, Arc) isinstance(el, Arc)
and isinstance(el_p, Segment) and isinstance(el_p, Segment)
@ -349,7 +347,7 @@ def finalize_hull(hull: Hull) -> Wire:
a2 = degrees(atan2p(el_n.a.x - el.c.x, el_n.a.y - el.c.y)) a2 = degrees(atan2p(el_n.a.x - el.c.x, el_n.a.y - el.c.y))
rv.append( rv.append(
Edge.makeCircle(el.r, Vector(el.c.x, el.c.y), angle1=a1, angle2=a2) Edge.make_circle(el.r, Vector(el.c.x, el.c.y), angle1=a1, angle2=a2)
) )
el1 = hull[1] el1 = hull[1]
@ -358,10 +356,10 @@ def finalize_hull(hull: Hull) -> Wire:
a2 = degrees(atan2p(el1.a.x - el_n.c.x, el1.a.y - el_n.c.y)) a2 = degrees(atan2p(el1.a.x - el_n.c.x, el1.a.y - el_n.c.y))
rv.append( rv.append(
Edge.makeCircle(el_n.r, Vector(el_n.c.x, el_n.c.y), angle1=a1, angle2=a2) Edge.make_circle(el_n.r, Vector(el_n.c.x, el_n.c.y), angle1=a1, angle2=a2)
) )
return Wire.assembleEdges(rv) return Wire.make_wire(rv)
def find_hull(edges: Iterable[Edge]) -> Wire: def find_hull(edges: Iterable[Edge]) -> Wire:

View file

@ -28,7 +28,7 @@ license:
import unittest import unittest
from math import sqrt from math import sqrt
from build123d import * from build123d import *
from cadquery import Vector from build123d import Vector
def _assertTupleAlmostEquals(self, expected, actual, places, msg=None): def _assertTupleAlmostEquals(self, expected, actual, places, msg=None):