Ë
    Jÿi/¸  ã                  ó„  — d Z ddlmZ ddlZddlZddlmZmZmZ ddl	m
Z
mZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZmZ ddlm Z m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z; ddl<m=Z=m>Z>m?Z?m@Z@mAZA ddlBmCZCmDZD ddlEmFZFmGZGmHZHmIZI ddlJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS ddlTmUZU ddlVmWZWmXZXmYZY ddlZm[Z[m\Z\m]Z]m^Z^m_Z_ ddl`maZambZbmcZcmdZd dd lemfZfmgZgmhZhmiZi dd!ljmkZk erdd"llmmZmmnZnmoZompZp  G d#„ d$e[«      Zq G d%„ d&eqe[e@   «      Zry)'aó  
build123d topology

name: three_d.py
by:   Gumyr
date: January 07, 2025

desc:

This module defines the `Solid` class and associated methods for creating, manipulating, and
querying three-dimensional solid geometries in the build123d CAD system. It provides powerful tools
for constructing complex 3D models, including operations such as extrusion, sweeping, filleting,
chamfering, and Boolean operations. The module integrates with OpenCascade to leverage its robust
geometric kernel for precise 3D modeling.

Key Features:
- **Solid Class**:
  - Represents closed, bounded 3D shapes with methods for volume calculation, bounding box
    computation, and validity checks.
  - Includes constructors for primitive solids (e.g., box, cylinder, cone, torus) and advanced
    operations like lofting, revolving, and sweeping profiles along paths.

- **Mixin3D**:
  - Adds shared methods for operations like filleting, chamfering, splitting, and hollowing solids.
  - Supports advanced workflows such as finding maximum fillet radii and extruding with rotation or
    taper.

- **Boolean Operations**:
  - Provides utilities for union, subtraction, and intersection of solids.

- **Thickening and Offsetting**:
  - Allows transformation of faces or shells into solids through thickening.

This module is essential for generating and manipulating complex 3D geometries in the build123d
library, offering a comprehensive API for CAD modeling.

license:

    Copyright 2025 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.

é    )ÚannotationsN)ÚradiansÚcosÚtan)ÚUnionÚTYPE_CHECKING)ÚIterable)ÚBRepAlgoAPI_Cut)ÚBRepBuilderAPI_MakeSolid)ÚBRepClass3d_SolidClassifier)ÚBRepFeat_MakeDPrism)ÚBRepFilletAPI_MakeChamferÚBRepFilletAPI_MakeFillet)ÚBRepOffset_MakeOffsetÚBRepOffset_Skin)ÚBRepOffsetAPI_MakePipeShellÚBRepOffsetAPI_MakeThickSolid)ÚBRepPrimAPI_MakeBoxÚBRepPrimAPI_MakeConeÚBRepPrimAPI_MakeCylinderÚBRepPrimAPI_MakeRevolÚBRepPrimAPI_MakeSphereÚBRepPrimAPI_MakeTorusÚBRepPrimAPI_MakeWedge)ÚGProp_GProps)ÚGeomAbs_IntersectionÚGeomAbs_JoinType)ÚLocOpe_DPrism)ÚShapeFix_Solid)ÚStandard_Failure)ÚStdFail_NotDone)ÚTopExp)Ú)TopTools_IndexedDataMapOfShapeListOfShapeÚTopTools_ListOfShape)ÚTopoDSÚTopoDS_FaceÚTopoDS_ShapeÚTopoDS_SolidÚTopoDS_Wire)Úgp_Ax2Úgp_Pnt)ÚCenterOfÚKindÚ
TransitionÚUntil)	ÚDEG2RADÚAxisÚBoundBoxÚColorÚLocationÚOrientedBoundBoxÚPlaneÚVectorÚ
VectorLike)ÚSelfé   )ÚEdgeÚWireÚMixin1D)ÚShapeÚ	ShapeListÚJointÚdowncastÚ	shapetype)Úsort_wires_by_build_orderÚMixin2DÚFaceÚShell)Ú_extrude_topods_shapeÚfind_max_dimensionÚ
_make_loftÚ!_make_topods_compound_from_shapes)ÚVertex)ÚCompoundÚCurveÚSketchÚPartc                  óœ  — e Zd ZdZej
                  Zej                  Zej                  Zej                  Z	ej                  Z
ej                  Zej                  Zej                  Zej                  Zej                  Zej                   Zej"                  Zej$                  Zedd„«       Zedd„«       Ze	 	 	 	 	 	 dd„«       Zej2                  fdd„Z	 d	 	 	 	 	 	 	 	 	 dd„Z	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd	„Zd
ej>                  f	 	 	 	 	 	 	 	 	 dd„Z ddd„Z!	 	 d	 	 	 	 	 dd„Z"d
ej>                  f	 	 	 	 	 	 	 	 	 dd„Z#d d„Z$d!d„Z%y)"ÚMixin3Dz-Additional methods to add to 3D Shape classesc                 ó   — y)zDimension of Solidsé   © ©Úselfs    úk/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/build123d/topology/three_d.pyÚ_dimzMixin3D._dimŒ   s   € ð ó    c                ó4  — t         j                  t        t         j                  t        t         j
                  t        t         j                  t        t         j                  t        t         j                  t        i}t        |«      } ||   t        |«      «      S )z6Returns the right type of wrapper, given a OCCT object)ÚtaÚTopAbs_VERTEXrK   ÚTopAbs_EDGEr;   ÚTopAbs_WIREr<   ÚTopAbs_FACErE   ÚTopAbs_SHELLrF   ÚTopAbs_SOLIDÚSolidrB   rA   )ÚclsÚobjÚconstructor_lutÚ
shape_types       rW   ÚcastzMixin3D.cast“   sd   € ô ×ÑœfÜ�N‰NœDÜ�N‰NœDÜ�N‰NœDÜ�O‰OœUÜ�O‰OœUð
ˆô ˜s“^ˆ
à*ˆ˜zÑ*¬8°C«=Ó9Ð9rY   c                ó   — t         S )z9Unused - only here because Mixin1D is a subclass of Shape)ÚNotImplemented©rc   rd   Ú	directions      rW   ÚextrudezMixin3D.extrude¥   s
   € ô
 ÐrY   c                ó†  — |t         j                  k(  rt        d«      ‚|t         j                  k(  r^t	        «       }t
        j                  t        | j                  «         } || j                  |«       t        |j                  «       «      }|S |t         j                  k(  r| j                  «       j                  «       }S )a�  Return center of object

        Find center of object

        Args:
            center_of (CenterOf, optional): center option. Defaults to CenterOf.MASS.

        Raises:
            ValueError: Center of GEOMETRY is not supported for this object
            NotImplementedError: Unable to calculate center of mass of this object

        Returns:
            Vector: center
        z3Center of GEOMETRY is not supported for this object)r,   ÚGEOMETRYÚ
ValueErrorÚMASSr   r>   Úshape_properties_LUTrB   Úwrappedr7   ÚCentreOfMassÚBOUNDING_BOXÚbounding_boxÚcenter)rV   Ú	center_ofÚ
propertiesÚcalc_functionÚmiddles        rW   rv   zMixin3D.center®   sž   € ð œ×)Ñ)Ò)ÜÐRÓSÐSØœŸ™Ò%Ü%›ˆJÜ!×6Ñ6´yÀÇÁÓ7NÑOˆMÙ˜$Ÿ,™,¨
Ô3Ü˜J×3Ñ3Ó5Ó6ˆFð ˆð œ(×/Ñ/Ò/Ø×&Ñ&Ó(×/Ñ/Ó1ˆFØˆrY   Nc           	     óØ  ‡— t        |«      }‰rt        ˆfd„|D «       «      rt        d«      ‚|D �cg c]  }|j                  ‘Œ }}t	        «       }t        j                  | j                  t        j                  t        j                  |«       t        | j                  «      }|r|}	|}
n|}	|}
|D ]W  }‰r‰j                  }n|j                  |«      j                  «       }|j                  |	|
|t        j                  |«      «       ŒY 	 | j!                  |j#                  «       «      }|j%                  «       st&        ‚	 |S c c}w # t(        t&        f$ r}t        d«      |‚d}~ww xY w)a]  Chamfer

        Chamfers the specified edges of this solid.

        Args:
            length (float): length > 0, the length (length) of the chamfer
            length2 (Optional[float]): length2 > 0, optional parameter for asymmetrical
                chamfer. Should be `None` if not required.
            edge_list (Iterable[Edge]): a list of Edge objects, which must belong to
                this solid
            face (Face, optional): identifies the side where length is measured. The edge(s)
                must be part of the face

        Returns:
            Self:  Chamfered solid
        c              3  óH   •K  — | ]  }|‰j                  «       vsŒ|–— Œ y ­w©N)Úedges)Ú.0ÚedgeÚfaces     €rW   Ú	<genexpr>z"Mixin3D.chamfer.<locals>.<genexpr>á   s   øè ø€ ÐJ¡I˜D°¸T¿Z¹Z»\Ò1I”4¡Iùs   ƒ"›"z#Some edges are not part of the facez8Failed creating a chamfer, try a smaller length value(s)N)ÚlistÚanyro   rr   r#   r"   ÚMapShapesAndAncestors_sr[   r]   r_   r   ÚFindFromKeyÚFirstÚAddr%   ÚFace_sÚ	__class__r>   Úis_validr    r!   )rV   ÚlengthÚlength2Ú	edge_listr�   ÚeÚnative_edgesÚedge_face_mapÚchamfer_builderÚ	distance1Ú	distance2Únative_edgeÚ	topo_faceÚ	new_shapeÚerrs       `          rW   ÚchamferzMixin3D.chamferÈ   sT  ø€ ô. ˜“Oˆ	ÙÜÓJ¡IÓJÔJÜ Ð!FÓGÐGá+4Ó5©9 a˜Ÿ	›	¨9ˆÐ5ô BÓCˆÜ×&Ñ&Ø�L‰Lœ"Ÿ.™.¬"¯.©.¸-ô	
