
    ^j                     R   d Z ddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZ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 ddlmZmZ dd	lmZ 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&m'Z' ddl(m)Z) ddl*m+Z+m*Z* ddl,m-Z- ddl.m/Z/m0Z0m1Z1  G d dejd                        Z3 G d d      Z4y)z
B-spline algorithms and utilities.

This module provides static methods for B-spline manipulation, including
parameter computation, degree matching, knot vector manipulation, and
other B-spline operations.
    N)BSplCLib)Geom_BSplineCurveGeom_BSplineSurface
Geom_Conic
Geom_CurveGeom_TrimmedCurve)Geom2dAPI_InterpolateGeom2dAPI_ProjectPointOnCurve)
GeomAbs_C1
GeomAbs_C2)GeomConvertGeomConvert_ApproxCurve)gp_Pntgp_Pnt2d)math_Matrix)	Precision)TColgp_Array1OfPntTColgp_Array2OfPntTColgp_HArray1OfPntTColgp_HArray1OfPnt2d)TColStd_Array1OfIntegerTColStd_Array1OfRealTColStd_HArray1OfIntegerTColStd_HArray1OfReal   )ApproxResult)	ErrorCodeerror)IntersectBSplines)clone_bsplineclone_bspline_surfacesave_bsplines_to_filec                       e Zd ZdZdZdZy)SurfaceDirectionr   r      N)__name__
__module____qualname__uvboth     _/opt/ringagent/.cad-venv/lib/python3.12/site-packages/ocp_gordon/internal/bspline_algorithms.pyr$   r$   0   s    	A	ADr-   r$   c                      e Zd ZdZdZdZededededefd       Z	ed	ed
ede
dee   dee   f
d       Zedededefd       Zedededefd       Zededee   fd       Z G d d      Zededdfd       Zeded	ed
edefd       Ze	 dZdededee   fd       Ze	 d[dee   deddfd       Zedee   ddfd       Zedee   d edee   fd!       Ze	 d[d"ed	ed
ed eddf
d#       Zed$ee   dee   fd%       Ze	 d\d&ed'ededeeeef      fd(       Zed"edefd)       Z edee   defd*       Z!ededefd+       Z"ede#defd,       Z$ed-eee   z  ez  e#z  defd.       Z%ed"edee   fd/       Z&ed"ed0ed ede
fd1       Z'ed"edee(   fd2       Z)ed"edee   fd3       Z*ed"ed4ee   d5ee
   d edef
d6       Z+ed"ed7ee   d8ee   d9e
de,f
d:       Z-ed"ed	ed
edefd;       Z.ededefd<       Z/e	 d]d=ee   d>e
d?edee   fd@       Z0e	 d^d>e
d4e1d=e1dAe
de2jf                  f
dB       Z4ede#defdC       Z5ed]dedDedefdE       Z6edFee   de7fdG       Z8edFee
   de9fdH       Z:edIedJe
defdK       Z;edIedLe
defdM       Z<e	 dZdededeee   ee   f   fdN       Z=ededefdO       Z>e	 d_d0edPe
d>e
d4ee   dQee
   d efdR       Z? G dS dT      Z@ G dU dV      ZAededW   dXedefdY       ZBy)`BSplineAlgorithmszF
    Utility class with static methods for B-spline manipulation.
    :0yE>h㈵>valuetarget	tolerancereturnc                 $    t        | |z
        |k  S )zDHelper function to check if a value is within tolerance of a target.absr3   r4   r5   s      r.   _is_inside_tolerancez&BSplineAlgorithms._is_inside_toleranceA   s     56>"Y..r-   uminumaxn_valuesbreaksc                 b   |dk  r
|dk(  r| gS g S || z
  |dz
  z  }t        |      D cg c]
  }| ||z  z    }}d}|D ]  }d}	t        |      D ](  \  }}
t        j                  |
|||z        s!|||<   |}	 n |	dk(  sAd}t	        d      }t        |      D ]  \  }}
t        |
|z
        }||k  s|}|} |dk7  r1||   |kD  r|j                  ||       |j                  |dz   |       |s|j                  |       t        j                  ||      }|j                  ||        |S c c}w )a3  
        Generates a sequence of evenly spaced values over a specified interval,
        including specified break points. This is a Python port of the C++
        LinspaceWithBreaks function.

        Args:
            umin: The starting value of the sequence.
            umax: The ending value of the sequence.
            n_values: The number of evenly spaced values to generate.
            breaks: A list of break points to include in the sequence.

        Returns:
            A list of values including the evenly spaced points and break points.
        r%   r   g333333?inf)
range	enumerater0   r;   floatr9   insertappendbisectbisect_left)r<   r=   r>   r?   duiresulteps
breakpoint	found_posvalclosest_idxmin_distdist
insert_poss                  r.   linspace_with_breaksz&BSplineAlgorithms.linspace_with_breaksF   st   $ a<%]D622Tkhl+).x9A$R-99  &	>JI#F+ 3$99#z2PS8T *F1I !I	 B
 ! <'/ (FAssZ/0Dh#'&'	( "$ k*Z7k:>kAozB "j1 &,%7%7
%K
j*=M&	>P Y :s   D,pointsc                     d}| j                         }| j                         }t        | j                         | j	                         dz         D ]+  } | ||      } | ||      }|j                  ||      r(d} |S  |S NTr   F)LowerRowUpperRowrC   LowerColUpperColIsEqual)rV   r5   u_dir_closedulouhiv_idxpfirstpLasts           r.   is_u_dir_closedz!BSplineAlgorithms.is_u_dir_closed   s    oooo6??,foo.?!.CD 	EC'F3&E>>%3$	 r-   c                     d}| j                         }| j                         }t        | j                         | j	                         dz         D ]'  } | ||      j                   | ||      |      r$d} |S  |S rX   )r[   r\   rC   rY   rZ   r]   )rV   r5   v_dir_closedvlovhiu_idxs         r.   is_v_dir_closedz!BSplineAlgorithms.is_v_dir_closed   s    oooo6??,foo.?!.CD 	E%%--uc"I  %	 r-   curvec                    | t        dt        j                        d}g }t        d| j	                               D ]  }| j                  |      | j                         k(  s&| j                  |      }| j                  ||z   d      }| j                  ||z
  d      }|j                  |      }d}t        |      |k  rt        |t        j                  z
        |k  r|j                  |        |S )NzNull Pointer curver1   r%   r   g-C6?)r   r   NULL_POINTERrC   NbKnotsMultiplicityDegreeKnotDNAngler9   mathpirG   )	rk   rM   kinks
knot_indexknottangent1tangent2angleangle_tolerances	            r.   get_kink_parametersz%BSplineAlgorithms.get_kink_parameters   s    =,i.D.DEE5==?3 	'J!!*-?zz*- !88D3J2 88D3J2 !x0 #'
 J05477?+o=LL&)	'* r-   c                       e Zd Zd Zy)BSplineAlgorithms.SurfaceKinksc                      g | _         g | _        y N)r)   r*   selfs    r.   __init__z'BSplineAlgorithms.SurfaceKinks.__init__   s    "$DF"$DFr-   N)r&   r'   r(   r   r,   r-   r.   SurfaceKinksr      s    	%r-   r   surfacer   c                    | t        dt        j                        t        j	                         }t        d| j                               D ]Q  }| j                  |      | j                         k(  s&| j                  |      }|j                  j                  |       S t        d| j                               D ]Q  }| j                  |      | j                         k(  s&| j                  |      }|j                   j                  |       S |S )NzNull Pointer surfacer%   )r   r   rm   r0   r   rC   NbUKnotsUMultiplicityUDegreeUKnotr)   rG   NbVKnotsVMultiplicityVDegreeVKnotr*   )r   rv   rw   rx   s       r.   get_kink_parameters_surfacez-BSplineAlgorithms.get_kink_parameters_surface   s     ?.	0F0FGG!..07#3#3#56 	%J$$Z0GOO4EE}}Z0t$	%
  7#3#3#56 	%J$$Z0GOO4EE}}Z0t$	% r-   c                 @    t        |       }|j                  ||       |S r   )r    Segment)rk   r<   r=   copys       r.   
trim_curvezBSplineAlgorithms.trim_curve   s!     U#T4 r-   alphac                 &   | j                         }|dk  r|dk(  rddgS g S g }d}t        d|      D ]  } | |      } | |dz         }|j                         |j                         z
  }|j                         |j                         z
  }	|j	                         |j	                         z
  }
t        j                  ||z  |	|	z  z   |
|
z  z         }|j                  ||z         ||d   z  } dg}d}|D ]  }||z  }|j                  ||z          |S )a  
        Computes parameters of a B-spline curve at given points.

        Args:
            points: Points where parameters are computed
            alpha: Exponent for parameter computation (0.5 = centripetal method)

        Returns:
            List of computed parameters
        r%   r                 ?rA   )LengthrC   XYZrt   sqrtrG   )rV   r   n_pointschord_lengthstotal_lengthrK   p1p2dxdydzlengthparamscurrent_lengths                 r.   compute_params_bspline_curvez.BSplineAlgorithms.compute_params_bspline_curve   s(    ==?a<!)QC:6B6  q(# 	.ABAB"$$&B"$$&B"$$&BYYrBwb027:;F  /M"--L	. # 	9Ff$NMM.<78	9 r-   bsplinesNc                    | sy| d   }|j                         }|j                         }| dd D ]]  }|j                         }|j                         }t        ||z
        |kD  st        ||z
        |kD  sFt        j	                  ||||       _ y)z
        Matches parameter range of all B-splines to the first B-spline.

        Args:
            bsplines: List of B-splines to match (modified in place)
            tolerance: Tolerance for parameter comparison
        Nr   r   )FirstParameterLastParameterr9   r0   reparametrize_bspline)r   r5   first_splineumin_refumax_refspliner<   r=   s           r.   match_parameter_rangez'BSplineAlgorithms.match_parameter_range  s     {..0--/qrl 	F((*D'')D4(?#i/3th3G)3S!77Hh		r-   c                     | syt        d | D              }| D ])  }|j                         }||k  s|j                  |       + y)z
        Matches degree of all B-splines by raising to maximum degree.

        Args:
            bsplines: List of B-splines to match (modified in place)
        Nc              3   <   K   | ]  }|j                           y wr   )rp   ).0r   s     r.   	<genexpr>z1BSplineAlgorithms.match_degree.<locals>.<genexpr>7  s     @V@s   )maxrp   IncreaseDegree)r   
max_degreer   current_degrees       r.   match_degreezBSplineAlgorithms.match_degree+  sN      @x@@
  	2F#]]_N
*%%j1	2r-   splines_vectortolc                    | sg S t               }| D ](  }t        j                  |      }|j                  |       * t	        |      }g }g }|D ]P  }d}	| D ]%  }t        j                  |||      }
t        |	|
      }	' |j                  |       |j                  |	       R g }| D ]+  }t        j                  ||||      }|j                  |       - |S )a  
        Creates common knots vector for given B-splines.

        Args:
            splines_vector: Vector of B-splines with different knot vectors
            tol: Tolerance for knot comparison

        Returns:
            List of B-splines with common knot vector
        r   )	setr0   
_get_knotsupdatesorted_get_knot_multiplicityr   rG   _insert_knots)r   r   	all_knotsr   knotssorted_knotscommon_knotsmultiplicitiesrx   max_multmultrL   
new_splines                r.    create_common_knots_vector_curvez2BSplineAlgorithms.create_common_knots_vector_curve?  s     I E	$ 	$F%008EU#	$
 i(  	,DH( /(??cRx./ %!!(+	, +-$ 	&F*88ncJ MM*%		& r-   r   c                 t    | j                         }t        j                  |||       | j                  |       y)a  
        Changes parameter range of the B-spline curve.

        Args:
            spline: B-spline to reparametrize (modified in place)
            umin: New minimum parameter
            umax: New maximum parameter
            tol: Tolerance for parameter comparison
        N)Knotsr   Reparametrize_sSetKnots)r   r<   r=   r   r   s        r.   r   z'BSplineAlgorithms.reparametrize_bsplineo  s-       tU3r-   curvesc                     g }| D ]S  }t        |t              r|j                  t        |             .t        j                  |      }|j                  |       U |S )z
        Converts a curve array into a B-spline array.

        Args:
            curves: List of generic curves

        Returns:
            List of B-spline curves
        )
isinstancer   rG   r    r0   _convert_to_bspline)r   rL   rk   bsplines       r.   to_bsplineszBSplineAlgorithms.to_bsplines  sY      	'E%!23mE23 ,??Fg&	' r-   spline1spline2c                     t         j                  |       }t         j                  |      }||z   dz  }||z  }t        | ||      }|D cg c]  }|d   |d   f c}S c c}w )a2  
        Returns all intersections of two B-splines.

        Args:
            spline1: First B-spline
            spline2: Second B-spline
            tolerance: Relative tolerance for intersection checking

        Returns:
            List of (parameter on spline1, parameter on spline2) pairs
               @parmOnCurve1parmOnCurve2)r0   scaler   )	r   r   r5   scale1scale2splines_scalescaled_toleranceresultsrs	            r.   intersectionszBSplineAlgorithms.intersections  su      #((1"((1&C/ %}4#GW6FG AHH1>"An$56HHHs   	Ac                     d}| j                         dkD  r_| j                  d      }t        d| j                         dz         D ].  }|j                  | j                  |            }t	        ||      }0 |dkD  r|S dS )z
        Returns the approximate scale of a single B-spline curve.
        Matches the C++ scale(const Handle(Geom_BSplineCurve)& spline) function.
        r   r   r   r%   r   )NbPolesPolerC   Distancer   )r   	scale_valfirst_ctrl_pntctrl_pnt_idxdistances        r.   _scale_curvezBSplineAlgorithms._scale_curve  s     	>>a#[[^N %a)9A)= > 5)226;;|3LM	84	5 &My2s2r-   c                 d    d}| D ]!  }t        t        j                  |      |      }# |dkD  r|S dS )z
        Returns the approximate scale of the biggest B-spline curve in a list.
        Matches the C++ scale(const std::vector<Handle(Geom_BSplineCurve)>& splines_vector) function.
        r   r   r   )r   r0   r   )r   	max_scaler   s      r.   _scale_curve_listz#BSplineAlgorithms._scale_curve_list  sC     	$ 	OF-::6BINI	O%My2s2r-   c                 F   d}t        | j                         | j                         dz         D ]p  } | || j                               }t        | j                         dz   | j	                         dz         D ]&  }|j                   | ||            }t        ||      }( r |S )z
        Returns the scale of the point matrix.
        Matches the C++ scale(const TColgp_Array2OfPnt& points) function.
        r   r   )rC   rY   rZ   r[   r\   r   r   )rV   	the_scaleri   p_firstra   rS   s         r.   _scale_array2_of_pntz&BSplineAlgorithms._scale_array2_of_pnt  s     	6??,foo.?!.CD 	1EUFOO$56Gv014foo6G!6KL 1''ue(<=	40	1	1
 r-   c                    d}t        | j                         | j                         dz         D ]P  }t        |dz   | j                         dz         D ]+  } | |      j                   | |            }t	        ||      }- R |dkD  r|S dS )z
        Returns the scale of the point list by searching for the largest distance between two points.
        Matches the C++ scale(const TColgp_Array1OfPnt& points) function.
        r   r   r   r   rC   LowerUpperr   r   )rV   r   rK   jrS   s        r.   _scale_array1_of_pntz&BSplineAlgorithms._scale_array1_of_pnt  s     	v||~v||~'9: 	1AAv||~) 1 ay))&)4	40		1	1 &My2s2r-   objc                 @   t        | t              rt        j                  |       S t        | t              rt        j                  |       S t        | t              rt        j                  |       S t        | t              rt        j                  |       S t        d      )z
        Returns the approximate scale of the given B-spline curve(s) or point array(s).
        This is a unified method to match the overloaded C++ scale functions.
        z#Unsupported type for scale function)r   r   r0   r   listr   r   r   r   r   	TypeError)r   s    r.   r   zBSplineAlgorithms.scale  s     c,-$11#66T"$66s;;/0$99#>>/0$99#>>ABBr-   c                     g }| j                         }t        d|dz         D ]"  }|j                  | j                  |             $ |S )z$Get all knots from a B-spline curve.r   )rn   rC   rG   rq   )r   r   n_knotsrK   s       r.   r   zBSplineAlgorithms._get_knots  H     .."q'A+& 	)ALLQ(	)r-   rx   c                     | j                         }t        d|dz         D ]5  }t        | j                  |      |z
        |k  s$| j	                  |      c S  y)z$Get multiplicity of a specific knot.r   r   )rn   rC   r9   rq   ro   )r   rx   r   r  rK   s        r.   r   z(BSplineAlgorithms._get_knot_multiplicity
  sZ    
 .."q'A+& 	.A6;;q>D()C/**1--	. r-   c                     g }| j                         }t        d|dz         D ]"  }|j                  | j                  |             $ |S )z$Get all poles from a B-spline curve.r   )r   rC   rG   r   )r   polesn_polesrK   s       r.   
_get_poleszBSplineAlgorithms._get_poles  r  r-   c                     | j                         sdg| j                         z  S g }| j                         }t        d|dz         D ]"  }|j                  | j	                  |             $ |S )z/Get all weights from a rational B-spline curve.r   r   )
IsRationalr   rC   rG   Weight)r   weightsr  rK   s       r.   _get_weightszBSplineAlgorithms._get_weights  si       "56>>+++.."q'A+& 	-ANN6==+,	-r-   r   r   c                 &   t        |       }t        ||      D ]v  \  }}d}t        d|j                         dz         D ]8  }t	        |j                  |      |z
        |k  s$d}|j                  ||        n |rc|j                  |||d       x |S )a:  
        Insert knots into a B-spline curve.

        Args:
            spline: Original B-spline curve
            knots: Knots to insert
            multiplicities: Multiplicities for each knot
            tol: Tolerance for knot comparison

        Returns:
            New B-spline with inserted knots
        Fr   T)r    ziprC   rn   r9   rq   IncreaseMultiplicity
InsertKnot)	r   r   r   r   r   rx   r   knot_existsrK   s	            r.   r   zBSplineAlgorithms._insert_knots*  s    * #6*
 e^4 	>JD$K1j002Q67 zq)D01C7"&K33At<
  %%dD#u=	>" r-   old_parametersnew_parametersn_control_pntsc           	         dt         dt         dt         fd}dt        t            dt         dt         fd}t        |      t        |      k7  rt        d      t	        dt        |            }t        t        |            D ]&  }|dz   }|j                  |t        ||   d	             ( t        j                  |      }	t        ||	d
d      }
|
j                          |
j                         st        dt        j                        |
j                         }t        dt        |      dz
        D cg c]  }||   	 }}d}t        j!                  |       }t        t        |            D ].  }t#        t        ||   d      |      j%                         }|||<   0 g }|D ]-  }d
}|D ]  } ||||      sd} n |r|j'                  |       / |}t        j)                  |d	   |d   t+        d|dz        |      }|D ]  }t-        j.                  ||        t1        dt        |            }t        dt        |      dz         D ]H  }|j3                  ||dz
           j5                         }|j                  || j3                  |             J | j7                         xra | j9                  | j;                         d      j=                  | j9                  | j?                         d            dt@        jB                  z  k  }ddl"m#}  ||tI        |      d|      }g }|j'                  |d	          |jK                  |       |j'                  |d          |D ]#  } ||||      } | dk7  s|jM                  |        % |D ]$  } ||||      } | dk7  s|jM                  | d       & |jO                  |      }!|!jP                  J |!S c c}w )a  
        Reparametrize B-spline curve using approximation, matching C++ line by line.

        Args:
            spline: Original B-spline curve
            old_parameters: Original parameter values at intersection points
            new_parameters: New parameter values at intersection points
            n_control_pnts: Maximum number of control points for the new curve

        Returns:
            ApproxResult containing the reparametrized curve and other info.
        r3   r4   r5   c                 $    t        | |z
        |k  S r   r8   r:   s      r.   r;   zYBSplineAlgorithms.reparametrize_bspline_continuously_approx.<locals>._is_inside_tolerancej  s    uv~&22r-   	data_listc                 T    t        |       D ]  \  }}t        ||z
        |k  s|c S  y)NrA   )rD   r9   )r  r4   r5   rK   rP   s        r.   _find_index_with_tolerancez_BSplineAlgorithms.reparametrize_bspline_continuously_approx.<locals>._find_index_with_tolerancen  s7     $I. 3sV|$y0H r-   zparameter sizes dont matchr   r   Fư>zCannot reparametrizeg|=r   TrA   e   r%   g?)BSplineApproxInterp   ))rE   r   lenr   r   rC   SetValuer   r0   to_arrayr	   PerformIsDoner   
MATH_ERRORCurver}   r
   LowerDistanceParameterrG   rU   r   rH   insort_leftr   Valuer   IsClosedrr   r   rs   r   rt   ru   bspline_approx_interpr  intextendinterpolate_pointfit_curve_optimalrk   )"r   r  r  r  r;   r  old_parameters_pntsparameter_idxoccIdxnew_parameters_arrayinterpolationObjectreparametrizing_splineiparr?   par_tolrv   ikinkprojected_param
new_breaksbis_kink_nearbyk
parameterskinkrV   rK   oldParametermakeContinuousr  approximationObjbreaks_for_interpolationthebreakidxrL   s"                                     r.   )reparametrize_bspline_continuously_approxz;BSplineAlgorithms.reparametrize_bspline_continuously_approxU  s
   *	3 	3u 	3 	3	E{	,1	>C	 ~#n"55455 4As>7JK"3~#67 	M"Q&F((!>B	  199.I 4!5ud
 	##%"))+.	0D0DEE!4!:!:!<38C<ORS<S3TU4.&UU "55f=3u:& 	+E;us+-C$$&  +E%L		+ 
 	%A"N '1g6%)N "!!!$	% &;;1~b13sNQ<N3OQW

  	1Dz40	1 %QJ8q#j/A-. 	;A177
1q58IJLLNLOOAv||L9:	;  * 
IIf++-q177		&..0!4 DGG#$ 	 	?.C'N
 $&  ''q(9: ''/ ''r(:;0 	8H,Z7KCby 2237	8
  	>D,ZwGCby 223=	>
 "33J?||'''I Vs   /O	c           	         | j                         }| j                         }||z
  ||z
  z  }|||z  z
  }| j                         }t        d|      }t	        d|dz         D ]-  }	| j                  |	      }
||
z  |z   }|j                  |	|       / | j                         }t        d|      }t        d|      }t	        d|dz         D ]D  }	|j                  |	| j                  |	             |j                  |	| j                  |	             F t        d|      }t	        d|dz         D ]#  }	|j                  |	| j                  |	             % t        ||||| j                         | j                               S )a  
        Simple linear reparameterization of B-spline curve.

        Args:
            spline: Original B-spline curve
            umin: New minimum parameter
            umax: New maximum parameter

        Returns:
            Reparametrized B-spline curve
        r   )r   r   rn   r   rC   rq   r   r   r   r   r  r   ro   r   rp   
IsPeriodic)r   r<   r=   current_umincurrent_umaxar:  r  knots_arrayrK   old_knotnew_knotr  r  r  
mult_arrays                   r.   reparametrize_bspline_simplez.BSplineAlgorithms.reparametrize_bspline_simple  s     ,,.++- D[\L891|## .."*1g6q'A+& 	.A{{1~H8|a'H  H-	. ..""1g.&q'2q'A+& 	2ANN1fkk!n-Qa 01	2 -Q8
q'A+& 	;A6#6#6q#9:	; !MMO
 	
r-   c           	      0   dt         fd} ||       r	 d}| j                  | j                               }t        dd      D ]\  }d|dz  z
  | j                         z  |dz  | j	                         z  z   }t        ||j                  | j                  |                  }^ t        j                         |z  dz  }t        | |t        dd	
      }|j                         r%|j                         |k  r|j                         }|S t        j                  |       S )z
        Convert generic curve to B-spline curve.

        Args:
            curve: Generic curve to convert

        Returns:
            B-spline curve
        rk   c                     | j                  d      ry| j                  d      r4t        | t              sJ | j                         }|j                  d      ryy)Nr   Tr   F)IsKindr   r   
BasisCurve)rk   basis_curves     r.   is_conicz7BSplineAlgorithms._convert_to_bspline.<locals>.is_conic  sQ    ||L)||/0!%):;;;#..0%%l3r-   r   r   r        @      )MaxSegments	MaxDegree)r   r(  r   rC   r   r   r   r   Approximation_sr   r   	HasResultMaxErrorr%  r   CurveToBSplineCurve_s)	rk   rU  
curve_sizecurve_start_pntrK   r)   r   approxr   s	            r.   r   z%BSplineAlgorithms._convert_to_bspline  s   	J 	 E?
 J#kk%*>*>*@AO1a[ WQY%"6"6"88E'')<* * !_-E-EekkRSn-UV
	W ++-
:S@C,F !foo&7#&= ,,.0077r-   r   degreeclosed_curvec                 `   t        |       dk  rt        d      t        |       }|r||dz
  z  }||z
  dz   }dg|z  }| d   |d<   | d   |d<   g }|r|dz  dk(  rt        |       dz
  }dg|dz   z  }t        |dz         D ]  }	| |	dz      | |	   z
  ||	<    |d   d|d   ||   z   z  z   |d<   t        d|      D ]  }	||	   d||	dz
     ||	   z   z  z   ||	dz   <   ! t        t        |             D ]  }	| |	xx   ||   dz  z  cc<    n|r3t        |      t        |       k7  rt        d	      | j                         }nLt        dt        |       |z
        D ]1  }
