1
7
8 #include "moab/IntxMesh/Intx2MeshInPlane.hpp"
9 #include "moab/GeomUtil.hpp"
10 #include "moab/IntxMesh/IntxUtils.hpp"
11
12 namespace moab
13 {
14
15 Intx2MeshInPlane::Intx2MeshInPlane( Interface* mbimpl ) : Intx2Mesh( mbimpl ) {}
16
17 Intx2MeshInPlane::~Intx2MeshInPlane() {}
18
19 double Intx2MeshInPlane::setup_tgt_cell( EntityHandle tgt, int& nsTgt )
20 {
21
22
23
24 double cellArea = 0;
25 int num_nodes;
26 ErrorCode rval = mb->get_connectivity( tgt, tgtConn, num_nodes );
27 if( MB_SUCCESS != rval ) return 1.;
28
29 nsTgt = num_nodes;
30
31 rval = mb->get_coords( tgtConn, num_nodes, &( tgtCoords[0][0] ) );
32 if( MB_SUCCESS != rval ) return 1.;
33
34 for( int j = 0; j < nsTgt; j++ )
35 {
36
37
38 tgtCoords2D[2 * j] = tgtCoords[j][0];
39 tgtCoords2D[2 * j + 1] = tgtCoords[j][1];
40 }
41 for( int j = 1; j < nsTgt - 1; j++ )
42 cellArea += IntxUtils::area2D( &tgtCoords2D[0], &tgtCoords2D[2 * j], &tgtCoords2D[2 * j + 2] );
43
44 return cellArea;
45 }
46
47 ErrorCode Intx2MeshInPlane::computeIntersectionBetweenTgtAndSrc( EntityHandle tgt,
48 EntityHandle src,
49 double* P,
50 int& nP,
51 double& area,
52 int markb[MAXEDGES],
53 int markr[MAXEDGES],
54 int& nsSrc,
55 int& nsTgt,
56 bool check_boxes_first )
57 {
58
59 int num_nodes = 0;
60 ErrorCode rval = mb->get_connectivity( src, srcConn, num_nodes );MB_CHK_ERR( rval );
61
62 nsSrc = num_nodes;
63 rval = mb->get_coords( srcConn, num_nodes, &( srcCoords[0][0] ) );MB_CHK_ERR( rval );
64
65 area = 0.;
66 nP = 0;
67 if( check_boxes_first )
68 {
69 setup_tgt_cell( tgt, nsTgt );
70
71 if( !GeomUtil::bounding_boxes_overlap( tgtCoords, nsTgt, srcCoords, nsSrc, box_error ) )
72 return MB_SUCCESS;
73 }
74 #ifdef ENABLE_DEBUG
75 if( dbg_1 )
76 {
77 std::cout << "tgt " << mb->id_from_handle( tgt ) << "\n";
78 for( int j = 0; j < nsTgt; j++ )
79 {
80 std::cout << tgtCoords[j] << "\n";
81 }
82 std::cout << "src " << mb->id_from_handle( src ) << "\n";
83 for( int j = 0; j < nsSrc; j++ )
84 {
85 std::cout << srcCoords[j] << "\n";
86 }
87 mb->list_entities( &tgt, 1 );
88 mb->list_entities( &src, 1 );
89 }
90 #endif
91
92 for( int j = 0; j < nsSrc; j++ )
93 {
94 srcCoords2D[2 * j] = srcCoords[j][0];
95 srcCoords2D[2 * j + 1] = srcCoords[j][1];
96 }
97 #ifdef ENABLE_DEBUG
98 if( dbg_1 )
99 {
100
101 std::cout << " tgt \n";
102 for( int j = 0; j < nsTgt; j++ )
103 {
104 std::cout << tgtCoords2D[2 * j] << " " << tgtCoords2D[2 * j + 1] << "\n ";
105 }
106 std::cout << " src\n";
107 for( int j = 0; j < nsSrc; j++ )
108 {
109 std::cout << srcCoords2D[2 * j] << " " << srcCoords2D[2 * j + 1] << "\n";
110 }
111 }
112 #endif
113
114 rval = IntxUtils::EdgeIntersections2( srcCoords2D, nsSrc, tgtCoords2D, nsTgt, markb, markr, P, nP );MB_CHK_ERR( rval );
115 #ifdef ENABLE_DEBUG
116 if( dbg_1 )
117 {
118 for( int k = 0; k < 3; k++ )
119 {
120 std::cout << " markb, markr: " << k << " " << markb[k] << " " << markr[k] << "\n";
121 }
122 }
123 #endif
124
125 int side[MAXEDGES] = { 0 };
126 int extraPoints =
127 IntxUtils::borderPointsOfXinY2( srcCoords2D, nsSrc, tgtCoords2D, nsTgt, &( P[2 * nP] ), side, epsilon_area );
128 if( extraPoints >= 1 )
129 {
130 for( int k = 0; k < nsSrc; k++ )
131 {
132 if( side[k] )
133 {
134
135
136
137
138 markb[k] = 1;
139 markb[( k + nsSrc - 1 ) % nsSrc] =
140 1;
141
142
143 side[k] = 0;
144 }
145 }
146 }
147 #ifdef ENABLE_DEBUG
148 if( dbg_1 )
149 {
150 for( int k = 0; k < 3; k++ )
151 {
152 std::cout << " markb, markr: " << k << " " << markb[k] << " " << markr[k] << "\n";
153 }
154 }
155 #endif
156 nP += extraPoints;
157
158 extraPoints =
159 IntxUtils::borderPointsOfXinY2( tgtCoords2D, nsTgt, srcCoords2D, nsSrc, &( P[2 * nP] ), side, epsilon_area );
160 if( extraPoints >= 1 )
161 {
162 for( int k = 0; k < nsTgt; k++ )
163 {
164 if( side[k] )
165 {
166
167 markr[k] = 1;
168 markr[( k + nsTgt - 1 ) % nsTgt] =
169 1;
170
171
172 }
173 }
174 }
175 #ifdef ENABLE_DEBUG
176 if( dbg_1 )
177 {
178 for( int k = 0; k < 3; k++ )
179 {
180 std::cout << " markb, markr: " << k << " " << markb[k] << " " << markr[k] << "\n";
181 }
182 }
183 #endif
184 nP += extraPoints;
185
186
187
188
189 IntxUtils::SortAndRemoveDoubles2( P, nP, epsilon_1 );
190
191
192 if( nP >= 3 )
193 {
194 for( int k = 1; k < nP - 1; k++ )
195 area += IntxUtils::area2D( P, &P[2 * k], &P[2 * k + 2] );
196 }
197
198 return MB_SUCCESS;
199 }
200
201
202
203
204
205
206 ErrorCode Intx2MeshInPlane::findNodes( EntityHandle tgt, int nsTgt, EntityHandle src, int nsSrc, double* iP, int nP )
207 {
208
209
210
211
212 #ifdef ENABLE_DEBUG
213 if( dbg_1 )
214 {
215 std::cout << "tgt, src, nP, P " << mb->id_from_handle( tgt ) << " " << mb->id_from_handle( src ) << " " << nP
216 << "\n";
217 for( int n = 0; n < nP; n++ )
218 std::cout << " \t" << iP[2 * n] << "\t" << iP[2 * n + 1] << "\n";
219 }
220 #endif
221
222
223
224
225
226
227 EntityHandle adjTgtEdges[MAXEDGES];
228 ErrorCode rval = mb->tag_get_data( neighTgtEdgeTag, &tgt, 1, &( adjTgtEdges[0] ) );MB_CHK_SET_ERR( rval, "can't get edge tgt tag" );
229
230
231
232
233
234
235 EntityHandle* foundIds = new EntityHandle[nP];
236 for( int i = 0; i < nP; i++ )
237 {
238 double* pp = &iP[2 * i];
239
240 CartVect pos( pp[0], pp[1], 0. );
241 int found = 0;
242
243
244 int j = 0;
245 EntityHandle outNode = (EntityHandle)0;
246 for( j = 0; j < nsTgt && !found; j++ )
247 {
248
249 double d2 = IntxUtils::dist2( pp, &tgtCoords2D[2 * j] );
250 if( d2 < epsilon_1 )
251 {
252
253 foundIds[i] = tgtConn[j];
254 found = 1;
255 #ifdef ENABLE_DEBUG
256 if( dbg_1 )
257 std::cout << " tgt node j:" << j << " id:" << mb->id_from_handle( tgtConn[j] )
258 << " 2d coords:" << tgtCoords2D[2 * j] << " " << tgtCoords2D[2 * j + 1] << " d2: " << d2
259 << " \n";
260 #endif
261 }
262 }
263
264 for( j = 0; j < nsSrc && !found; j++ )
265 {
266
267 double d2 = IntxUtils::dist2( pp, &srcCoords2D[2 * j] );
268 if( d2 < epsilon_1 )
269 {
270
271
272 foundIds[i] = srcConn[j];
273 found = 1;
274 #ifdef ENABLE_DEBUG
275 if( dbg_1 )
276 std::cout << " src node " << j << " " << mb->id_from_handle( srcConn[j] ) << " d2:" << d2 << " \n";
277 #endif
278 }
279 }
280 if( !found )
281 {
282
283
284 for( j = 0; j < nsTgt; j++ )
285 {
286 int j1 = ( j + 1 ) % nsTgt;
287 double area = IntxUtils::area2D( &tgtCoords2D[2 * j], &tgtCoords2D[2 * j1], pp );
288 #ifdef ENABLE_DEBUG
289 if( dbg_1 )
290 std::cout << " edge " << j << ": " << mb->id_from_handle( adjTgtEdges[j] ) << " " << tgtConn[j]
291 << " " << tgtConn[j1] << " area : " << area << "\n";
292 #endif
293 if( fabs( area ) < epsilon_1 / 2 )
294 {
295
296
297 int indx = TgtEdges.index( adjTgtEdges[j] );
298 if( indx < 0 )
299 {
300 std::cerr << " error in adjacent tgt edge: " << mb->id_from_handle( adjTgtEdges[j] ) << "\n";
301 delete[] foundIds;
302 return MB_FAILURE;
303 }
304 std::vector< EntityHandle >* expts = extraNodesVec[indx];
305
306
307
308 int nbExtraNodesSoFar = expts->size();
309 if( nbExtraNodesSoFar > 0 )
310 {
311 CartVect* coords1 = new CartVect[nbExtraNodesSoFar];
312 mb->get_coords( &( *expts )[0], nbExtraNodesSoFar, &( coords1[0][0] ) );
313
314 for( int k = 0; k < nbExtraNodesSoFar && !found; k++ )
315 {
316
317 double d3 = ( pos - coords1[k] ).length_squared();
318 if( d3 < epsilon_1 )
319 {
320 found = 1;
321 foundIds[i] = ( *expts )[k];
322 #ifdef ENABLE_DEBUG
323 if( dbg_1 ) std::cout << " found node:" << foundIds[i] << std::endl;
324 #endif
325 }
326 }
327 delete[] coords1;
328 }
329
330 if( !found )
331 {
332
333
334
335
336
337 mb->create_vertex( pos.array(), outNode );
338 ( *expts ).push_back( outNode );
339 foundIds[i] = outNode;
340 found = 1;
341 #ifdef ENABLE_DEBUG
342 if( dbg_1 ) std::cout << " new node: " << outNode << std::endl;
343 #endif
344 }
345 }
346 }
347 }
348 if( !found )
349 {
350 std::cout << " tgt polygon: ";
351 for( int j1 = 0; j1 < nsTgt; j1++ )
352 {
353 std::cout << tgtCoords2D[2 * j1] << " " << tgtCoords2D[2 * j1 + 1] << "\n";
354 }
355 std::cout << " a point pp is not on a tgt polygon " << *pp << " " << pp[1] << " tgt polygon "
356 << mb->id_from_handle( tgt ) << " \n";
357 delete[] foundIds;
358 return MB_FAILURE;
359 }
360 }
361 #ifdef ENABLE_DEBUG
362 if( dbg_1 )
363 {
364 std::cout << " candidate polygon: nP " << nP << "\n";
365 for( int i1 = 0; i1 < nP; i1++ )
366 std::cout << iP[2 * i1] << " " << iP[2 * i1 + 1] << " " << foundIds[i1] << "\n";
367 }
368 #endif
369
370
371
372
373 correct_polygon( foundIds, nP );
374
375
376 if( nP >= 3 )
377 {
378 EntityHandle polyNew;
379 mb->create_element( MBPOLYGON, foundIds, nP, polyNew );
380 mb->add_entities( outSet, &polyNew, 1 );
381
382
383 int id = rs1.index( src );
384 mb->tag_set_data( srcParentTag, &polyNew, 1, &id );
385 id = rs2.index( tgt );
386 mb->tag_set_data( tgtParentTag, &polyNew, 1, &id );
387
388 counting++;
389 mb->tag_set_data( countTag, &polyNew, 1, &counting );
390
391 #ifdef ENABLE_DEBUG
392 if( dbg_1 )
393 {
394
395 std::cout << "Count: " << counting + 1 << "\n";
396 std::cout << " polygon " << mb->id_from_handle( polyNew ) << " nodes: " << nP << " :";
397 for( int i1 = 0; i1 < nP; i1++ )
398 std::cout << " " << mb->id_from_handle( foundIds[i1] );
399 std::cout << "\n";
400 std::vector< CartVect > posi( nP );
401 mb->get_coords( foundIds, nP, &( posi[0][0] ) );
402 for( int i1 = 0; i1 < nP; i1++ )
403 std::cout << iP[2 * i1] << " " << iP[2 * i1 + 1] << " " << posi[i1] << "\n";
404
405 std::stringstream fff;
406 fff << "file0" << counting << ".vtk";
407 mb->write_mesh( fff.str().c_str(), &outSet, 1 );
408 }
409 #endif
410 }
411 delete[] foundIds;
412 foundIds = NULL;
413 return MB_SUCCESS;
414
415 }
416
417 }