
    Og/;                        d dl mZ d dlmZmZmZmZ d dlmZm	Z	m
Z
 d dlmZmZmZmZ ddlmZ ddlmZmZmZmZmZ dddZ	 	 	 	 dd	Z	 d	 	 	 	 	 ddZdddZddZ G d d      ZddZddZdddZy
)    )annotations)IteratorSequenceOptionalIterable)MeshVertexMergerMeshTransformerMeshBuilder)Matrix44Vec3NULLVECBoundingBox   )entities)BodyLumpNONE_REFFaceShellc                j   t        | t              st        dt        |              g }t	               }t        |       D ]K  }|D ]  }|j                  |        |r|j                  t        j                  |             t	               }M |r$|j                  t        j                  |             |S )a  Returns a list of :class:`~ezdxf.render.MeshTransformer` instances from
    the given ACIS :class:`Body` entity.
    The list contains multiple meshes if `merge_lumps` is ``False`` or just a
    single mesh if `merge_lumps` is ``True``.

    The ACIS format stores the faces in counter-clockwise orientation where the
    face-normal points outwards (away) from the solid body (material).

    .. note::

        This function returns meshes build up only from flat polygonal
        :class:`Face` entities, for a tessellation of more complex ACIS
        entities (spline surfaces, tori, cones, ...) is an ACIS kernel
        required which `ezdxf` does not provide.

    Args:
        body: ACIS entity of type :class:`Body`
        merge_lumps: returns all :class:`Lump` entities
            from a body as a single mesh if ``True`` otherwise each :class:`Lump`
            entity is a separated mesh

    Raises:
        TypeError: given `body` entity has invalid type

    expected a body entity, got: )

isinstancer   	TypeErrortyper   flat_polygon_faces_from_bodyadd_faceappendr	   from_builder)bodymerge_lumpsmeshesbuilderfacesfaces         T/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/acis/mesh.pymesh_from_bodyr&      s    4 dD!7T
|DEE$&F G-d3 ) 	#DT"	#MM/66w?@&(G) o227;<M    c              #  8  K   t        | t              st        dt        |              | j                  }| j
                  }d}|j                  s|j                  }|j                  s1t        t        ||             |j                  }|j                  s0yyw)a$  Yields all flat polygon faces from all lumps in the given
    :class:`Body` entity.
    Yields a separated list of faces for each linked :class:`Lump` entity.

    Args:
        body: ACIS entity of type :class:`Body`

    Raises:
        TypeError: given `body` entity has invalid type

    r   N)r   r   r   r   lump	transformis_nonematrixlistflat_polygon_faces_from_lump	next_lump)r   r)   r*   ms       r%   r   r   5   s      dD!7T
|DEE99DI All/a899~~ lls   BBBNc              #    K   t        | t              st        dt        |              | j                  }|j
                  ryg }|j                  }|j
                  sKt        }|j                          |j                  j                  dk(  r	 |j                  j                  }|}|j
                  s|j                  }	 |j                  j                  dk7  rn|j                  r0|j!                  |j"                  j$                  j&                         n/|j!                  |j(                  j$                  j&                         |j*                  }||u r-|t-        |j/                  |             nt-        |       n|j
                  s|j0                  }|j
                  sJyy# t        $ r Y w xY w# t        $ r Y 7w xY ww)av  Yields all flat polygon faces from the given :class:`Lump` entity as
    sequence of :class:`~ezdxf.math.Vec3` instances. Applies the transformation
    :class:`~ezdxf.math.Matrix44` `m` to all vertices if not ``None``.

    Args:
        lump: :class:`Lump` entity
        m: optional transformation matrix

    Raises:
        TypeError: `lump` has invalid ACIS type

    expected a lump entity, got: Nzplane-surfacezstraight-curve)r   r   r   r   shellr+   r$   r   clearsurfaceloopcoedgeAttributeErroredgecurvesenser   