d}t        |
|
|z         D ]
  }|| |   z  } |t	        |      z  ||
<   3 |r|d   ||dz
     z
  }t        |      D ]"  }|j                  ||||z
  dz
  |z      z          $ t        |      D ]  }|j                  ||           t        |      D ]  }|j                  | ||dz      z           not        |      D ]  }|j                  |d           t        |      D ]  }|j                  ||           t        |      D ]  }|j                  ||dz
             |r&|dk  r!t        |      }|d   |d<   ||dz
     ||dz
  <   |S )
a:  
        Create knot vector from curve parameters following Park (2000) algorithm.

        Args:
            params: Parameter values (corresponding to control points)
            degree: Degree of the spline
            closed_curve: Whether the curve is closed

        Returns:
            Knot vector
        r%   z-Parameters must contain two or more elements.r   r   r   rA         ?r   z=Inner knots size must match parameters size for closed curves)r  
ValueErrorrC   r   rE   rG   )r   rc  rd  n_cpn_inner_knotsinner_knotsr   mdparmiparmr   sum_valrK   offsetiknotr  s                   r.   knots_from_curve_parametersz-BSplineAlgorithms.knots_from_curve_parameters<  sZ    v;?LMM6{FQJDv)em+A *BFQJ!OFaA EQUOEq1u A%eai06%=@eA )^cU1Xa5H.IIKNq! )4U);c%!)$uU|3? *EAI& s6{+ 0uqC/0 ;3v;. S  !++-K 1c&kF23 9q!f*- )Avay(G)!(5=!8A9  ^k-!2C&DDFv WVk-&2H12Lu2T&UUVW}- 1[/01v ?fW{519'==>? v -[^,-}- 1[/01v =[):;<= FaK%jGQxE!H!&w{!3E'A+r-   deriv_orderc           
      &   |j                         | z
  dz
  }|j                         }t        j                  ||f      }t        d|dz   d| dz         }t	        d|dz         D ]  } ||      }	t        j                  | ||	d| dz   |j                         | z
        \  }
}t        j                  || dz   ||	t               |       t	        | dz         D ]<  }|
| z
  dz
  |z   }d|cxk  r|k  sn |j                  |dz   |dz         ||dz
  |f<   >  |S )a$  
        Compute B-spline basis matrix.

        Args:
            degree: Degree of B-spline
            knots: Knot vector
            params: Parameter values
            deriv_order: Derivative order (0 = basis functions)

        Returns:
            Basis matrix as numpy array
        r   Fr   )
