PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/brlcad/tags/rel-7-16-8/src/conv/iges/make_nurb_face.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 445 lines | 338 code | 63 blank | 44 comment | 64 complexity | 64032ec1f3d4040357491b98915aac50 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /* M A K E _ N U R B _ F A C E . C
  2. * BRL-CAD
  3. *
  4. * Copyright (c) 1995-2010 United States Government as represented by
  5. * the U.S. Army Research Laboratory.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public License
  9. * version 2.1 as published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this file; see the file named COPYING for more
  18. * information.
  19. */
  20. /** @file make_nurb_face.c
  21. *
  22. */
  23. #include "./iges_struct.h"
  24. #include "./iges_extern.h"
  25. int
  26. Add_nurb_loop_to_face( s, fu, loop_entityno, face_orient )
  27. struct shell *s;
  28. struct faceuse *fu;
  29. int loop_entityno;
  30. int face_orient;
  31. {
  32. int i, j, k;
  33. int entity_type;
  34. int no_of_edges;
  35. int no_of_param_curves;
  36. int vert_no;
  37. struct face *f;
  38. struct face_g_snurb *srf;
  39. struct faceuse *fu_ret;
  40. struct loopuse *lu;
  41. struct edgeuse *eu;
  42. struct vertex **verts;
  43. struct iges_edge_use *edge_uses;
  44. NMG_CK_SHELL( s );
  45. NMG_CK_FACEUSE( fu );
  46. f = fu->f_p;
  47. NMG_CK_FACE( f );
  48. srf = f->g.snurb_p;
  49. NMG_CK_FACE_G_SNURB( srf );
  50. if ( dir[loop_entityno]->param <= pstart )
  51. {
  52. bu_log( "Illegal parameter pointer for entity D%07d (%s), loop ignored\n" ,
  53. dir[loop_entityno]->direct, dir[loop_entityno]->name );
  54. return( 0 );
  55. }
  56. if ( dir[loop_entityno]->type != 508 )
  57. {
  58. bu_exit(1, "ERROR: Entity #%d is not a loop (it's a %s)\n", loop_entityno, iges_type(dir[loop_entityno]->type) );
  59. }
  60. Readrec( dir[loop_entityno]->param );
  61. Readint( &entity_type, "" );
  62. if ( entity_type != 508 )
  63. {
  64. bu_exit(1, "Add_nurb_loop_to_face ERROR: Entity #%d is not a loop (it's a %s)\n",
  65. loop_entityno, iges_type(entity_type) );
  66. }
  67. Readint( &no_of_edges, "" );
  68. edge_uses = (struct iges_edge_use *)bu_calloc( no_of_edges, sizeof( struct iges_edge_use ) ,
  69. "Add_nurb_loop_to_face (edge_uses)" );
  70. for ( i=0; i<no_of_edges; i++ )
  71. {
  72. Readint( &edge_uses[i].edge_is_vertex, "" );
  73. Readint( &edge_uses[i].edge_de, "" );
  74. Readint( &edge_uses[i].index, "" );
  75. Readint( &edge_uses[i].orient, "" );
  76. edge_uses[i].root = (struct iges_param_curve *)NULL;
  77. Readint( &no_of_param_curves, "" );
  78. for ( j=0; j<no_of_param_curves; j++ )
  79. {
  80. struct iges_param_curve *new_crv;
  81. struct iges_param_curve *crv;
  82. Readint( &k, "" ); /* ignore iso-parametric flag */
  83. new_crv = (struct iges_param_curve *)bu_malloc( sizeof( struct iges_param_curve ),
  84. "Add_nurb_loop_to_face: new_crv" );
  85. if ( edge_uses[i].root == (struct iges_param_curve *)NULL )
  86. edge_uses[i].root = new_crv;
  87. else
  88. {
  89. crv = edge_uses[i].root;
  90. while ( crv->next != (struct iges_param_curve *)NULL )
  91. crv = crv->next;
  92. crv->next = new_crv;
  93. }
  94. Readint( &new_crv->curve_de, "" );
  95. new_crv->next = (struct iges_param_curve *)NULL;
  96. }
  97. }
  98. verts = (struct vertex **)bu_calloc( no_of_edges, sizeof( struct vertex *) ,
  99. "Add_nurb_loop_to_face: vertex_list **" );
  100. for ( i=0; i<no_of_edges; i++ )
  101. {
  102. struct vertex **v;
  103. v = Get_vertex( &edge_uses[i] );
  104. if ( *v )
  105. verts[i] = (*v);
  106. else
  107. verts[i] = (struct vertex *)NULL;
  108. }
  109. fu_ret = nmg_add_loop_to_face( s, fu, verts, no_of_edges, OT_SAME );
  110. for ( i=0; i<no_of_edges; i++ )
  111. {
  112. struct vertex **v;
  113. v = Get_vertex( &edge_uses[i] );
  114. if ( !(*v) )
  115. {
  116. if ( !Put_vertex( verts[i], &edge_uses[i] ) )
  117. {
  118. bu_exit(1, "Cannot put vertex x%x\n", verts[i] );
  119. }
  120. }
  121. }
  122. lu = BU_LIST_LAST( loopuse, &fu_ret->lu_hd );
  123. NMG_CK_LOOPUSE( lu );
  124. i = no_of_edges - 1;
  125. for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) )
  126. {
  127. struct vertex **v;
  128. v = Get_vertex( &edge_uses[i] );
  129. if ( *v != eu->vu_p->v_p )
  130. {
  131. nmg_jv( *v, eu->vu_p->v_p );
  132. verts[i] = *v;
  133. }
  134. i++;
  135. if ( i == no_of_edges )
  136. i = 0;
  137. }
  138. /* assign geometry to vertices */
  139. for ( vert_no=0; vert_no < no_of_edges; vert_no++ )
  140. {
  141. struct iges_vertex *ivert;
  142. ivert = Get_iges_vertex( verts[vert_no] );
  143. if ( !ivert )
  144. {
  145. bu_exit(1, "ERROR: Can't get geometry, vertex x%x not in vertex list\n", verts[vert_no] );
  146. }
  147. nmg_vertex_gv( ivert->v, ivert->pt );
  148. }
  149. /* assign geometry to edges */
  150. i = no_of_edges - 1;
  151. for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) )
  152. {
  153. int next_edge_no;
  154. struct iges_param_curve *param;
  155. struct vertex *ivert, *jvert;
  156. next_edge_no = i + 1;
  157. if ( next_edge_no == no_of_edges )
  158. next_edge_no = 0;
  159. ivert = (*Get_vertex( &edge_uses[i] ) );
  160. if ( !ivert )
  161. bu_exit(1, "Cannot get vertex for edge_use!\n" );
  162. jvert = (*Get_vertex( &edge_uses[next_edge_no] ) );
  163. if ( !jvert )
  164. bu_exit(1, "Cannot get vertex for edge_use!\n" );
  165. if ( ivert != eu->vu_p->v_p || jvert != eu->eumate_p->vu_p->v_p )
  166. {
  167. bu_log( "ivert=x%x, jvert=x%x, eu->vu_p->v_p=x%x, eu->eumate_p->vu_p->v_p=x%x\n",
  168. ivert, jvert, eu->vu_p->v_p, eu->eumate_p->vu_p->v_p );
  169. bu_exit(1, "Add_nurb_loop_to_face: Edgeuse/vertex mixup!\n" );
  170. }
  171. param = edge_uses[i].root;
  172. if ( !param )
  173. {
  174. bu_log( "No parameter curve for eu x%x\n", eu );
  175. continue;
  176. }
  177. while ( param )
  178. {
  179. int linear;
  180. int coords;
  181. struct edge_g_cnurb *crv;
  182. struct vertex *v2;
  183. struct edgeuse *new_eu;
  184. point_t start_uv;
  185. point_t end_uv;
  186. hpoint_t pt_on_srf;
  187. v2 = (struct vertex *)NULL;
  188. /* Get NURB curve in parameter space for This edgeuse */
  189. crv = Get_cnurb_curve( param->curve_de, &linear );
  190. coords = RT_NURB_EXTRACT_COORDS( crv->pt_type );
  191. VMOVE( start_uv, crv->ctl_points );
  192. VMOVE( end_uv, &crv->ctl_points[(crv->c_size-1)*coords] );
  193. if ( coords == 2 )
  194. {
  195. start_uv[2] = 1.0;
  196. end_uv[2] = 1.0;
  197. }
  198. if ( param->next )
  199. {
  200. /* need to split this edge to agree with parameter curves */
  201. new_eu = nmg_esplit( v2, eu, 0 );
  202. /* evaluate srf at the parameter values for v2 to get geometry */
  203. if ( RT_NURB_EXTRACT_PT_TYPE( crv->pt_type ) == RT_NURB_PT_UV &&
  204. RT_NURB_IS_PT_RATIONAL( crv->pt_type ) )
  205. {
  206. rt_nurb_s_eval( srf, end_uv[0]/end_uv[2],
  207. end_uv[1]/end_uv[2], pt_on_srf );
  208. }
  209. else if ( coords == 2 )
  210. rt_nurb_s_eval( srf, end_uv[0], end_uv[1], pt_on_srf );
  211. if ( RT_NURB_IS_PT_RATIONAL( srf->pt_type ) )
  212. {
  213. fastf_t scale;
  214. scale = 1.0/pt_on_srf[3];
  215. VSCALE( pt_on_srf, pt_on_srf, scale );
  216. }
  217. nmg_vertex_gv( v2, pt_on_srf );
  218. }
  219. else
  220. new_eu = (struct edgeuse *)NULL;
  221. if ( eu->vu_p->v_p == eu->eumate_p->vu_p->v_p )
  222. {
  223. /* this edge runs to/from one vertex, need to split */
  224. struct bu_list split_hd;
  225. struct edge_g_cnurb *crv1, *crv2;
  226. point_t start_uv, end_uv;
  227. hpoint_t pt_on_srf;
  228. BU_LIST_INIT( &split_hd );
  229. /* split the edge */
  230. v2 = (struct vertex *)NULL;
  231. new_eu = nmg_esplit( v2, eu, 0 );
  232. /* split the curve */
  233. rt_nurb_c_split( &split_hd, crv );
  234. crv1 = BU_LIST_FIRST( edge_g_cnurb, &split_hd );
  235. crv2 = BU_LIST_LAST( edge_g_cnurb, &split_hd );
  236. /* get geometry for new vertex */
  237. coords = RT_NURB_EXTRACT_COORDS( crv1->pt_type );
  238. VMOVE( start_uv, crv1->ctl_points );
  239. VMOVE( end_uv, &crv1->ctl_points[(crv1->c_size-1)*coords] );
  240. if ( RT_NURB_EXTRACT_PT_TYPE( crv1->pt_type ) == RT_NURB_PT_UV &&
  241. RT_NURB_IS_PT_RATIONAL( crv1->pt_type ) )
  242. {
  243. rt_nurb_s_eval( srf, end_uv[0]/end_uv[2],
  244. end_uv[1]/end_uv[2], pt_on_srf );
  245. }
  246. else
  247. {
  248. start_uv[2] = 1.0;
  249. end_uv[2] = 1.0;
  250. rt_nurb_s_eval( srf, end_uv[0], end_uv[1], pt_on_srf );
  251. }
  252. if ( RT_NURB_IS_PT_RATIONAL( srf->pt_type ) )
  253. {
  254. fastf_t scale;
  255. scale = 1.0/pt_on_srf[3];
  256. VSCALE( pt_on_srf, pt_on_srf, scale );
  257. }
  258. /* assign geometry */
  259. nmg_vertex_gv( new_eu->vu_p->v_p, pt_on_srf );
  260. nmg_vertexuse_a_cnurb( eu->vu_p, start_uv );
  261. nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, end_uv );
  262. if ( linear )
  263. nmg_edge_g_cnurb_plinear( eu );
  264. else
  265. Assign_cnurb_to_eu( eu, crv1 );
  266. /* now the second section */
  267. coords = RT_NURB_EXTRACT_COORDS( crv2->pt_type );
  268. VMOVE( start_uv, crv2->ctl_points );
  269. VMOVE( end_uv, &crv2->ctl_points[(crv2->c_size-1)*coords] );
  270. if ( RT_NURB_EXTRACT_PT_TYPE( crv2->pt_type ) == RT_NURB_PT_UV &&
  271. RT_NURB_IS_PT_RATIONAL( crv2->pt_type ) )
  272. {
  273. rt_nurb_s_eval( srf, start_uv[0]/start_uv[2],
  274. start_uv[1]/start_uv[2], pt_on_srf );
  275. }
  276. else
  277. {
  278. start_uv[2] = 1.0;
  279. end_uv[2] = 1.0;
  280. rt_nurb_s_eval( srf, start_uv[0], start_uv[1], pt_on_srf );
  281. }
  282. if ( RT_NURB_IS_PT_RATIONAL( srf->pt_type ) )
  283. {
  284. fastf_t scale;
  285. scale = 1.0/pt_on_srf[3];
  286. VSCALE( pt_on_srf, pt_on_srf, scale );
  287. }
  288. /* assign geometry */
  289. nmg_vertexuse_a_cnurb( new_eu->vu_p, start_uv );
  290. nmg_vertexuse_a_cnurb( new_eu->eumate_p->vu_p, end_uv );
  291. if ( linear )
  292. nmg_edge_g_cnurb_plinear( new_eu );
  293. else
  294. Assign_cnurb_to_eu( new_eu, crv2 );
  295. /* free memory */
  296. while ( BU_LIST_NON_EMPTY( &split_hd ) )
  297. {
  298. struct edge_g_cnurb *tmp_crv;
  299. tmp_crv = BU_LIST_FIRST( edge_g_cnurb, &split_hd );
  300. BU_LIST_DEQUEUE( &tmp_crv->l );
  301. bu_free( (char *)tmp_crv, "Add_nurb_loop_to_face: tmp_crv" );
  302. }
  303. }
  304. else
  305. {
  306. nmg_vertexuse_a_cnurb( eu->vu_p, start_uv );
  307. nmg_vertexuse_a_cnurb( eu->eumate_p->vu_p, end_uv );
  308. if ( linear )
  309. nmg_edge_g_cnurb_plinear( eu );
  310. else
  311. Assign_cnurb_to_eu( eu, crv );
  312. }
  313. bu_free( (char *)crv->k.knots, "Add_nurb_loop_to_face: crv->k.knots" );
  314. bu_free( (char *)crv->ctl_points, "Add_nurb_loop_to_face: crv->ctl_points" );
  315. bu_free( (char *)crv, "Add_nurb_loop_to_face: crv" );
  316. if ( new_eu )
  317. eu = new_eu;
  318. param = param->next;
  319. }
  320. i++;
  321. if ( i == no_of_edges )
  322. i = 0;
  323. }
  324. return( 1 );
  325. #if 0
  326. err:
  327. for ( i=0; i<no_of_edges; i++ )
  328. {
  329. struct iges_param_curve *crv;
  330. crv = edge_uses[i].root;
  331. while ( crv )
  332. {
  333. struct iges_param_curve *tmp_crv;
  334. tmp_crv = crv;
  335. crv = crv->next;
  336. bu_free( (char *)tmp_crv, "Add_nurb_loop_to_face: tmp_crv" );
  337. }
  338. }
  339. bu_free( (char *)edge_uses, "Add_nurb_loop_to_face: (edge list)" );
  340. bu_free( (char *)verts, "Add_nurb_loop_to_face: (vertex list)" );
  341. return( 0 );
  342. #endif
  343. }
  344. struct faceuse *
  345. Make_nurb_face( s, surf_entityno )
  346. struct shell *s;
  347. int surf_entityno;
  348. {
  349. struct vertex *verts[1];
  350. struct loopuse *lu;
  351. struct faceuse *fu;
  352. struct face_g_snurb *srf;
  353. struct model *m;
  354. if ( dir[surf_entityno]->type != 128 )
  355. {
  356. bu_log( "Make_nurb_face: Called with surface entity (%d) of type %s\n", surf_entityno,
  357. iges_type( dir[surf_entityno]->type ) );
  358. bu_log( "Make_nurb_face: Can only handle surfaces of %s, ignoring face\n", iges_type( 128 ) );
  359. return( (struct faceuse *)NULL );
  360. }
  361. m = nmg_find_model( &s->l.magic );
  362. if ( (srf = Get_nurb_surf( surf_entityno, m )) == (struct face_g_snurb *)NULL )
  363. {
  364. bu_log( "Make_nurb_face: Get_nurb_surf failed for surface entity (%d), face ignored\n", surf_entityno );
  365. return( (struct faceuse *)NULL );
  366. }
  367. verts[0] = (struct vertex *)NULL;
  368. fu = nmg_cface( s, verts, 1 );
  369. Assign_surface_to_fu( fu, srf );
  370. lu = BU_LIST_FIRST( loopuse, &fu->lu_hd );
  371. (void)nmg_klu( lu );
  372. return( fu );
  373. }
  374. /*
  375. * Local Variables:
  376. * mode: C
  377. * tab-width: 8
  378. * indent-tabs-mode: t
  379. * c-file-style: "stroustrup"
  380. * End:
  381. * ex: shiftwidth=4 tabstop=8
  382. */