ô
 4°D·L±LÓAˆáØˆIØ‰IàˆIØˆIã'ˆKÙØ ŸL™L‘	à)×5Ñ5°kÓB×HÑHÓJ�	à×ÑØ˜9 k´6·=±=ÀÓ3Kõð (ð	ØŸ™ ×'<Ñ'<Ó'>Ó?ˆIØ×%Ñ%Ô'Ü&Ð&ð (ð ÐùòK 6øô@  Ô!1Ð2ò 	ÜØJóàðûð	ús   ²EÄ5E	 Å	E)ÅE$Å$E)c           	     óê  — t        |d   t        «      r+t        |«      }|D �	cg c]  }	t        |	d   |	dd «      ‘Œ }
}	n|}
| j                  }|
D ]�  }t        ||j                  |r|j                  n	t        «       |t        z  |d«      }|�|j                  |j                  «       n&|s|€|j                  «        n|j                  |«       |j                  «       }Œ� | j                  |«      S c c}	w )a~  dprism

        Make a prismatic feature (additive or subtractive)

        Args:
            basis (Optional[Face]): face to perform the operation on
            bounds (list[Union[Face,Wire]]): list of profiles
            depth (float, optional): depth of the cut or extrusion. Defaults to None.
            taper (float, optional): in degrees. Defaults to 0.
            up_to_face (Face, optional): a face to extrude until. Defaults to None.
            thru_all (bool, optional): cut thru_all. Defaults to True.
            additive (bool, optional): Defaults to True.

        Returns:
            Solid: prismatic feature
        r   r:   NF)Ú
isinstancer<   rC   rE   rr   r   r&   r0   ÚPerformÚPerformThruAllr>   rŠ   )rV   ÚbasisÚboundsÚdepthÚtaperÚ
up_to_faceÚthru_allÚadditiveÚsorted_profilesÚpÚfacesÚshaper�   Úfeats                 rW   ÚdprismzMixin3D.dprism  sâ   € ô4 �f˜Q‘i¤Ô&Ü7¸Ó?ˆOÙ0?Ó@±¨1”T˜!˜A™$  ! " Õ&°ˆEÑ@àˆEà-1¯\©\ˆÛˆDÜ&ØØ—‘Ù!&�—’¬K«MØœ‘ØØóˆDð Ð%Ø—‘˜Z×/Ñ/Õ0Ù˜U˜]Ø×#Ñ#Õ%à—‘˜UÔ#à—J‘J“L‰Eð# ð& �~‰~˜eÓ$Ð$ùò1 As   £C0c                óZ  — |D �cg c]  }|j                   ‘Œ }}t        | j                   «      }|D ]  }|j                  ||«       Œ 	 | j                  |j	                  «       «      }|j                  «       st        ‚	 |S c c}w # t        t        f$ r}t        d|› d�«      |‚d}~ww xY w)a$  Fillet

        Fillets the specified edges of this solid.

        Args:
            radius (float): float > 0, the radius of the fillet
            edge_list (Iterable[Edge]): a list of Edge objects, which must belong to this solid

        Returns:
            Any: Filleted solid
        z(Failed creating a fillet with radius of zQ, try a smaller value or use max_fillet() to find the largest valid fillet radiusN)	rr   r   rˆ   rŠ   r>   r‹   r    r!   ro   )	rV   ÚradiusrŽ   r�   r�   Úfillet_builderr•   r—   r˜   s	            rW   ÚfilletzMixin3D.filletA  sÂ   € ñ ,5Ó5©9 a˜Ÿ	›	¨9ˆÐ5ä1°$·,±,Ó?ˆã'ˆKØ×Ñ˜v {Õ3ð (ð	ØŸ™ ~×';Ñ';Ó'=Ó>ˆIØ×%Ñ%Ô'Ü&Ð&ð (ð Ðùò# 6øô  Ô!1Ð2ò 	ÜØ:¸6¸(ð COð Póð ðûð	ús   …BÁ	5B ÂB*ÂB%Â%B*g-Cëâ6?c           	     óv  — |rt        |«      ng }|t        j                  k(  rt        d«      ‚t        j                  t
        j                  t        j                  t
        j                  i}t        «       }|D ]  }|j                  |j                  «       Œ t        «       }|j                  | j                  |||d||   ¬«       |j                  «        |r+| j                  j!                  |j#                  «       «      }	|	S | j                  j!                  |j#                  «       «      j%                  «       d   j                  }