r   npzerosr   rC   r   LocateParameter_sEvalBsplineBasis_sr+  r(  )rc  r   r   rr  rh  n_params	basis_mat
bspl_basisi_param	param_valspan_idx_r   col_idxs                 r.   bspline_basis_matz#BSplineAlgorithms.bspline_basis_mat  s9   & ||~&*==? HHh-.	 K!OQ
C
 Q1- 	GwI #44y%!U\\^f=TKHa ''VaZ	35* 6A:& "V+a/!3&$&6@6F6F#aQ7Igk723	" r-   c                     d}t        | j                         | j                               D ]P  }t        |dz   | j                         dz         D ]+  } | |      j                   | |            }t	        ||      }- R |S )z
        Compute maximum distance between points in bounding box.

        Args:
            points: Array of points

        Returns:
            Maximum distance
        r   r   r   )rV   max_distancerK   r   rS   s        r.   max_distance_of_bounding_boxz.BSplineAlgorithms.max_distance_of_bounding_box  s|     v||~v||~6 	7A1q5&,,.1"45 7ay))&)4"<67	7 r-   c2_continuousc                     t         j                  | j                               }d|z  } | | j                               j	                   | | j                               |      xr |S )z
        Check if points form a closed curve.

        Args:
            points: Points to check
            c2_continuous: Whether to require C2 continuity

        Returns:
            True if curve is closed
        r  )r0   r  Array1r   r]   r   )rV   r  r  r   s       r.   	is_closedzBSplineAlgorithms.is_closed  sW     )EEfmmoV|#6<<>"**6&,,.+A5I 	