end_vertexpointlocationstart_vertexnext_coedgetupletransform_vertices	next_face)r)   r0   r3   verticesr$   first_coedger7   r9   s           r%   r.   r.   Q   sz     dD!7T
|DEEJJE}}H::Dll<</#yy// ..;;D::??&66<<OODOO$9$9$B$BCOOD$5$5$;$;$D$DE
 ''F%= 4 4X >??/)- ... ~~A ll "  "  sh   BG	F* $G	?F: G	A+F: A	G	G	(G	*	F73G	6F77G	:	GG	GG	c                   | j                  |      } t               }t        | j                        }|j                  j
                  sX| j                  |j                          t        j                         }t        j                  |j                   |_
        ||_        | j                         D ]  } t        |       }|j                  |         |S )a#  Returns a :term:`ACIS` :class:`~ezdxf.acis.entities.Body` entity from a
    :class:`~ezdxf.render.MeshBuilder` instance.

    This entity can be assigned to a :class:`~ezdxf.entities.Solid3d` DXF entity
    as :term:`SAT` or :term:`SAB` data according to the version your DXF
    document uses (SAT for DXF R2000 to R2010 and SAB for DXF R2013 and later).

    If the `mesh` contains multiple separated meshes, each mesh will be a
    separated :class:`~ezdxf.acis.entities.Lump` node.
    If each mesh should get its own :class:`~ezdxf.acis.entities.Body` entity,
    separate the meshes beforehand by the method
    :meth:`~ezdxf.render.MeshBuilder.separate_meshes`.

    A closed mesh creates a solid body and an open mesh creates an open (hollow)
    shell. The detection if the mesh is open or closed is based on the edges
    of the mesh: if **all** edges of mesh have two adjacent faces the mesh is
    closed.

    The current implementation applies automatically a vertex optimization,
    which merges coincident vertices into a single vertex.

    )optimize_verticesr   r   rD   centeris_null	translater   	Transformr   r,   r*   separate_mesheslump_from_meshappend_lump)mesh	precisionr   bboxr*   r)   s         r%   body_from_meshrR      s    . !!),D6Dt}}%D;;|$&&(	#--t{{;	"$$& d# Kr'   c                    t               }t               }|j                  |       t        |       }|j	                         D ]  }|j                  |        |S )zReturns a :class:`~ezdxf.acis.entities.Lump` entity from a
    :class:`~ezdxf.render.MeshBuilder` instance. The `mesh` has to be a single
    body or shell!
    )r   r   append_shellPolyhedronFaceBuilder
acis_facesappend_face)rO   r)   r3   face_builderr$   s        r%   rM   rM      sU    
 6DGEe(.L'')  $ Kr'   c                  Z    e Zd Zd
dZd ZddZddZddZddZ	 	 	 	 	 	 	 	 ddZ	ddZ
y	)rU   c                L   |j                         }|j                          |j                  | _        |j                  | _        t	        |j                               | _        g | _        |j                         j                  | _
        t               | _        t               | _        y N)copynormalize_facesrD   r#   r-   face_normalsnormalsacis_verticesdiagnoseis_edge_balance_brokendouble_sideddictpartner_coedgesedges)selfrO   	mesh_copys      r%   __init__zPolyhedronFaceBuilder.__init__   s~    IIK	!!#$-$6$6*3//
I224546 &..0GG HLv;?6
r'   c                    t        t        | j                              | _        | j                  j                          | j                  j                          y r[   )r-   make_verticesrD   r`   re   r4   rf   )rg   s    r%   resetzPolyhedronFaceBuilder.reset   s:    !-">?""$

r'   c                   | j                          g }t        | j                  | j                        D ]  \  }}|j                  rt               }| j                  |      }|1||_        | j                  |      }|L|j                  |       ||_
        d|_        | j                  |_        |j                  |        |S )NF)rl   zipr#   r_   rI   r   
make_planenormal	make_loopappend_loopr5   r;   rc   r   )rg   r#   r$   face_normal	acis_faceplaner6   s          r%   rV   z PolyhedronFaceBuilder.acis_faces   s    

!$TZZ!> 	$D+""IOOD)E}&EL>>$'D|!!$' %I#IO%)%6%6I"LL#	$$ r'   c                   t        |      dkD  sJ d       t        j                         }d|_        | j                  |d      |_        	 | j                  |d      |j
                  z
  j                         |_        |S # t        $ r Y y w xY w)Nr   zface requires least 2 verticesFr   )	lenr   Plane	reverse_vrD   origin	normalizeu_dirZeroDivisionError)rg   r$   ru   s      r%   ro   z PolyhedronFaceBuilder.make_plane   s    4y1}>>>} }}T!W-	==a1ELL@KKMEK  ! 		s   	2A= =	B	B	c                `   g }t        |dd        }|d   |d   k7  r|j                  |d          t        ||      D ]H  \  }}| j                  ||      }| j	                  |||      \  |_        |_        |j                  |       J t        j                         }|j                  |d       |S )Nr   r   T)close)