| j%                  «       d   j                  }|dkD  rt'        |
|«      }nt'        ||
«      }| j                  j!                  |j#                  «       «      j)                  «       }	|	S )an  Hollow

        Return the outer shelled solid of self.

        Args:
            faces (Optional[Iterable[Face]]): faces to be removed,
            which must be part of the solid. Can be an empty list.
            thickness (float): shell thickness - positive shells outwards, negative
                shells inwards.
            tolerance (float, optional): modelling tolerance of the method. Defaults to 0.0001.
            kind (Kind, optional): intersection type. Defaults to Kind.ARC.

        Raises:
            ValueError: Kind.TANGENT not supported

        Returns:
            Solid: A hollow solid.
        úKind.TANGENT not supportedT)ÚIntersectionÚJoinr   )rƒ   r-   ÚTANGENTro   ÚARCr   ÚGeomAbs_ArcÚINTERSECTIONr   r$   ÚAppendrr   r   ÚMakeThickSolidByJoinÚBuildrŠ   rg   r>   Úshellsr   Úfix)rV   r§   Ú	thicknessÚ	toleranceÚkindÚ	kind_dictÚocc_faces_listr�   Úshell_builderÚreturn_valueÚshell1Úshell2Úsols                rW   ÚhollowzMixin3D.hollow`  s|  € ñ2  %”�U”¨"ˆØ”4—<‘<ÒÜÐ9Ó:Ð:ô �H‰HÔ&×2Ñ2Ü×ÑÔ/×DÑDð
ˆ	ô
 .Ó/ˆÛˆDØ×!Ñ! $§,¡,Õ/ð ô 5Ó6ˆØ×*Ñ*Ø�L‰LØØØØØ˜4‘ð 	+ô 	
ð 	×ÑÔáØŸ>™>×.Ñ.¨}×/BÑ/BÓ/DÓEˆLð Ðð —^‘^×(Ñ(¨×)<Ñ)<Ó)>Ó?×FÑFÓHÈÑK×SÑSˆFØ—[‘[“] 1Ñ%×-Ñ-ˆFð ˜1Š}Ü.¨v°vÓ>‘ä.¨v°vÓ>�ð  Ÿ>™>×.Ñ.¨s¯y©y«{Ó;×?Ñ?ÓAˆLàÐrY   c                óð   — t        | j                  «      }|j                  t        t	        |«      j                  «       Ž |«       |j                  «       t        j                  k(  xs |j                  «       S )a¶  Returns whether or not the point is inside a solid or compound
        object within the specified tolerance.

        Args:
          point: tuple or Vector representing 3D point to be tested
          tolerance: tolerance for inside determination, default=1.0e-6
          point: VectorLike:
          tolerance: float:  (Default value = 1.0e-6)

        Returns:
          bool indicating whether or not point is within solid

        )
r   rr   rœ   r+   r7   Úto_tupleÚStater[   Ú	TopAbs_INÚ	IsOnAFace)rV   Úpointr½   Úsolid_classifiers       rW   Ú	is_insidezMixin3D.is_inside£  s\   € ô 7°t·|±|ÓDÐØ× Ñ ¤¬°«×)?Ñ)?Ó)AÐ!BÀIÔNà×%Ñ%Ó'¬2¯<©<Ñ7ÒWÐ;K×;UÑ;UÓ;WÐWrY   c                ó.  ‡ ‡‡‡‡‡— dˆˆˆˆˆ ˆfd„Š‰ j                  «       st        d«      ‚|D �cg c]  }|j                  ‘Œ c}Št        j                  «       dk(  rt
        Šnt        Š ‰dd‰ j                  «       j                  z  d«      }|S c c}w )a5  Find Maximum Fillet Size

        Find the largest fillet radius for the given Shape and edges with a
        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
        c                óh  •— | |z   dz  }|‰
k(  rt        d‰› d‰
› �«      ‚t        ‰j                  «      }‰D ]  }|j                  ||«       Œ 	 ‰j	                  |j                  «       «      }|j                  «       s‰	‚	 || z
  ‰k  r|}|S  ‰|||dz   «      }|S # ‰	$ r  ‰| ||dz   «      cY S w xY w)Né   z$Failed to find the max value within z in r:   )ÚRuntimeErrorr   rr   rˆ   rŠ   r>   r‹   )Ú
window_minÚ
window_maxÚcurrent_iterationÚ
window_midr­   r•   r—   rÂ   Ú_Mixin3D__max_filletÚfillet_exceptionÚmax_iterationsr�   rV   r½   s           €€€€€€rW   Ú__max_filletz(Mixin3D.max_fillet.<locals>.__max_filletÔ  sü   ø€ Ø$ zÑ1°QÑ6ˆJà  NÒ2Ü"Ø:¸9¸+ÀTÈ.ÐIYÐZóð ô 6°d·l±lÓCˆNã+�Ø×"Ñ" :¨{Õ;ð  ,ðSØ ŸN™N¨>×+?Ñ+?Ó+AÓB�	Ø ×)Ñ)Ô+Ø*Ð*ð ,ð ˜JÑ&¨)Ò3Ø)�ð
  Ðñ  ,Ø 
Ð,=ÀÑ,Aó �ð  Ðøð $ò SÙ# J°
Ð<MÐPQÑ<QÓRÒRðSús   Á1B ÂB1Â0B1zInvalid ShapeÚDarwinç        rÑ   r   )rÓ   ÚfloatrÔ   rÝ   rÕ   Úint)	r‹   ro   rr   ÚplatformÚsystemr    r!   ru   Údiagonal)	rV   rŽ   r½   rÙ   r�   Ú
max_radiusr×   rØ   r�   s	   ` ``  @@@rW   Ú
max_filletzMixin3D.max_fillet¶  s…   ý€ ÷<	 ò 	 ð< �}‰}ŒÜ˜_Ó-Ð-á+4Ó5©9 a˜Ÿ	›	¨9Ñ5ˆô �?‰?Ó Ò(Ü/Ñä.Ðá! # q¨4×+<Ñ+<Ó+>×+GÑ+GÑ'GÈÓKˆ
àÐùò 6s   ±Bc           
     óú  — |rt        |«      ng }|t        j                  k(  rt        d«      ‚t        j                  t
        j                  t        j                  t
        j                  t        j                  t
        j                  i}t        «       }|D ]  }|j                  |j                  «       Œ t        «       }|j                  | j                  |||dd||   ¬«       |j                  «        	 |j!                  «       }	| j(                  j+                  |	«      }|j                  €J ‚|j,                  dk  r|j                  j/                  «        |S # t"        t$        f$ r}
t'        d«      |
‚d}
~
ww xY w)aQ  Shell

        Make an offset solid of self.

        Args:
            openings (Optional[Iterable[Face]]): faces to be removed,
                which must be part of the solid. Can be an empty list.
            thickness (float): offset amount - positive offset outwards, negative inwards
            tolerance (float, optional): modelling tolerance of the method. Defaults to 0.0001.
            kind (Kind, optional): intersection type. Defaults to Kind.ARC.

        Raises:
            ValueError: Kind.TANGENT not supported

        Returns:
            Solid: A shelled solid.
        r°   T)r±   ÚRemoveIntEdgesr²   z8offset Error, an alternative kind may resolve this errorNr   )rƒ   r-   r³   ro   r´   r   rµ   r¶   r   ÚGeomAbs_Tangentr$   r·   rr   r   r¸   r¹   r>   r!   r    rÒ   rŠ   rg   ÚvolumeÚReverse)rV   Úopeningsr¼   r½   r¾   r¿   rÀ   r�   Úoffset_builderÚoffset_occt_solidr˜   Úoffset_solids               rW   Ú	offset_3dzMixin3D.offset_3d  sb  € ñ0 &.”4˜”>°2ˆØ”4—<‘<ÒÜÐ9Ó:Ð:ô �H‰HÔ&×2Ñ2Ü×ÑÔ/×DÑDÜ�L‰LÔ*×:Ñ:ð
ˆ	ô .Ó/ˆÛˆDØ×!Ñ! $§,¡,Õ/ð ô 6Ó7ˆØ×+Ñ+Ø�L‰LØØØØØØ˜4‘ð 	,ô 	
ð 	×ÑÔð	Ø .× 4Ñ 4Ó 6Ðð —~‘~×*Ñ*Ð+<Ó=ˆØ×#Ñ#Ð/Ð/Ð/ð ×Ñ Ò"Ø× Ñ ×(Ñ(Ô*àÐøô  Ô!1Ð2ò 	ÜØJóàðûð	ús   Ã6E ÅE:Å)E5Å5E:c                ó.   — t        j                  | d«      S )zReturn the Solidrb   )r>   Úget_single_shaperU   s    rW   ÚsolidzMixin3D.solidD  s   € ä×%Ñ% d¨GÓ4Ð4rY   c                ó.   — t        j                  | d«      S )z%solids - all the solids in this Shaperb   )r>   Úget_shape_listrU   s    rW   ÚsolidszMixin3D.solidsH  s   € ä×#Ñ# D¨'Ó2Ð2rY   )Úreturnz
int | None)rd   r'   rô   r9   )rd   r>   rk   r8   rô   z&Edge | Face | Shell | Solid | Compound)rw   r,   rô   r7   r}   )
rŒ   rÝ   r�   úfloat | NonerŽ   úIterable[Edge]r�   úFace | Nonerô   r9   )Nr   NTT)rž   r÷   rŸ   zlist[Face | Wire]r    rõ   r¡   rÝ   r¢   r÷   r£   Úboolr¤   rø   rô   rb   )r¬   rÝ   rŽ   rö   rô   r9   )
r§   úIterable[Face] | Noner¼   rÝ   r½   rÝ   r¾   r-   rô   rb   )g�íµ ÷Æ°>)rÌ   r8   r½   rÝ   rô   rø   )gš™™™™™¹?é
   )rŽ   rö   rÙ   rÞ   rô   rÝ   )