r-   vectorc                 |    t        dt        |             }t        | d      D ]  \  }}|j                  ||        |S )z
        Convert Python list to TColStd_HArray1OfReal.

        Args:
            vector: List of values

        Returns:
            TColStd_HArray1OfReal handle
        r   )r   r  rD   r   r  arrayrK   r3   s       r.   r!  zBSplineAlgorithms.to_array  sA     &aV5!&!, 	%HAuNN1e$	%r-   c                 |    t        dt        |             }t        | d      D ]  \  }}|j                  ||        |S )z
        Convert Python list to TColStd_HArray1OfInteger.

        Args:
            vector: List of integer values

        Returns:
            TColStd_HArray1OfInteger handle
        r   )r   r  rD   r   r  s       r.   to_array_intzBSplineAlgorithms.to_array_int  sA     )CK8!&!, 	%HAuNN1e$	%r-   matrix	col_indexc                     | j                         }| j                         }t        ||      }t        ||dz         D ]  }|j	                  | | ||              |S )z
        Extracts a column from a TColgp_Array2OfPnt and returns it as a TColgp_HArray1OfPnt.
        Matches the C++ array2GetColumn helper function.
        r   )rY   rZ   r   rC   r   )r  r  	lower_row	upper_row
col_vectorrow_idxs         r.   _pnt_array2_get_columnz(BSplineAlgorithms._pnt_array2_get_column  sa     OO%	OO%	(I>
Y	A6 	EG)CD	Er-   	row_indexc                     | j                         }| j                         }t        ||      }t        ||dz         D ]  }|j	                  | | ||              |S )z
        Extracts a row from a TColgp_Array2OfPnt and returns it as a TColgp_HArray1OfPnt.
        Matches the C++ array2GetRow helper function.
        r   )r[   r\   r   rC   r   )r  r  	lower_col	upper_col