r-   r   rn   make_coedge	make_edger9   r;   r   Loopset_coedges)rg   r$   coedgesface2i1i2r7   r6   s           r%   rq   zPolyhedronFaceBuilder.make_loop   s    )+T!"X7d2hLLa!$& 	#FB%%b"-F(,r2v(F%FKNN6"	# }}-r'   c                    ||kD  r||f}n||f}t        j                         }	 | j                  |   }|j                  |       |S # t        $ r || j                  |<   Y |S w xY wr[   )r   Coedgere   add_partner_coedgeKeyError)rg   index1index2keyr7   partner_coedges         r%   r   z!PolyhedronFaceBuilder.make_coedge  sy    F?&.C&.C"	6!11#6N --f5	  	/(.D  % 		/s   A A"!A"c                    d fd}d}|}|}||kD  rd}||}}	  j                   ||f   |fS # t        $ r Y nw xY wt        j                         |_        d_         ||      _        d_         ||      _         j                  |   j                   j                  |         _         j                  ||      _         j                   ||f<   |fS )Nc                    j                   |    }|xj                  dz  c_        |j                  j                  r|_        |S )Nr   )r`   	ref_countr9   r+   )indexvertexr9   rg   s     r%   make_vertexz4PolyhedronFaceBuilder.make_edge.<locals>.make_vertex  s=    ''.F!{{"""Mr'   FTg        )r   int)rf   r   r   Edger7   r;   r?   start_paramr<   rD   distance	end_parammake_rayr:   )	rg   r   r   parentr   r;   ex1ex2r9   s	   `       @r%   r   zPolyhedronFaceBuilder.make_edge  s    	 9ECC	::c3h'.. 		 }}
',%c*s+44T]]35GH]]3,
#

38U{s   / 	;;c                    | j                   |   }| j                   |   }t        j                         }||_        	 ||z
  j	                         |_        |S # t        $ r t        |_        Y |S w xY wr[   )rD   r   StraightCurverz   r{   	directionr}   r   )rg   r   r   v1v2rays         r%   r   zPolyhedronFaceBuilder.make_ray=  sp    ]]6"]]6"$$&
	$"W//1CM 
 ! 	$#CM
	$s   A A-,A-N)rO   r
   )returnz
list[Face])r$   Sequence[int]r   zOptional[entities.Plane])r$   r   r   zOptional[entities.Loop])r   r   r   r   r   entities.Coedge)r   r   r   r   r   r   r   ztuple[entities.Edge, bool])r   r   r   r   r   zentities.StraightCurve)__name__
__module____qualname__ri   rl   rV   ro   rq   r   r   r    r'   r%   rU   rU      sL    B.
.
  #& 0? 	# D	r'   rU   c              #     K   | D ]<  }t        j                         }||_        t        j                         }||_        | > y wr[   )r   Pointr>   Vertexr=   )rD   vr=   r   s       r%   rk   rk   I  s@       "s   AAc                <   t        | t              st        dt        |              | j                  }| j
                  }g }d}|j                  s|j                  }|j                  s4|j                  t        ||             |j                  }|j                  s4|S )a  Returns all stored vertices in the given :class:`Body` entity.
    The result is not optimized, meaning the vertices are in no particular order and
    there are duplicates.

    This function can be useful to determining the approximate bounding box of an 
    :term:`ACIS` entity.  The result is exact for polyhedra with flat faces with 
    straight edges, but not for bodies with curved edges and faces.

    Args:
        body: ACIS entity of type :class:`Body`

    Raises:
        TypeError: given `body` entity has invalid type

    r   N)r   r   r   r   r)   r*   r+   r,   extendvertices_from_lumpr/   )r   r)   r*   rD   r0   s        r%   vertices_from_bodyr   R  s    " dD!7T
|DEE99DIH All*434~~ ll Or'   c                   t        | t              st        dt        |              g }| j                  }|j
                  r|S |j                  }|j
                  st        }	 |j                  j                  }|}|j
                  s|j                  }	 |j                  |j                  j                  j                         |j                  |j                   j                  j                         |j"                  }||u rn|j
                  s|j$                  }|j
                  s|t'        |j)                  |            S |S # t        $ r Y w xY w# t        $ r Y Qw xY w)aA  Returns all stored vertices from a given :class:`Lump` entity. 
    Applies the transformation :class:`~ezdxf.math.Matrix44` `m` to all vertices if not 
    ``None``.

    Args:
        lump: :class:`Lump` entity
        m: optional transformation matrix

    Raises:
        TypeError: `lump` has invalid ACIS type

    r2   )r   r   r   r   r3   r+   r$   r   r6   r7   r8   r9   r   r?   r=   r>   r<   r@   rC   r-   rB   )r)   r0   rD   r3   r$   rE   r7   r9   s           r%   r   r   r  s>    dD!7T
|DEEHJJE}}::Dll	99++L ..;;D 1 1 7 7 @ @A 5 5 > >?
 ''F% .. ~~) ll* 	}A((233O'  		 "  s%   #E AE 	EE	E"!E")T)r   r   r   zlist[MeshTransformer])r   r   r   zIterator[list[Sequence[Vec3]]]r[   )r)   r   r0   Matrix44 | Noner   zIterator[Sequence[Vec3]])   )rO   r
   rP   r   r   r   )rO   r
   r   r   )rD   zIterable[Vec3]r   zIterator[entities.Vertex])r   r   r   
list[Vec3])r)   r   r0   r   r   r   ) 
__future__r   typingr   r   r   r   ezdxf.renderr   r	   r
   
ezdxf.mathr   r   r   r    r   r   r   r   r   r   r&   r   r.   rR   rM   rU   rk   r   r   r   r'   r%   <module>r      s    # 9 9 G G ; ;  7 7'T
#: &*7
7"77t#LG GT@-r'   