ré   rù   r¼   rÝ   r½   rÝ   r¾   r-   rô   rb   )rô   zSolid | None)rô   zShapeList[Solid])&Ú__name__Ú
__module__Ú__qualname__Ú__doc__r=   Úproject_to_viewportÚsplitrD   Úfind_intersection_pointsÚverticesÚvertexr~   r€   ÚwiresÚwirer§   r�   rº   ÚshellÚpropertyrX   Úclassmethodrg   rl   r,   rp   rv   r™   rª   r®   r-   r´   rÆ   rÎ   rã   rí   rð   ró   rT   rY   rW   rQ   rQ   y   s^  „ Ù7à!×5Ñ5ÐØ�M‰M€EØ&×?Ñ?Ðà×Ñ€HØ�^‰^€FØ�M‰M€EØ�<‰<€DØ�M‰M€EØ�<‰<€DØ�M‰M€EØ�<‰<€DØ�^‰^€FØ�M‰M€Eð òó ðð ò:ó ð:ð" ðØðØ$.ðà	/òó ðð ,4¯=©=ô ð> !ðAàðAð ðAð "ð	Að
 ðAð 
óAðN #ØØ"&ØØð4%àð4%ð "ð4%ð ð	4%ð
 ð4%ð  ð4%ð ð4%ð ð4%ð 
ó4%ólðF "Ø—X‘XðAà$ðAð ðAð ð	Að
 ðAð 
óAôFXð, Ø ð	Jà!ðJð ð	Jð
 