row_vectorr  s         r.   _pnt_array2_get_rowz%BSplineAlgorithms._pnt_array2_get_row  sa     OO%	OO%	(I>
Y	A6 	EG	7)CD	Er-   c                 b   dg| j                         z  }t        | j                         | j                         dz         D ]W  }t        j                  | |      }t        j                  ||      }t        t        |            D ]  }||xx   ||   z  cc<    Y t        t        |            D ]&  }||xx   t        | j                               z  cc<   ( dg| j                         z  }t        | j                         | j                         dz         D ]W  }t        j                  | |      }	t        j                  |	|      }
t        t        |
            D ]  }||xx   |
|   z  cc<    Y t        t        |            D ]&  }||xx   t        | j                               z  cc<   ( ||fS )z
        Computes parameters for a B-spline surface in both u and v directions.
        Matches the C++ computeParamsBSplineSurf function line by line.
        r   r   )	ColLengthrC   r[   r\   r0   r  r   r  rE   	RowLengthrY   rZ   r  )rV   r   params_ura   points_u_lineparameters_u_lineu_param_idxparams_vri   points_v_lineparameters_v_linev_param_idxs               r.   compute_params_bspline_surfz-BSplineAlgorithms.compute_params_bspline_surf&  s    56++-- 6??,foo.?!.CD 	HE-DDVUSM !2 N Nu!
  %S):%;< H%):;)GG%H	H !X/ 	?K[!U6+;+;+=%>>!	? 56++-- 6??,foo.?!.CD 	HE-AA&%PM !2 N Nu!
  %S):%;< H%):;)GG%H	H !X/ 	?K[!U6+;+;+=%>>!	? !!r-   c                 <    t        |       }|j                          |S )z
        Swaps axes of the given surface, i.e., surface(u-coord, v-coord) becomes surface(v-coord, u-coord).
        Matches the C++ flipSurface function.
        )r!   
