242 |
|
normalize(ps); |
243 |
|
} |
244 |
|
|
245 |
– |
smDir_in_cone(sm,ps,id) |
246 |
– |
SM *sm; |
247 |
– |
FVECT ps; |
248 |
– |
int id; |
249 |
– |
{ |
250 |
– |
|
251 |
– |
VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
252 |
– |
normalize(ps); |
253 |
– |
} |
254 |
– |
|
245 |
|
smClear_flags(sm,which) |
246 |
|
SM *sm; |
247 |
|
int which; |
481 |
|
{ |
482 |
|
int max_vertices; |
483 |
|
|
494 |
– |
|
484 |
|
/* If n <=0, Just clear the existing structures */ |
485 |
|
if(n <= 0) |
486 |
|
{ |
509 |
|
} |
510 |
|
|
511 |
|
|
512 |
< |
smLocator_apply(sm,v0,v1,v2,func) |
512 |
> |
smLocator_apply(sm,v0,v1,v2,func,n) |
513 |
|
SM *sm; |
514 |
|
FVECT v0,v1,v2; |
515 |
|
FUNC func; |
516 |
+ |
int n; |
517 |
|
{ |
518 |
|
STREE *st; |
519 |
|
FVECT tri[3]; |
523 |
|
VSUB(tri[0],v0,SM_VIEW_CENTER(sm)); |
524 |
|
VSUB(tri[1],v1,SM_VIEW_CENTER(sm)); |
525 |
|
VSUB(tri[2],v2,SM_VIEW_CENTER(sm)); |
526 |
< |
stVisit(st,tri,func); |
526 |
> |
stVisit(st,tri,func,n); |
527 |
|
|
528 |
|
} |
529 |
|
|
540 |
– |
|
541 |
– |
/* NEW INSERTION!!! ******************************************************/ |
530 |
|
QUADTREE |
531 |
|
insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale, |
532 |
|
s0,s1,s2,sq0,sq1,sq2,rev,f,n) |
689 |
|
|
690 |
|
if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id)) |
691 |
|
SM_SET_NTH_T_BASE(sm,t_id); |
692 |
< |
else |
693 |
< |
if(SM_DIR_ID(sm,v0_id) && SM_DIR_ID(sm,v1_id) && SM_DIR_ID(sm,v2_id)) |
692 |
> |
|
693 |
> |
if(SM_DIR_ID(sm,v0_id) || SM_DIR_ID(sm,v1_id) || SM_DIR_ID(sm,v2_id)) |
694 |
|
SM_SET_NTH_T_BG(sm,t_id); |
695 |
|
|
696 |
|
S_SET_FLAG(T_NTH_V(t,0)); |
879 |
|
if(!T_IS_VALID(t_opp)) |
880 |
|
error(CONSISTENCY,"Invalid trismFix_tris()\n"); |
881 |
|
#endif |
882 |
< |
smDir_in_cone(sm,p0,T_NTH_V(t_opp,0)); |
883 |
< |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,1)); |
884 |
< |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,2)); |
882 |
> |
smDir(sm,p0,T_NTH_V(t_opp,0)); |
883 |
> |
smDir(sm,p1,T_NTH_V(t_opp,1)); |
884 |
> |
smDir(sm,p2,T_NTH_V(t_opp,2)); |
885 |
|
if(point_in_cone(p,p0,p1,p2)) |
886 |
|
{ |
887 |
|
swapped = 1; |
1820 |
|
|
1821 |
|
} |
1822 |
|
|
1835 |
– |
|
1836 |
– |
int |
1837 |
– |
smNext_tri_flag_set(sm,i,which,b) |
1838 |
– |
SM *sm; |
1839 |
– |
int i,which; |
1840 |
– |
int b; |
1841 |
– |
{ |
1842 |
– |
|
1843 |
– |
for(; i < SM_NUM_TRI(sm);i++) |
1844 |
– |
{ |
1845 |
– |
|
1846 |
– |
if(!T_IS_VALID(SM_NTH_TRI(sm,i))) |
1847 |
– |
continue; |
1848 |
– |
if(!SM_IS_NTH_T_FLAG(sm,i,which)) |
1849 |
– |
continue; |
1850 |
– |
if(!b) |
1851 |
– |
break; |
1852 |
– |
if((b==1) && !SM_BG_TRI(sm,i)) |
1853 |
– |
break; |
1854 |
– |
if((b==2) && SM_BG_TRI(sm,i)) |
1855 |
– |
break; |
1856 |
– |
} |
1857 |
– |
|
1858 |
– |
return(i); |
1859 |
– |
} |
1860 |
– |
|
1861 |
– |
|
1862 |
– |
|
1863 |
– |
int |
1864 |
– |
smNext_valid_tri(sm,i) |
1865 |
– |
SM *sm; |
1866 |
– |
int i; |
1867 |
– |
{ |
1868 |
– |
|
1869 |
– |
while( i < SM_NUM_TRI(sm) && !T_IS_VALID(SM_NTH_TRI(sm,i))) |
1870 |
– |
i++; |
1871 |
– |
|
1872 |
– |
return(i); |
1873 |
– |
} |
1874 |
– |
|
1875 |
– |
|
1876 |
– |
|
1877 |
– |
qtTri_from_id(t_id,v0,v1,v2) |
1878 |
– |
int t_id; |
1879 |
– |
FVECT v0,v1,v2; |
1880 |
– |
{ |
1881 |
– |
TRI *t; |
1882 |
– |
|
1883 |
– |
t = SM_NTH_TRI(smMesh,t_id); |
1884 |
– |
if(!T_IS_VALID(t)) |
1885 |
– |
return(0); |
1886 |
– |
VSUB(v0,SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh)); |
1887 |
– |
VSUB(v1,SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh)); |
1888 |
– |
VSUB(v2,SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh)); |
1889 |
– |
return(1); |
1890 |
– |
} |
1891 |
– |
|
1892 |
– |
|
1823 |
|
smRebuild_mesh(sm,v) |
1824 |
|
SM *sm; |
1825 |
|
VIEW *v; |
1831 |
|
#ifdef DEBUG |
1832 |
|
fprintf(stderr,"smRebuild_mesh(): rebuilding...."); |
1833 |
|
#endif |
1834 |
+ |
smCull(sm,v,SM_ALL_LEVELS); |
1835 |
|
/* Clear the mesh- and rebuild using the current sample array */ |
1836 |
|
/* Remember the current number of samples */ |
1837 |
|
cnt = SM_NUM_SAMP(sm); |
1893 |
|
{ |
1894 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
1895 |
|
t = SM_NTH_TRI(smMesh,t_id); |
1896 |
< |
if(!T_IS_VALID(t)) |
1896 |
> |
if(!T_IS_VALID(t) || SM_IS_NTH_T_BASE(smMesh,t_id)|| |
1897 |
> |
SM_IS_NTH_T_BG(smMesh,t_id)) |
1898 |
|
continue; |
1899 |
|
pid0 = T_NTH_V(t,0); |
1900 |
|
pid1 = T_NTH_V(t,1); |
1901 |
|
pid2 = T_NTH_V(t,2); |
1970 |
– |
if(base = SM_IS_NTH_T_BASE(smMesh,t_id)) |
1971 |
– |
if(SM_BASE_ID(smMesh,pid0) && SM_BASE_ID(smMesh,pid1) && |
1972 |
– |
SM_BASE_ID(smMesh,pid2)) |
1973 |
– |
continue; |
1902 |
|
VCOPY(p0,SM_NTH_WV(smMesh,pid0)); |
1903 |
|
VCOPY(p1,SM_NTH_WV(smMesh,pid1)); |
1904 |
|
VCOPY(p2,SM_NTH_WV(smMesh,pid2)); |
1905 |
|
if(ray_intersect_tri(orig,dir,p0,p1,p2,p)) |
1906 |
|
{ |
1907 |
< |
if(!base) |
1908 |
< |
{ |
1909 |
< |
d = DIST_SQ(p,p0); |
1910 |
< |
d1 = DIST_SQ(p,p1); |
1911 |
< |
if(d < d1) |
1912 |
< |
{ |
1913 |
< |
d1 = DIST_SQ(p,p2); |
1986 |
< |
id = (d1 < d)?pid2:pid0; |
1987 |
< |
} |
1988 |
< |
else |
1989 |
< |
{ |
1990 |
< |
d = DIST_SQ(p,p2); |
1991 |
< |
id = (d < d1)? pid2:pid1; |
1992 |
< |
} |
1993 |
< |
} |
1907 |
> |
d = DIST_SQ(p,p0); |
1908 |
> |
d1 = DIST_SQ(p,p1); |
1909 |
> |
if(d < d1) |
1910 |
> |
{ |
1911 |
> |
d1 = DIST_SQ(p,p2); |
1912 |
> |
id = (d1 < d)?pid2:pid0; |
1913 |
> |
} |
1914 |
|
else |
1915 |
|
{ |
1916 |
< |
if(SM_BASE_ID(smMesh,pid0)) |
1917 |
< |
{ |
1998 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
1999 |
< |
id = pid2; |
2000 |
< |
else |
2001 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
2002 |
< |
id = pid1; |
2003 |
< |
else |
2004 |
< |
{ |
2005 |
< |
d = DIST_SQ(p,p1); |
2006 |
< |
d1 = DIST_SQ(p,p2); |
2007 |
< |
if(d < d1) |
2008 |
< |
id = pid1; |
2009 |
< |
else |
2010 |
< |
id = pid2; |
2011 |
< |
} |
2012 |
< |
} |
2013 |
< |
else |
2014 |
< |
{ |
2015 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
2016 |
< |
{ |
2017 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
2018 |
< |
id = pid0; |
2019 |
< |
else |
2020 |
< |
{ |
2021 |
< |
d = DIST_SQ(p,p0); |
2022 |
< |
d1 = DIST_SQ(p,p2); |
2023 |
< |
if(d < d1) |
2024 |
< |
id = pid0; |
2025 |
< |
else |
2026 |
< |
id = pid2; |
2027 |
< |
} |
2028 |
< |
} |
2029 |
< |
else |
2030 |
< |
{ |
2031 |
< |
d = DIST_SQ(p,p0); |
2032 |
< |
d1 = DIST_SQ(p,p1); |
2033 |
< |
if(d < d1) |
2034 |
< |
id = pid0; |
2035 |
< |
else |
2036 |
< |
id = pid1; |
2037 |
< |
} |
2038 |
< |
} |
1916 |
> |
d = DIST_SQ(p,p2); |
1917 |
> |
id = (d < d1)? pid2:pid1; |
1918 |
|
} |
1919 |
|
if(pt) |
1920 |
|
VCOPY(pt,p); |
2051 |
|
#ifdef DEBUG_TEST_DRIVER |
2052 |
|
VCOPY(Pick_point[0],p); |
2053 |
|
#endif |
2175 |
– |
#ifdef DEBUG |
2176 |
– |
fprintf(stderr,"Simple pick returning %d\n",s_id); |
2177 |
– |
#endif |
2178 |
– |
|
2054 |
|
return(s_id); |
2055 |
|
} |
2056 |
|
d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh)); |
2064 |
|
#ifdef DEBUG_TEST_DRIVER |
2065 |
|
VCOPY(Pick_point[0],p); |
2066 |
|
#endif |
2192 |
– |
#ifdef DEBUG |
2193 |
– |
fprintf(stderr,"Simple pick2 returning %d\n",s_id); |
2194 |
– |
#endif |
2067 |
|
return(s_id); |
2068 |
|
} |
2069 |
|
if(OPP_EQUAL_VEC3(b,dir)) |
2113 |
|
F_ARGS(func) = (int *)(&rt); |
2114 |
|
stTrace_ray(SM_LOCATOR(smMesh),o,dir,func); |
2115 |
|
s_id = rt.t_id; |
2116 |
+ |
|
2117 |
|
} |
2245 |
– |
#ifdef DEBUG |
2246 |
– |
fprintf(stderr,"Trace pick returning %d\n",s_id); |
2247 |
– |
#endif |
2118 |
|
return(s_id); |
2119 |
|
|
2120 |
|
Lerror: |
2125 |
|
|
2126 |
|
} |
2127 |
|
|
2128 |
+ |
null_func(argptr,root,qt,n) |
2129 |
+ |
int *argptr; |
2130 |
+ |
int root; |
2131 |
+ |
QUADTREE qt; |
2132 |
+ |
int n; |
2133 |
+ |
{ |
2134 |
+ |
/* do nothing */ |
2135 |
+ |
} |
2136 |
|
|
2137 |
< |
mark_active_tris(argptr,root,qt) |
2137 |
> |
mark_active_tris(argptr,root,qt,n) |
2138 |
|
int *argptr; |
2139 |
|
int root; |
2140 |
|
QUADTREE qt; |
2141 |
+ |
int n; |
2142 |
|
{ |
2143 |
|
OBJECT *os,*optr; |
2144 |
|
register int i,t_id; |
2166 |
|
} |
2167 |
|
|
2168 |
|
|
2169 |
< |
mark_tris_in_frustum(view) |
2169 |
> |
smCull(sm,view,n) |
2170 |
> |
SM *sm; |
2171 |
|
VIEW *view; |
2172 |
+ |
int n; |
2173 |
|
{ |
2174 |
|
FVECT nr[4],far[4]; |
2175 |
|
FPEQ peq; |
2176 |
|
int debug=0; |
2177 |
|
FUNC f; |
2178 |
|
|
2179 |
< |
F_FUNC(f) = mark_active_tris; |
2180 |
< |
F_ARGS(f) = NULL; |
2179 |
> |
/* First clear all the quadtree node flags */ |
2180 |
> |
qtClearAllFlags(); |
2181 |
|
|
2182 |
+ |
F_ARGS(f) = NULL; |
2183 |
+ |
/* If marking samples down to leaves */ |
2184 |
+ |
if(n == SM_ALL_LEVELS) |
2185 |
+ |
{ |
2186 |
|
/* Mark triangles in approx. view frustum as being active:set |
2187 |
|
LRU counter: for use in discarding samples when out |
2188 |
|
of space |
2189 |
+ |
*/ |
2190 |
+ |
F_FUNC(f) = mark_active_tris; |
2191 |
+ |
smClear_flags(sm,T_ACTIVE_FLAG); |
2192 |
+ |
/* Clear all of the active sample flags*/ |
2193 |
+ |
sClear_all_flags(SM_SAMP(sm)); |
2194 |
+ |
} |
2195 |
+ |
else |
2196 |
+ |
/* Just mark qtree flags */ |
2197 |
+ |
F_FUNC(f) = null_func; |
2198 |
+ |
|
2199 |
+ |
/* calculate the world space coordinates of the view frustum: |
2200 |
|
Radiance often has no far clipping plane: but driver will set |
2201 |
|
dev_zmin,dev_zmax to satisfy OGL |
2202 |
< |
*/ |
2307 |
< |
|
2308 |
< |
/* First clear all the quadtree node and triangle active flags */ |
2309 |
< |
qtClearAllFlags(); |
2310 |
< |
smClear_flags(smMesh,T_ACTIVE_FLAG); |
2311 |
< |
/* Clear all of the active sample flags*/ |
2312 |
< |
sClear_all_flags(SM_SAMP(smMesh)); |
2313 |
< |
|
2314 |
< |
|
2315 |
< |
/* calculate the world space coordinates of the view frustum */ |
2202 |
> |
*/ |
2203 |
|
calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz, |
2204 |
|
view->vert, dev_zmin,dev_zmax,nr,far); |
2205 |
|
|
2220 |
|
Also set the triangles LRU clock counter |
2221 |
|
*/ |
2222 |
|
|
2223 |
< |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(smMesh))) |
2223 |
> |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(sm))) |
2224 |
|
{/* Near face triangles */ |
2225 |
|
|
2226 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2227 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2226 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2227 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2228 |
|
return; |
2229 |
|
} |
2230 |
|
/* Test the view against the planes: and swap orientation if inside:*/ |
2231 |
|
tri_plane_equation(nr[0],nr[2],nr[3], &peq,FALSE); |
2232 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2232 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2233 |
|
{/* Near face triangles */ |
2234 |
< |
smLocator_apply(smMesh,nr[3],nr[2],nr[0],f); |
2235 |
< |
smLocator_apply(smMesh,nr[1],nr[0],nr[2],f); |
2234 |
> |
smLocator_apply(sm,nr[3],nr[2],nr[0],f,n); |
2235 |
> |
smLocator_apply(sm,nr[1],nr[0],nr[2],f,n); |
2236 |
|
} |
2237 |
|
else |
2238 |
|
{/* Near face triangles */ |
2239 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2240 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2239 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2240 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2241 |
|
} |
2242 |
|
tri_plane_equation(nr[0],far[3],far[0], &peq,FALSE); |
2243 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2243 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2244 |
|
{ /* Right face triangles */ |
2245 |
< |
smLocator_apply(smMesh,far[0],far[3],nr[0],f); |
2246 |
< |
smLocator_apply(smMesh,nr[3],nr[0],far[3],f); |
2245 |
> |
smLocator_apply(sm,far[0],far[3],nr[0],f,n); |
2246 |
> |
smLocator_apply(sm,nr[3],nr[0],far[3],f,n); |
2247 |
|
} |
2248 |
|
else |
2249 |
|
{/* Right face triangles */ |
2250 |
< |
smLocator_apply(smMesh,nr[0],far[3],far[0],f); |
2251 |
< |
smLocator_apply(smMesh,far[3],nr[0],nr[3],f); |
2250 |
> |
smLocator_apply(sm,nr[0],far[3],far[0],f,n); |
2251 |
> |
smLocator_apply(sm,far[3],nr[0],nr[3],f,n); |
2252 |
|
} |
2253 |
|
|
2254 |
|
tri_plane_equation(nr[1],far[2],nr[2], &peq,FALSE); |
2255 |
|
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2256 |
|
{ /* Left face triangles */ |
2257 |
< |
smLocator_apply(smMesh,nr[2],far[2],nr[1],f); |
2258 |
< |
smLocator_apply(smMesh,far[1],nr[1],far[2],f); |
2257 |
> |
smLocator_apply(sm,nr[2],far[2],nr[1],f,n); |
2258 |
> |
smLocator_apply(sm,far[1],nr[1],far[2],f,n); |
2259 |
|
} |
2260 |
|
else |
2261 |
|
{ /* Left face triangles */ |
2262 |
< |
smLocator_apply(smMesh,nr[1],far[2],nr[2],f); |
2263 |
< |
smLocator_apply(smMesh,far[2],nr[1],far[1],f); |
2262 |
> |
smLocator_apply(sm,nr[1],far[2],nr[2],f,n); |
2263 |
> |
smLocator_apply(sm,far[2],nr[1],far[1],f,n); |
2264 |
|
} |
2265 |
|
tri_plane_equation(nr[0],far[0],nr[1], &peq,FALSE); |
2266 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2266 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2267 |
|
{/* Top face triangles */ |
2268 |
< |
smLocator_apply(smMesh,nr[1],far[0],nr[0],f); |
2269 |
< |
smLocator_apply(smMesh,far[1],far[0],nr[1],f); |
2268 |
> |
smLocator_apply(sm,nr[1],far[0],nr[0],f,n); |
2269 |
> |
smLocator_apply(sm,far[1],far[0],nr[1],f,n); |
2270 |
|
} |
2271 |
|
else |
2272 |
|
{/* Top face triangles */ |
2273 |
< |
smLocator_apply(smMesh,nr[0],far[0],nr[1],f); |
2274 |
< |
smLocator_apply(smMesh,nr[1],far[0],far[1],f); |
2273 |
> |
smLocator_apply(sm,nr[0],far[0],nr[1],f,n); |
2274 |
> |
smLocator_apply(sm,nr[1],far[0],far[1],f,n); |
2275 |
|
} |
2276 |
|
tri_plane_equation(nr[3],nr[2],far[3], &peq,FALSE); |
2277 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2277 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2278 |
|
{/* Bottom face triangles */ |
2279 |
< |
smLocator_apply(smMesh,far[3],nr[2],nr[3],f); |
2280 |
< |
smLocator_apply(smMesh,far[3],far[2],nr[2],f); |
2279 |
> |
smLocator_apply(sm,far[3],nr[2],nr[3],f,n); |
2280 |
> |
smLocator_apply(sm,far[3],far[2],nr[2],f,n); |
2281 |
|
} |
2282 |
|
else |
2283 |
|
{ /* Bottom face triangles */ |
2284 |
< |
smLocator_apply(smMesh,nr[3],nr[2],far[3],f); |
2285 |
< |
smLocator_apply(smMesh,nr[2],far[2],far[3],f); |
2284 |
> |
smLocator_apply(sm,nr[3],nr[2],far[3],f,n); |
2285 |
> |
smLocator_apply(sm,nr[2],far[2],far[3],f,n); |
2286 |
|
} |
2287 |
|
tri_plane_equation(far[2],far[0],far[1], &peq,FALSE); |
2288 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2288 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2289 |
|
{/* Far face triangles */ |
2290 |
< |
smLocator_apply(smMesh,far[0],far[2],far[1],f); |
2291 |
< |
smLocator_apply(smMesh,far[2],far[0],far[3],f); |
2290 |
> |
smLocator_apply(sm,far[0],far[2],far[1],f,n); |
2291 |
> |
smLocator_apply(sm,far[2],far[0],far[3],f,n); |
2292 |
|
} |
2293 |
|
else |
2294 |
|
{/* Far face triangles */ |
2295 |
< |
smLocator_apply(smMesh,far[1],far[2],far[0],f); |
2296 |
< |
smLocator_apply(smMesh,far[3],far[0],far[2],f); |
2295 |
> |
smLocator_apply(sm,far[1],far[2],far[0],f,n); |
2296 |
> |
smLocator_apply(sm,far[3],far[0],far[2],f,n); |
2297 |
|
} |
2298 |
|
|
2299 |
|
} |