óJð` "Ø—X‘Xð@à'ð@ð ð@ð ð	@ð
 ð@ð 
ó@óD5ô3rY   rQ   c                  ó¾  ‡ — e Zd ZdZdZ	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 dˆ fd„Zed d„«       Zed!d„«       Z	e	 	 	 	 	 	 	 	 d"d„«       Z
ed#d„«       Ze	 d$	 	 	 	 	 	 	 	 	 	 	 d%d	„«       Ze	 d&	 	 	 	 	 	 	 	 	 d'd„«       Zeej                  f	 	 	 	 	 	 	 	 	 d(d„«       Zed)d„«       Zeej&                  f	 	 	 	 	 	 	 	 	 d*d„«       Zeej&                  df	 	 	 	 	 	 	 	 	 	 	 d+d„«       Zeej&                  df	 	 	 	 	 	 	 	 	 d,d„«       Zed-d.d„«       Zeej&                  dddf	 	 	 	 	 	 	 	 	 	 	 d/d„«       Zeej&                  dddf	 	 	 	 	 	 	 	 	 	 	 	 	 d0d„«       Zeej&                  f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1d„«       Ze	 d$	 	 	 	 	 	 	 	 	 d2d„«       Zedd
ddej:                  f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d3d„«       Ze	 	 	 d4	 	 	 	 	 	 	 	 	 	 	 d5d„«       Ze	 d$	 	 	 	 	 	 	 d6d„«       Z ˆ xZ!S )7rb   a°  A Solid in build123d represents a three-dimensional solid geometry
    in a topological structure. A solid is a closed and bounded volume, enclosing
    a region in 3D space. It comprises faces, edges, and vertices connected in a
    well-defined manner. Solid modeling operations, such as Boolean
    operations (union, intersection, and difference), are often performed on
    Solid objects to create or modify complex geometries.g      @Nc                ó®   •— t        |t        «      rt        j                  |«      }t        ‰| �  ||||¬«       |€dn|| _        |€i | _        y|| _        y)aè  Build a solid from an OCCT TopoDS_Shape/TopoDS_Solid

        Args:
            obj (TopoDS_Shape | Shell, optional): OCCT Solid or Shell.
            label (str, optional): Defaults to ''.
            color (Color, optional): Defaults to None.
            material (str, optional): tag for external tools. Defaults to ''.
            joints (dict[str, Joint], optional): names joints. Defaults to None.
            parent (Compound, optional): assembly parent. Defaults to None.
        )rd   ÚlabelÚcolorÚparentNÚ )r›   rF   rb   Ú_make_solidÚsuperÚ__init__ÚmaterialÚjoints)rV   rd   r  r  r  r  r  rŠ   s          €rW   r  zSolid.__init__X  s^   ø€ ô( �cœ5Ô!Ü×#Ñ# CÓ(ˆCä‰ÑØàØØð 	ô 	
ð 'Ð.™°HˆŒØ"˜N�bˆ�°ˆ�rY   c                ó,   — t        j                  | «      S )z!volume - the volume of this Solid)r>   Úcompute_massrU   s    rW   rç   zSolid.volume{  s   € ô ×!Ñ! $Ó'Ð'rY   c                óH   — t        «       j                  |j                  «      S )z,Create a Solid object from the surface shell)r   ÚSolidFromShellrr   )rc   r  s     rW   r  zSolid._make_solidƒ  s   € ô Ó×.Ñ.¨u¯}©}Ó=Ð=rY   c                ó€  — d}t        |t        «      rkt        «       }|j                  |j	                  «       j                  «       «       |j                  |j                  «       «       |j                  |«       d}|S t        |t        t        f«      r*|j                  |j                  «       j                  d«       |S )NFT)r›   r7   r*   ÚSetLocationÚstart_pointÚto_pntÚSetDirectionÚto_dirÚSetModer<   r;   Úto_wirerr   )rc   ÚbuilderÚpathÚbinormalÚrotateÚcoordinate_systems         rW   Ú_set_sweep_modezSolid._set_sweep_modeˆ  s›   € ð ˆä�h¤Ô'Ü &£ÐØ×)Ñ)¨$×*:Ñ*:Ó*<×*CÑ*CÓ*EÔFØ×*Ñ*¨8¯?©?Ó+<Ô=Ø�O‰OÐ-Ô.ØˆFð ˆô ˜¤4¬ ,Ô/Ø�O‰O˜H×,Ñ,Ó.×6Ñ6¸Ô=àˆrY   c                óf   — t        t        j                  t        |j                  |«      «      «      S )a/  extrude

        Extrude a Face into a Solid.

        Args:
            direction (VectorLike): direction and magnitude of extrusion

        Raises:
            ValueError: Unsupported class
            RuntimeError: Generated invalid result

        Returns:
            Edge: extruded shape
        )rb   r%   ÚSolid_srG   rr   rj   s      rW   rl   zSolid.extrudeœ  s$   € ô  ”V—^‘^Ô$9¸#¿+¹+ÀyÓ$QÓRÓSÐSrY   c           	     ó¬  — |r|ng }t        |«      }t        |«      }	 	 	 	 	 	 	 	 dd„}t        |t        «      r!|j                  «       }|j	                  «       }n|}t        j                  ||j                  |«      «      }t        j                  |g«      d   j                  }	d|z  |j                  z  }
t        t        j                  |
|j                  d||¬«      g«      j                  } ||j                  |	|«      }|D �cg c]  } ||j                  |	|«      ‘Œ }}t        |«      }t        t        ||«      j!                  «       «      S c c}w )an  Extrude with Rotation

        Creates a 'twisted prism' by extruding, while simultaneously rotating around the
        extrusion vector.

        Args:
            section (Union[Face,Wire]): cross section
            vec_center (VectorLike): the center point about which to rotate
            vec_normal (VectorLike): a vector along which to extrude the wires
            angle (float): the angle to rotate through while extruding
            inner_wires (list[Wire], optional): holes - only used if section is of type Wire.
                Defaults to None.

        Returns:
            Solid: extruded object
        c                ó¾   — t        |«      }|j                  |d«       |j                  | «       |j                  «        |j	                  «        |j                  «       S )zHelper functionF)r   r  rˆ   r¹   Ú	MakeSolidr>   )r  ÚspineÚ	aux_spineÚextrude_builders       rW   Úextrude_aux_spinez=Solid.extrude_linear_with_rotation.<locals>.extrude_aux_spineÕ  sS   € ô :¸%Ó@ˆOØ×#Ñ# I¨uÔ5Ø×Ñ Ô%Ø×!Ñ!Ô#Ø×%Ñ%Ô'Ø"×(Ñ(Ó*Ð*rY   r   g     €v@r:   )rv   Únormal)r  r)   r+  r)   r,  r)   rô   r'   )r7   r›   rE   Ú
outer_wireÚinner_wiresr;   Ú	make_lineÚaddr<   Úcombinerr   rŒ   Ú
make_helixrJ   rb   r
   r>   )rc   Úsectionrv   r/  Úangler1  r.  r0  Ústraight_spine_eÚstraight_spine_wÚpitchÚaux_spine_wÚouter_solidÚwÚinner_solidsÚ
inner_comps                   rW   Úextrude_linear_with_rotationz"Solid.extrude_linear_with_rotation®  se  € ñF &1‘k°bˆÜ˜“ˆÜ˜“ˆð		+Øð		+Ø&1ð		+Ø>Ið		+àó		+ô �gœtÔ$Ø ×+Ñ+Ó-ˆJØ!×-Ñ-Ó/‰Kà ˆJô  Ÿ>™>¨&°&·*±*¸VÓ2DÓEÐÜŸ<™<Ð)9Ð(:Ó;¸AÑ>×FÑFÐð ˜‘ §¡Ñ-ˆÜÜ�_‰_˜U F§M¡M°1¸VÈFÔSÐTó
ç
‰'ð 	ñ
 (Ø×ÑÐ 0°+ó
ˆñ !ó
á �ñ ˜aŸi™iÐ)9¸;ÕGØ ð 	ð 
ô 7°|ÓDˆ
ô ”_ [°*Ó=×CÑCÓEÓFÐFùò
s   ÄETc           	     ó:  — t        |«      }|j                  «       |j                  «       k(  r‘t        |«      j                  j
                  dkD  ro|dkD  rj|j                  «       sZt        |j                  |j                  t        t        |«      «      z  t        |«      «      }t        |j                  «       «      }|S |j                   t        t        |«      «      z  }|j                  «       }t        |«      j!                  |«      }	|	j#                  |t$        j&                  ¬«      }
t        |«      j)                  |
«      }|j+                  t-        |«      «       |j                  «       g|j                  «       z   }g }t/        |«      D ]“  \  }}|dkD  r|rdnd}t        |«      j!                  |«      }|j#                  ||z  t$        j&                  ¬«      }t        |«      j)                  |«      }|j+                  t-        |«      «       |j1                  |«       Œ• t3        ||«      D ��cg c]  \  }}t        j5                  ||g«      ‘Œ }}}t7        |«      dkD  r+ |d   j8                  |dd Ž }t;        |t        «      sJ ‚|}|S |d   }|S c c}}w )aü  Extrude a cross section with a taper

        Extrude a cross section into a prismatic solid in the provided direction.

        Note that two difference algorithms are used. If direction aligns with
        the profile normal (which must be positive), the taper is positive and the profile
        contains no holes the OCP LocOpe_DPrism algorithm is used as it generates the most
        accurate results. Otherwise, a loft is created between the profile and the profile
        with a 2D offset set at the appropriate direction.

        Args:
            section (Face]): cross section
            normal (VectorLike): a vector along which to extrude the wires. The length
                of the vector controls the length of the extrusion.
            taper (float): taper angle in degrees.
            flip_inner (bool, optional): outer and inner geometry have opposite tapers to
                allow for part extraction when injection molding.

        Returns:
            Solid: extruded cross section
        r   )r¾   éÿÿÿÿr:   N)r7   Ú
normalizedÚ	normal_atr6   Úz_dirÚZr1  r   rr   rŒ   r   r   rb   r>   r   r0  Úto_local_coordsÚ	offset_2dr-   r¶   Úfrom_local_coordsÚmover4   Ú	enumerateÚappendÚzipÚ	make_loftÚlenÚcutr›   )rc   Úprofilerk   r¡   Ú
flip_innerÚprism_builderÚ	new_solidÚ
offset_amtÚouterÚlocal_outerÚlocal_taper_outerÚtaper_outerÚprofile_wiresÚtaper_wiresÚir  ÚflipÚlocalÚlocal_taperÚ
taper_wirer¦   Útró   Úcomplex_solids                           rW   Úextrude_taperzSolid.extrude_taper  sh  € ô4 ˜9Ó%ˆ	ð × Ñ Ó" g×&7Ñ&7Ó&9Ò9Ü�g“×$Ñ$×&Ñ&¨Ò*Ø˜’	Ø×'Ñ'Ô)ä)Ø—‘Ø× Ñ ¤3¤w¨u£~Ó#6Ñ6Ü˜“óˆMô
 ˜m×1Ñ1Ó3Ó4ˆIðD Ðð? $×*Ñ*Ð*¬S´¸³Ó-@Ñ@ˆJà×&Ñ&Ó(ˆEÜ % g£× >Ñ >¸uÓ EˆKØ +× 5Ñ 5Ø¤×!2Ñ!2ð !6ó !Ðô   ›.×:Ñ:Ð;LÓMˆKØ×ÑœX iÓ0Ô1à$×/Ñ/Ó1Ð2°W×5HÑ5HÓ5JÑJˆMàˆKÜ$ ]Ö3‘��4Ø šU¡z‘r°q�Ü# G›n×<Ñ<¸TÓB�Ø#Ÿo™o¨d°ZÑ.?Äd×FWÑFW˜oÓX�Ü#(¨£>×#CÑ#CÀKÓ#P�
Ø—‘¤¨Ó 3Ô4Ø×"Ñ" :Õ.ð 4ô 58¸À{Ô4SôÙ4S©D¨A¨q”—‘  A Õ'Ð4Sð ñ ô �6‹{˜QŠØ -  q¡	§¡¨v°a°b¨zÐ :�Ü! -´Ô7Ð7Ð7Ø)�	ð Ðð # 1™I�	àÐùós   È3!Jc                óX  — t        |«      }|t        j                  t        j                  fv r8|dz  }|t        j                  k(  rt        j                  nt        j
                  }t        ||g«      }|t        j                  k(  r||z  n| |z  }t        |j                  «       |«      }t        j                  |||z  «      }g }	|j                  ||«      D ]7  }
t        |
t        «      r|	j                  |
«       Œ%|	|
j                  «       z  }	Œ9 |	D �cg c]2  }|j                   r"|j#                  «       j%                  |«      dk(  s|‘Œ4 }}|st'        d«      ‚|D �cg c]&  }t        j                  ||«      j)                  «       ‘Œ( }}|D �cg c]  }|j*                  dkD  sŒ|‘Œ }}|t        j                  k(  rR|j-                  |«      }t        |t.        «      r|j1                  |«      d   }n|}|D ]  }	 |j-                  |«      }Œ n›|j9                  |«      }t        |t.        «      r|}n|€t/        «       }nt/        |g«      }|D ]G  }	 |j9                  |«      }|�1|j                  |j;                  «       j1                  |«      d   «       ŒI t        j<                  |Ž }j;                  «       j1                  |«      d   }|S c c}w c c}w c c}w # t2        $ r t5        j6                  dd¬«       Y �Œ	w xY w# t2        $ r t5        j6                  dd¬«       Y ŒØw xY w)	aª  extrude_until

        Extrude section in provided direction until it encounters either the
        NEXT or LAST surface of target_object. Note that the bounding surface
        must be larger than the extruded face where they contact.

        Args:
            section (Face): Face to extrude
            target_object (Union[Compound, Solid]): object to limit extrusion
            direction (VectorLike): extrusion direction
            until (Until, optional): surface to limit extrusion. Defaults to Until.NEXT.

        Raises:
            ValueError: provided face does not intersect target_object

        Returns:
            Union[Compound, Solid]: extruded Face
        rB  rÜ   z.provided face does not intersect target_objectg•Ö&è.>r   z+clipping error - extrusion may be incorrectrÑ   )Ú
stacklevel)r7   r/   ÚPREVIOUSÚFIRSTÚNEXTÚLASTrH   r1   rv   rb   rl   Úproject_to_shaper›   rE   rL  r§   Ú	is_planarrD  Údotro   r»   rç   rP  r?   Úsort_byÚ	ExceptionÚwarningsÚwarnÚ	intersectró   Úfuse)rc   r6  Útarget_objectrk   ÚuntilÚmax_dimensionÚclipping_directionÚdirection_axisÚ	extrusionr§   r�   ÚfÚ
clip_facesÚclipping_objectsÚoÚtrimmed_extrusionÚclosest_extrusionÚclipping_objectÚextrusion_shapesÚ	base_partÚextrusion_partsÚclipped_extrusionÚresults                          rW   Úextrude_untilzSolid.extrude_untilL  s  € ô4 ˜9Ó%ˆ	Ø”U—^‘^¤U§[¡[Ð1Ñ1Ø˜‰OˆIØ"'¬5¯>©>Ò"9”E—J’J¼u¿z¹zˆEä*¨G°]Ð+CÓDˆð œŸ
™
Ò"ð ˜Ò%à�˜mÑ+ð 	ô
 ˜gŸn™nÓ.Ð0BÓCˆä—M‘M '¨9°}Ñ+DÓEˆ	ð
 ˆØ×,Ñ,¨]¸IÖFˆDÜ˜$¤Ô%Ø—‘˜TÕ"à˜Ÿ™›Ñ%‘ð	 Gñ ó
á�Ø—K’K A§K¡K£M×$5Ñ$5°iÓ$@ÀCÒ$Gò Øð 	ð 
ñ
 ÜÐMÓNÐNñ AKó
Ù@J¸1ŒE�M‰M˜!Ð/Ó0×4Ñ4Õ6À
ð 	ð 
ñ (8ÓKÑ'7 !¸1¿8¹8Àd»?šAÐ'7ÐÐKà”E—J‘JÒØ )§¡¨mÓ <ÐÜÐ+¬YÔ7Ø$5×$=Ñ$=¸nÓ$MÈaÑ$PÑ!à$5Ð!Û#3�ðØ'8×'<Ñ'<¸_Ó'MÑ$ñ $4ð "×+Ñ+¨MÓ:ˆIÜ˜)¤YÔ/Ø"+‘ØÐ"Ü"+£+‘ä"+¨Y¨KÓ"8�Û#3�ð
Ø(1×(;Ñ(;¸OÓ(LÐ%Ø(Ð4Ø'×.Ñ.Ø-×4Ñ4Ó6×>Ñ>¸~ÓNÈqÑQôøð	 $4ô  %Ÿz™z¨?Ð;Ðà!×(Ñ(Ó*×2Ñ2°>ÓBÀ1ÑEˆàˆùòo
ùò
ùò Løô !ò Ü—M‘MØEØ#$÷ð ðûô( !ò Ü—M‘MØEØ#$÷ðús=   Ä7KÅ +KÆKÆ&KÇ=KÉALË LÌLÌ L)Ì(L)c                ó¾  — t        |t        «      r>t        j                  |j                  Ž j                  t        |j                  «      «      S t        t        |j                   dz  «      «      j                  |j                  «      }t        j                  |j                  j                  |j                  j                  |j                  j                  |¬«      S )z)A box of the same dimensions and locationrÑ   )Úplane)r›   r2   rb   Úmake_boxÚsizeÚlocater4   Úminr6   rJ  ÚlocationÚXÚYrF  )rc   ÚbboxÚmoved_planes      rW   Úfrom_bounding_boxzSolid.from_bounding_box¸  s”   € ô �dœHÔ%Ü—>‘> 4§9¡9Ð-×4Ñ4´X¸d¿h¹hÓ5GÓHÐHä!&¤x°·±°
¸Q±Ó'?Ó!@×!EÑ!EÀdÇmÁmÓ!TˆKÜ—>‘>Ø—	‘	—‘˜TŸY™YŸ[™[¨$¯)©)¯+©+¸[ð "ó ð rY   c                ób   —  | t        |j                  «       |||«      j                  «       «      S )a<  make box

        Make a box at the origin of plane extending in positive direction of each axis.

        Args:
            length (float):
            width (float):
            height (float):
            plane (Plane, optional): base plane. Defaults to Plane.XY.

        Returns:
            Solid: Box
        )r   Ú	to_gp_ax2r>   )rc   rŒ   ÚwidthÚheightr‡  s        rW   rˆ  zSolid.make_boxÃ  s5   € ñ" ÜØ—‘Ó!ØØØó	÷
 ‰e‹gó
ð 	
rY   ih  c           
     ór   —  | t        |j                  «       ||||t        z  «      j                  «       «      S )af  make cone

        Make a cone with given radii and height

        Args:
            base_radius (float):
            top_radius (float):
            height (float):
            plane (Plane): base plane. Defaults to Plane.XY.
            angle (float, optional): arc size. Defaults to 360.

        Returns:
            Solid: Full or partial cone
        )r   r“  r0   r>   )rc   Úbase_radiusÚ
top_radiusr•  r‡  r7  s         rW   Ú	make_conezSolid.make_coneÝ  s<   € ñ. Ü Ø—‘Ó!ØØØØœ‘ó÷ ‰e‹gó
ð 	
rY   c           	     óp   —  | t        |j                  «       |||t        z  «      j                  «       «      S )av  make cylinder

        Make a cylinder with a given radius and height with the base center on plane origin.

        Args:
            radius (float):
            height (float):
            plane (Plane): base plane. Defaults to Plane.XY.
            angle (float, optional): arc size. Defaults to 360.

        Returns:
            Solid: Full or partial cylinder
        )r   r“  r0   r>   )rc   r¬   r•  r‡  r7  s        rW   Úmake_cylinderzSolid.make_cylinderþ  s9   € ñ* Ü$Ø—‘Ó!ØØØœ‘ó	÷
 ‰e‹gó
ð 	
rY   Fc                ó(   —  | t        |d|«      «      S )aë  make loft

        Makes a loft from a list of wires and vertices. Vertices can appear only at the
        beginning or end of the list, but cannot appear consecutively within the list
        nor between wires.

        Args:
            objs (list[Vertex, Wire]): wire perimeters or vertices
            ruled (bool, optional): stepped or smooth. Defaults to False (smooth).

        Raises:
            ValueError: Too few wires

        Returns:
            Solid: Lofted object
        T)rI   )rc   ÚobjsÚruleds      rW   rN  zSolid.make_loft  s   € ñ$ ”:˜d D¨%Ó0Ó1Ð1rY   i¦ÿÿÿéZ   c           
     óŽ   —  | t        |j                  «       ||t        z  |t        z  |t        z  «      j                  «       «      S )a£  Sphere

        Make a full or partial sphere - with a given radius center on the origin or plane.

        Args:
            radius (float):
            plane (Plane): base plane. Defaults to Plane.XY.
            angle1 (float, optional): Defaults to -90.
            angle2 (float, optional): Defaults to 90.
            angle3 (float, optional): Defaults to 360.

        Returns:
            Solid: sphere
        )r   r“  r0   r>   )rc   r¬   r‡  Úangle1Úangle2Úangle3s         rW   Úmake_spherezSolid.make_sphere0  sG   € ñ. Ü"Ø—‘Ó!ØØœÑ ØœÑ ØœÑ ó÷ ‰e‹gó
ð 	
rY   r   c                ó�   —  | t        |j                  «       |||t        z  |t        z  |t        z  «      j                  «       «      S )a¦  make torus

        Make a torus with a given radii and angles

        Args:
            major_radius (float):
            minor_radius (float):
            plane (Plane): base plane. Defaults to Plane.XY.
            start_angle (float, optional): start major arc. Defaults to 0.
            end_angle (float, optional): end major arc. Defaults to 360.

        Returns:
            Solid: Full or partial torus
        )r   r“  r0   r>   )rc   Úmajor_radiusÚminor_radiusr‡  Ústart_angleÚ	end_angleÚmajor_angles          rW   Ú
make_toruszSolid.make_torusQ  sJ   € ñ0 Ü!Ø—‘Ó!ØØØœgÑ%ØœGÑ#ØœgÑ%ó÷ ‰e‹gó	
ð 		
rY   c	                ój   —  | t        |j                  «       |||||||«      j                  «       «      S )aO  Make a wedge

        Args:
            delta_x (float):
            delta_y (float):
            delta_z (float):
            min_x (float):
            min_z (float):
            max_x (float):
            max_z (float):
            plane (Plane): base plane. Defaults to Plane.XY.

        Returns:
            Solid: wedge
        )r   r“  rb   )	rc   Údelta_xÚdelta_yÚdelta_zÚmin_xÚmin_zÚmax_xÚmax_zr‡  s	            rW   Ú
make_wedgezSolid.make_wedget  sA   € ñ6 Ü!Ø—‘Ó!ØØØØØØØó	÷ ‰e‹gó
ð 	
rY   c                óÊ   — |r|ng }t        |t        «      rt        ||«      }n|}t        |j                  |j                  |t
        z  d«      } | |j                  «       «      S )a¼  Revolve

        Revolve a cross section about the given Axis by the given angle.

        Args:
            section (Union[Face,Wire]): cross section
            angle (float): the angle to revolve through
            axis (Axis): rotation Axis
            inner_wires (list[Wire], optional): holes - only used if section is of type Wire.
                Defaults to [].

        Returns:
            Solid: the revolved cross section
        T)r›   r<   rE   r   rr   r0   r>   )rc   r6  r7  Úaxisr1  Úsection_faceÚrevol_builders          rW   ÚrevolvezSolid.revolveœ  sb   € ñ, &1‘k°bˆÜ�gœtÔ$Ü ¨Ó5‰Là"ˆLä-Ø× Ñ Ø�L‰LØ”G‰OØó	
ˆñ �=×&Ñ&Ó(Ó)Ð)rY   c                ó¶  — t        |t        «      r!|j                  «       }|j                  «       }n|}|r|ng }g }	|g|z   D ]å  }
t	        |j                  «       j                  «      }d}|rt        j                  |||«      }n|j                  |«       |j                  t        j                  |   «       |j                  |
j                  d|«       |j                  «        |r|j                  «        |	j!                  t"        j%                  |j                  «       «      «       Œç |	d   |	dd }}|r# |j&                  |Ž }t        |t        «      sJ ‚|S |S )a)  Sweep

        Sweep the given cross section into a prismatic solid along the provided path

        Args:
            section (Union[Face, Wire]): cross section to sweep
            path (Union[Wire, Edge]): sweep path
            inner_wires (list[Wire]): holes - only used if section is a wire
            make_solid (bool, optional): return Solid or Shell. Defaults to True.
            is_frenet (bool, optional): Frenet mode. Defaults to False.
            mode (Union[Vector, Wire, Edge, None], optional): additional sweep
                mode parameters. Defaults to None.
            transition (Transition, optional): handling of profile orientation at C1 path
                discontinuities. Defaults to Transition.TRANSFORMED.

        Returns:
            Solid: the swept cross section
        Fr   r:   N)r›   rE   r0  r1  r   r  rr   rb   r%  r  ÚSetTransitionModer>   Ú_transModeDictrˆ   r¹   r*  rL  rQ   rg   rP  )rc   r6  r!  r1  Ú
make_solidÚ	is_frenetÚmodeÚ
transitionr0  Úshapesr  r   r#  Úouter_shapeÚinner_shapesÚhollow_outer_shapes                   rW   ÚsweepzSolid.sweepÁ  s4  € ô: �gœtÔ$Ø ×+Ñ+Ó-ˆJØ!×-Ñ-Ó/‰Kà ˆJÙ)4™+¸"ˆKàˆØ�L ;Ô.ˆDÜ1°$·,±,³.×2HÑ2HÓIˆGàˆFñ Ü×.Ñ.¨w¸¸dÓC‘à—‘ 	Ô*à×%Ñ%¤e×&:Ñ&:¸:Ñ&FÔGà�K‰K˜Ÿ™ e¨VÔ4à�M‰MŒOÙØ×!Ñ!Ô#à�M‰Mœ'Ÿ,™, w§}¡}£Ó7Õ8ð' /ð* %+¨1¡I¨v°a°b¨z�\ˆáØ!0 §¡°,Ð!?ÐÜÐ0´%Ô8Ð8Ð8Ø%Ð%àÐrY   c                ó²  — |j                  «       j                  }t        |«      }d}d}	|r| j                  |||«      }	n|j	                  |«       |D ]K  }
t        |
t        «      r|
j                  n|
j                  «       j                  }|j                  |||	«       ŒM |j                  «        |r|j                  «         | |j                  «       «      S )aa  Multi section sweep

        Sweep through a sequence of profiles following a path.

        Args:
            profiles (Iterable[Union[Wire, Face]]): list of profiles
            path (Union[Wire, Edge]): The wire to sweep the face resulting from the wires over
            make_solid (bool, optional): Solid or Shell. Defaults to True.
            is_frenet (bool, optional): Select frenet mode. Defaults to False.
            binormal (Union[Vector, Wire, Edge, None], optional): additional sweep mode parameters.
                Defaults to None.

        Returns:
            Solid: swept object
        F)r  rr   r   r%  r  r›   r<   r0  rˆ   r¹   r*  r>   )rc   Úprofilesr!  r½  r¾  r"  Úpath_as_wirer   Ú	translater#  rQ  s              rW   Úsweep_multizSolid.sweep_multi  s¿   € ð0 —|‘|“~×-Ñ-ˆä-¨lÓ;ˆàˆ	ØˆáØ×(Ñ(¨°$¸ÓA‰Fà�O‰O˜IÔ&ãˆGô ˜g¤tÔ,ð —’à×'Ñ'Ó)×1Ñ1ð ð
 �K‰K˜ i°Õ8ð  ð 	�‰ŒáØ×ÑÔá�7—=‘=“?Ó#Ð#rY   c                óâ  — |}t        |t        «      r_|�]|j                  «       }|j                  |«      j	                  «       }|j                  t        |«      j	                  «       «      dk  r| }t        «       }|j                  |j                  |dt        ddt        dd¬«	       |j                  «        	 t        |j                  «       «      }|S # t        $ r}	t!        d«      |	‚d}	~	ww xY w)a€  Thicken Face or Shell

        Create a solid from a potentially non planar face or shell by thickening along
        the normals.

        .. image:: thickenFace.png

        Non-planar faces are thickened both towards and away from the center of the sphere.

        Args:
            depth (float): Amount to thicken face(s), can be positive or negative.
            normal_override (Vector, optional): Face only. The normal_override vector can be
                used to indicate which way is 'up', potentially flipping the face normal
                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.

        Raises:
            RuntimeError: Opencascade internal failures

        Returns:
            Solid: The resulting Solid object
        Nr   gñhãˆµøä>TF)ÚOffsetÚTolÚModer±   Ú	SelfInterr²   Ú
Thickeningrå   z'Error applying thicken to given surface)r›   rE   rv   rD  rC  rl  r7   r   Ú
Initializerr   r   r   ÚMakeOffsetShaperb   r>   r!   rÒ   )
rc   Úsurfacer    Únormal_overrideÚadjusted_depthÚsurface_centerÚsurface_normalrê   r„  r˜   s
             rW   ÚthickenzSolid.thicken7  sñ   € ð> ˆÜ�gœtÔ$¨Ð)DØ$Ÿ^™^Ó-ˆNØ$×.Ñ.¨~Ó>×IÑIÓKˆNØ×!Ñ!¤&¨Ó"9×"DÑ"DÓ"FÓGÈ!ÒKØ"' �ä.Ó0ˆØ×!Ñ!Ø�O‰OØ!ØÜ ð ØÜ%ØØð 	"ô 	
ð 	×&Ñ&Ô(ð	SÜ˜>×/Ñ/Ó1Ó2ˆFð ˆøô ò 	SÜÐHÓIÈsÐRûð	Sús   Â9C Ã	C.ÃC)Ã)C.)Nr  Nr  NN)rd   zTopoDS_Solid | Shell | Noner  Ústrr  zColor | Noner  rÙ  r  zdict[str, Joint] | Noner  zCompound | None)rô   rÝ   )r  rF   rô   r(   )r   r   r!  úWire | Edger"  zVector | Wire | Edgerô   rø   )rd   rE   rk   r8   rô   rb   r}   )r6  úFace | Wirerv   r8   r/  r8   r7  rÝ   r1  úlist[Wire] | Nonerô   rb   )T)
rQ  rE   rk   r8   r¡   rÝ   rR  rø   rô   rb   )
r6  rE   rs  úCompound | Solidrk   r8   rt  r/   rô   rÝ  )r�  zBoundBox | OrientedBoundBoxrô   rb   )
rŒ   rÝ   r”  rÝ   r•  rÝ   r‡  r6   rô   rb   )r—  rÝ   r˜  rÝ   r•  rÝ   r‡  r6   r7  rÝ   rô   rb   )
r¬   rÝ   r•  rÝ   r‡  r6   r7  rÝ   rô   rb   )F)r�  zIterable[Vertex | Wire]rž  rø   rô   rb   )r¬   rÝ   r‡  r6   r¡  rÝ   r¢  rÝ   r£  rÝ   rô   rb   )r¦  rÝ   r§  rÝ   r‡  r6   r¨  rÝ   r©  rÝ   rª  rÝ   rô   rb   )r­  rÝ   r®  rÝ   r¯  rÝ   r°  rÝ   r±  rÝ   r²  rÝ   r³  rÝ   r‡  r6   rô   rb   )
r6  rÛ  r7  rÝ   r¶  r1   r1  rÜ  rô   rb   )r6  rÛ  r!  rÚ  r1  rÜ  r½  rø   r¾  rø   r¿  úVector | Wire | Edge | NonerÀ  r.   rô   rb   )TFN)rÇ  zIterable[Wire | Face]r!  rÚ  r½  rø   r¾  rø   r"  rÞ  rô   rb   )rÓ  zFace | Shellr    rÝ   rÔ  zVectorLike | Nonerô   rb   )"rû   rü   rý   rþ   Úorderr  r  rç   r  r  r%  rl   r@  rc  r/   rh  r…  r‘  r6   ÚXYrˆ  r™  r›  rN  r¤  r«  r´  r¹  r.   ÚTRANSFORMEDrÅ  rÊ  rØ  Ú__classcell__)rŠ   s   @rW   rb   rb   M  sš  ø„ ñ=ð €Eð
 ,0ØØ"ØØ*.Ø"&ð7à(ð7ð ð7ð ð	7ð
 ð7ð (ð7ð  õ7ðF ò(ó ð(ð ò>ó ð>ð ðà,ðð ðð 'ð	ð
 
òó ðð& òTó ðTð" ð *.ðPGàðPGð ðPGð ð	PGð
 ðPGð 'ðPGð 
òPGó ðPGðd àTXðHØðHØ'1ðHØ:?ðHØMQðHà	òHó ðHðT ð —z‘zðiàðið (ðið ð	ið
 ðið 
òió ðiðV òó ðð àHMÏÉð
Øð
Ø#(ð
Ø27ð
Ø@Eð
à	ò
ó ð
ð2 ð —x‘xØð
àð
ð ð
ð ð	
ð
 ð
ð ð
ð 
ò
ó ð
ð@ ð
 —x‘xØð
àð
ð ð
ð ð	
ð
 ð
ð 
ò
ó ð
ð: ó2ó ð2ð& ð —x‘xØØØð
àð
ð ð
ð ð	
ð
 ð
ð ð
ð 
ò
ó ð
ð@ ð
 —x‘xØØØ ð 
àð 
ð ð 
ð ð	 
ð
 ð 
ð ð 
ð ð 
ð 
ò 
ó ð 
ðD ð —x‘xð%
àð%
ð ð%
ð ð	%
ð
 ð%
ð ð%
ð ð%
ð ð%
ð ð%
ð 
ò%
ó ð%
ðN ð *.ð"*àð"*ð ð"*ð ð	"*ð
 'ð"*ð 
ò"*ó ð"*ðH ð
 *.ØØØ,0Ø!+×!7Ñ!7ð@àð@ð ð@ð 'ð	@ð
 ð@ð ð@ð *ð@ð ð@ð 
ò@ó ð@ðD ð
  ØØ04ð0$à'ð0$ð ð0$ð ð	0$ð
 ð0$ð .ð0$ð 
ò0$ó ð0$ðd ð
 .2ð	9àð9ð ð9ð +ð	9ð
 
ò9ó ô9rY   rb   )srþ   Ú
__future__r   rß   ro  Úmathr   r   r   Útypingr   r   Úcollections.abcr	   Ú
OCP.TopAbsÚTopAbsr[   ÚOCP.BRepAlgoAPIr
   ÚOCP.BRepBuilderAPIr   ÚOCP.BRepClass3dr   ÚOCP.BRepFeatr   ÚOCP.BRepFilletAPIr   r   ÚOCP.BRepOffsetr   r   ÚOCP.BRepOffsetAPIr   r   ÚOCP.BRepPrimAPIr   r   r   r   r   r   r   Ú	OCP.GPropr   ÚOCP.GeomAbsr   r   Ú
OCP.LocOper   ÚOCP.ShapeFixr   ÚOCP.Standardr    ÚOCP.StdFailr!   Ú
OCP.TopExpr"   ÚOCP.TopToolsr#   r$   Ú
OCP.TopoDSr%   r&   r'   r(   r)   ÚOCP.gpr*   r+   Úbuild123d.build_enumsr,   r-   r.   r/   Úbuild123d.geometryr0   r1   r2   r3   r4   r5   r6   r7   r8   Útyping_extensionsr9   Úone_dr;   r<   r=   Ú
shape_corer>   r?   r@   rA   rB   Útwo_drC   rD   rE   rF   ÚutilsrG   rH   rI   rJ   Úzero_drK   Ú	compositerL   rM   rN   rO   rQ   rb   rT   rY   rW   Ú<module>r     sÖ   ðñ4õl #ã Û ß "Ñ "ß 'å $å Ý +Ý 7Ý 7Ý ,ß Qß Aß W÷÷ ñ õ #ß >Ý $Ý 'Ý )Ý 'Ý ß Xß SÕ Sß !ß CÓ C÷
÷ 
õ 
õ #ç &Ñ &ß DÕ Dß BÓ B÷ó õ ñ ß8Ó8ôQ3ˆeô Q3ôhdˆG�U˜<Ñ(õ drY   