ExchangeUV)r   rL   s     r.   flip_surfacezBSplineAlgorithms.flip_surfaceb  s     'w/r-   countmultsc                    |d   |z
  | cxk  r|d   |z   k  sn t        dt        j                        d}t        |      D ]  \  }}t	        || z
        |k  s|} n |dk7  rt        ||   |z   |      ||<   yd}	|	t        |      k  r$||	   | k  r|	dz  }	|	t        |      k  r	||	   | k  r|j                  |	|        |j                  |	t        ||             y)a  
        Inserts a knot into the knot vector with a specified multiplicity,
        similar to the C++ insertKnot helper function.

        Args:
            knot: The knot value to insert.
            count: The desired multiplicity for the knot.
            degree: The degree of the B-spline.
            knots: The list of distinct knot values (modified in place).
            mults: The list of multiplicities for each distinct knot (modified in place).
            tol: Tolerance for knot comparison.
        r   rA   zknot out of ranger   N)r   r   INVALID_ARGUMENTrD   r9   minr  rF   )
rx   r  rc  r   r  r   rO   rK   r<  
insert_idxs
             r.   _insert_knot_with_multiplicityz0BSplineAlgorithms._insert_knot_with_multiplicityl  s    * a3$9%)c/9+Y-G-GHH 	e$ 	DAq1t8}s"		
 ?"5#3e#;VDE) Js5z)eJ.?$.Fa
 s5z)eJ.?$.FLLT*LLCv.r-   c                       e Zd ZdZdeddfdZddededefd	Zd
edefdZ	d
edefdZ
defdZdefdZddZdefdZy)!BSplineAlgorithms.SurfAdapterViewz
        Adapter class for Geom_BSplineSurface to provide a unified interface
        for knot vector manipulation, similar to C++'s SurfAdapterView.
        surf	directionr$   c                      || _         || _        y r   )_surf_dir)r   r  r  s      r.   r   z*BSplineAlgorithms.SurfAdapterView.__init__  s    DJ!DIr-   rx   r   r5   c                     | j                   t        j                  k(  r| j                  j	                  |||d       y | j                  j                  |||d       y NF)r  r$   r)   r  InsertUKnotInsertVKnotr   rx   r   r5   s       r.   insert_knotz-BSplineAlgorithms.SurfAdapterView.insert_knot  sE    yy,...

&&tT9eD

&&tT9eDr-   rD  r6   c                     | j                   t        j                  k(  r| j                  j	                  |      S | j                  j                  |      S r   )r  r$   r)   r  r   r   r   rD  s     r.   get_knotz*BSplineAlgorithms.SurfAdapterView.get_knot  s?    yy,...zz'',,zz'',,r-   c                     | j                   t        j                  k(  r| j                  j	                  |      S | j                  j                  |      S r   )r  r$   r)   r  r   r   r  s     r.   get_multz*BSplineAlgorithms.SurfAdapterView.get_mult  s?    yy,...zz//44zz//44r-   c                     | j                   t        j                  k(  r| j                  j	                         S | j                  j                         S r   )r  r$   r)   r  r   r   r   s    r.   get_n_knotsz-BSplineAlgorithms.SurfAdapterView.get_n_knots  s;    yy,...zz**,,zz**,,r-   c                     | j                   t        j                  k(  r| j                  j	                         S | j                  j                         S r   )r  r$   r)   r  r   r   r   s    r.   
get_degreez,BSplineAlgorithms.SurfAdapterView.get_degree  s;    yy,...zz))++zz))++r-   c                     || _         y r   )r  )r   r  s     r.   set_dirz)BSplineAlgorithms.SurfAdapterView.set_dir  s	    !DIr-   c                     | j                   S r   )r  r   s    r.   get_surfacez-BSplineAlgorithms.SurfAdapterView.get_surface  s    ::r-   NgV瞯<)r  r$   )r&   r'   r(   __doc__r   r   rE   r+  r  r  r  r  r  r  r  r,   r-   r.   SurfAdapterViewr    s    	
	"!4 	"AS 	"	EE 	E 	E 	E	- 	- 	-	5 	5 	5	- 	-	, 	,	"	!4 	r-   r  c                   v    e Zd ZdZdefdZddededefdZded	efd
Z	ded	efdZ
d	efdZd	efdZd	efdZy)"BSplineAlgorithms.CurveAdapterViewz
        Adapter class for Geom_BSplineCurve to provide a unified interface
        for knot vector manipulation, similar to C++'s CurveAdapterView.
        rk   c                     || _         y r   _curve)r   rk   s     r.   r   z+BSplineAlgorithms.CurveAdapterView.__init__  s	    DKr-   rx   r   r5   c                 @    | j                   j                  |||d       y r  )r  r  r  s       r.   r  z.BSplineAlgorithms.CurveAdapterView.insert_knot  s    KK""4y%@r-   rD  r6   c                 8    | j                   j                  |      S r   )r  rq   r  s     r.   r  z+BSplineAlgorithms.CurveAdapterView.get_knot  s    ;;##C((r-   c                 8    | j                   j                  |      S r   )r  ro   r  s     r.   r  z+BSplineAlgorithms.CurveAdapterView.get_mult  s    ;;++C00r-   c                 6    | j                   j                         S r   )r  rn   r   s    r.   r  z.BSplineAlgorithms.CurveAdapterView.get_n_knots  s    ;;&&((r-   c                 6    | j                   j                         S r   )r  rp   r   s    r.   r  z-BSplineAlgorithms.CurveAdapterView.get_degree  s    ;;%%''r-   c                     | j                   S r   r  r   s    r.   	get_curvez,BSplineAlgorithms.CurveAdapterView.get_curve  s    ;;r-   Nr  )r&   r'   r(   r  r   r   rE   r+  r  r  r  r  r  r  r,   r-   r.   CurveAdapterViewr    s}    	
	 "3 	 	AE 	A 	A 	A	) 	) 	)	1 	1 	1	) 	)	( 	(	0 	r-   r  )zFBSplineAlgorithms.SurfAdapterView | BSplineAlgorithms.CurveAdapterViewpar_tolerancec                 .   | sy| d   }t        |t        j                  t        j                  f      st	        d      |j                  d      }|j                  |j                               }t        dt        |             D ]  }| |   }t        |t        j                  t        j                  f      st	        d      |j                  d      }|j                  |j                               }t        ||z
        |kD  st        ||z
        |kD  s y y)z
        Checks if all splines in the vector have the same parameter range.
        This is a generic helper for both curves and surfaces (via adapters).
        Tr   zLUnsupported spline type in have_same_range: first element is not an adapter.r   zMMixed types in splines_vector for have_same_range: element is not an adapter.F)
r   r0   r  r  r   r  r  rC   r  r9   )	r   r  first_adapterbegin_param_refend_param_ref
spline_idxcurrent_adapterbegin_param_currentend_param_currents	            r.   have_same_rangez!BSplineAlgorithms.have_same_range  s%    &q)..0A0R0RS
 ^  (003%..}/H/H/JK3~#67 	J,Z8O"224E4V4VW  c  #2":":1"= / 8 89T9T9V W '/9:]J(=89MI#	$ r-   )rf  r  )ga2U0*3?)F)r   )r2   )Cr&   r'   r(   r  REL_TOL_CLOSEDPAR_CHECK_TOLstaticmethodrE   boolr;   r+  r   rU   r   rd   rj   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   tupler   r   r   r   r   r   r   r   r   r   r  r  r   r   rE  rO  r   rq  r   rt  ndarrayr  r  r  r   r!  r   r  r  r  r  r  r  r  r  r  r,   r-   r.   r0   r0   6   s   
 N M/E /5 /U /t / / AA A,/A9=eA	eA AF  2 u    
 2 
u 
 
 
 #4 e  :% %
 $	) &  (-5:	  47)#),1)	e) )V >C()6;	 4 2t$56 24 2 2& -./-6;-		 - -^ JO!).6;BG	   D, 6G1H  * SWI"I->IKPI	eE5L!	"I I6 3. 35 3 3 3$/@*A 3e 3 3 %7 E   3%7 3E 3 3 C$%& ! !!C 
C C0 , e   !).5:	  , f   	. 	4; 	 	 (!(E{( S	( 	(
 
( (T ~!~U~ U~ 	~
 
~ ~@ 2
!2
).2
6;2
	2
 2
h .8: .82C .8 .8` ?DTUT%(T8<T	eT Tl 
 	++#+ %+ 	+
 
+ +Z -? E  " 
- 
d 
t 
 
$ e )>   T#Y +C   "/2	  "/2	  369""9"+09"	tE{DK'	(9" 9"v 1 6I    ))) ) E{	)
 Cy) ) )V, ,\ 6 ,U
, 	,
 
, ,r-   r0   )5r  rH   enumrt   numpyrt  OCP.BSplCLibr   OCP.Geomr   r   r   r   r   OCP.Geom2dAPIr	   r
   OCP.GeomAbsr   r   OCP.GeomConvertr   r   OCP.gpr   r   OCP.mathr   OCP.Precisionr   
OCP.TColgpr   r   r   r   OCP.TColStdr   r   r   r   approx_resultr   r   r   intersect_bsplinesr   miscr    r!   r"   Enumr$   r0   r,   r-   r.   <module>r     s{        !  O . @ #   #   ( # 1 M Mtyy X Xr-   