1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#ifndef FBENGINE_HPP_
#define FBENGINE_HPP_
#include <cstdlib>

#include <vector>
#include <map>

#include "moab/Types.hpp"
#include "moab/Interface.hpp"
#include "moab/Range.hpp"
#include "moab/CartVect.hpp"

namespace moab
{
class GeomTopoTool;

// some forward declarations
class SmoothFace;
class SmoothCurve;

/*
 *  Facet Based engine class for mesh-based geometry
 */
class FBEngine
{
  public:
    FBEngine( Interface* impl, GeomTopoTool* geomTopoTool = NULL, const bool smooth = false );

    ~FBEngine();

    ErrorCode Init();

    ErrorCode getRootSet( EntityHandle* root_set );

    ErrorCode getNumEntSets( EntityHandle set, int num_hops, int* all_sets );

    ErrorCode createEntSet( int isList, EntityHandle* pSet );

    ErrorCode addEntSet( EntityHandle entity_set_to_add, EntityHandle entity_set_handle );

    ErrorCode getEntities( EntityHandle root_set, int ent_type, Range& gentities );

    ErrorCode addEntArrToSet( const Range& entities, EntityHandle set );

    ErrorCode getNumOfType( EntityHandle set, int ent_type, int* pNum );

    ErrorCode getEntType( EntityHandle gent, int* type );

    ErrorCode getEntBoundBox( EntityHandle this_gent,
                              double* x0,
                              double* y0,
                              double* z0,
                              double* x1,
                              double* y1,
                              double* z1 );
    ErrorCode getEntClosestPt( EntityHandle this_gent,
                               double x,
                               double y,
                               double z,
                               double* x1,
                               double* y1,
                               double* y3 );

    ErrorCode getVtxCoord( EntityHandle this_gent, double* x0, double* y0, double* z0 );

    ErrorCode gsubtract( EntityHandle entity_set_1, EntityHandle entity_set_2, EntityHandle result_entity_set );

    ErrorCode getEntNrmlXYZ( EntityHandle entity_handle,
                             double x,
                             double y,
                             double z,
                             double* nrml_i,
                             double* nrml_j,
                             double* nrml_k );

    ErrorCode getPntRayIntsct( double x,
                               double y,
                               double z,
                               double dir_x,
                               double dir_y,
                               double dir_z,
                               std::vector< EntityHandle >& intersect_entity_handles,
                               /* int storage_order,*/
                               std::vector< double >& intersect_coords,
                               std::vector< double >& param_coords );

    // some new methods, that are needed

    ErrorCode createTag( const char* tag_name, int tag_num_type_values, int tag_type, Tag& tag_handle_out );

    Interface* moab_instance()
    {
        return _mbImpl;
    }

    ErrorCode getArrData( const moab::EntityHandle* entity_handles,
                          int entity_handles_size,
                          Tag tag_handle,
                          void* tag_values_out );

    ErrorCode setArrData( const EntityHandle* entity_handles,
                          int entity_handles_size,
                          Tag tag_handle,
                          const void* tag_values );

    ErrorCode getEntAdj( EntityHandle handle, int type_requested, Range& adjEnts );

    ErrorCode getEgFcSense( EntityHandle mbedge, EntityHandle mbface, int& sense );

    ErrorCode measure( const EntityHandle* moab_entities, int entities_size, double* measures );

    // to do
    ErrorCode getEntNrmlSense( EntityHandle face, EntityHandle region, int& sense );

    ErrorCode getEgEvalXYZ( EntityHandle edge,
                            double x,
                            double y,
                            double z,
                            double& on_x,
                            double& on_y,
                            double& on_z,
                            double& tngt_i,
                            double& tngt_j,
                            double& tngt_k,
                            double& cvtr_i,
                            double& cvtr_j,
                            double& cvtr_k );
    ErrorCode getFcEvalXYZ( EntityHandle face,
                            double x,
                            double y,
                            double z,
                            double& on_x,
                            double& on_y,
                            double& on_z,
                            double& nrml_i,
                            double& nrml_j,
                            double& nrml_k,
                            double& cvtr1_i,
                            double& cvtr1_j,
                            double& cvtr1_k,
                            double& cvtr2_i,
                            double& cvtr2_j,
                            double& cvtr2_k );

    ErrorCode getEgVtxSense( EntityHandle edge, EntityHandle vtx1, EntityHandle vtx2, int& sense );

    ErrorCode getEntURange( EntityHandle edge, double& u_min, double& u_max );

    ErrorCode getEntUtoXYZ( EntityHandle edge, double u, double& x, double& y, double& z );

    ErrorCode getEntTgntU( EntityHandle edge, double u, double& i, double& j, double& k );

    ErrorCode isEntAdj( EntityHandle entity1, EntityHandle entity2, bool& adjacent_out );

    ErrorCode split_surface_with_direction( EntityHandle face,
                                            std::vector< double >& xyz,
                                            double* direction,
                                            int closed,
                                            double min_dot,
                                            EntityHandle& oNewFace );
    // these new points will be on edges or triangles, if in interior of triangles
    ErrorCode split_surface( EntityHandle face,
                             std::vector< EntityHandle >& chainedEdges,
                             std::vector< EntityHandle >& splittingNodes,
                             EntityHandle& newFace );

    ErrorCode split_edge_at_point( EntityHandle edge, CartVect& point, EntityHandle& new_edge );

    ErrorCode split_edge_at_mesh_node( EntityHandle edge, EntityHandle node, EntityHandle& new_edge );

    ErrorCode split_bedge_at_new_mesh_node( EntityHandle b_edge,
                                            EntityHandle atNode,
                                            EntityHandle brokenEdge,
                                            EntityHandle& new_edge );
    // helper for cleaning the stuff
    // will be called if the topology is modified
    void clean();

    void delete_smooth_tags();

    // access to the geom topo tool
    // be careful what you do with it
    GeomTopoTool* get_gtt()
    {
        return this->_my_geomTopoTool;
    }

    ErrorCode create_volume_with_direction( EntityHandle newFace1,
                                            EntityHandle newFace2,
                                            double* direction,
                                            EntityHandle& volume );

    // get nodes from edge in order
    ErrorCode get_nodes_from_edge( EntityHandle gedge, std::vector< EntityHandle >& nodes );

    ErrorCode weave_lateral_face_from_edges( EntityHandle bEdge,
                                             EntityHandle tEdge,
                                             double* direction,
                                             EntityHandle& newLatFace );

    // chain "chain"-able edges
    // this could be useful if there are too many points / edges in the splitting
    // polyline
    // 2 edges are "chain"-able if
    /*
     *  1. they have the same adjacent faces
     *  2. their orientation is such as the end of one is the start of the other
     *  3. at meeting point, their tangents make an angle smaller then something
     *   (cos(angle) > cos (max_angle) = min_dot)
     */
    ErrorCode chain_edges( double min_dot );

    // 2 edges will be chained, along with modification of the topology
    ErrorCode chain_two_edges( EntityHandle edge, EntityHandle next_edge );

    ErrorCode get_vert_edges( EntityHandle edge, EntityHandle& v1, EntityHandle& v2 );

    void set_smooth()
    {
        _smooth = true;
    }

  private:
    ErrorCode initializeSmoothing();

    ErrorCode getAdjacentEntities( const EntityHandle from, const int to_dim, Range& adj_ents );

    ErrorCode compute_intersection_points( EntityHandle& face,
                                           EntityHandle from,
                                           EntityHandle to,
                                           CartVect& Dir,
                                           std::vector< CartVect >& points,
                                           std::vector< EntityHandle >& entities,
                                           std::vector< EntityHandle >& triangles );

    ErrorCode BreakTriangle( EntityHandle tri,
                             EntityHandle e1,
                             EntityHandle e3,
                             EntityHandle n1,
                             EntityHandle n2,
                             EntityHandle n3 );  // nodesAlongPolyline are on entities!

    ErrorCode BreakTriangle2( EntityHandle tri,
                              EntityHandle e1,
                              EntityHandle e2,
                              EntityHandle n1,
                              EntityHandle n2 );  // nodesAlongPolyline are on entities!

    void print_debug_triangle( EntityHandle triangle );

    ErrorCode create_new_gedge( std::vector< EntityHandle >& nodesAlongPolyline, EntityHandle& new_geo_edge );

    // used for splitting surfaces
    ErrorCode separate( EntityHandle face, std::vector< EntityHandle >& chainedEdges, Range& first, Range& second );

    ErrorCode smooth_new_intx_points( EntityHandle face, std::vector< EntityHandle >& chainedEdges );

    // having a node, split boundary along that node
    ErrorCode split_boundary( EntityHandle face, EntityHandle atNode );

    // see if the node is already part of a vertex set, do not create another one
    bool find_vertex_set_for_node( EntityHandle iNode, EntityHandle& oVertexSet );

    // if the splitting edge is not a loop, the original boundary edges will belong to
    // either original face, or new face
    // only the new geo edge (splitting) will be part of both, with the
    // orientation already decided
    //
    ErrorCode redistribute_boundary_edges_to_faces( EntityHandle face,
                                                    EntityHandle newFace,
                                                    std::vector< EntityHandle >& chainedEdges );

    // used as a way to isolate the faces after splitting
    ErrorCode set_neumann_tags( EntityHandle face, EntityHandle newFace );

    // split the quads if needed; it will create a new gtt, which will
    // contain triangles instead of quads
    ErrorCode split_quads();

    ErrorCode boundary_nodes_on_face( EntityHandle face, std::vector< EntityHandle >& boundary_nodes );

    ErrorCode boundary_mesh_edges_on_face( EntityHandle face, Range& boundary_mesh_edges );

    // used for splitting an edge
    ErrorCode split_internal_edge( EntityHandle& edge, EntityHandle& newVertex );
    // triangle split
    ErrorCode divide_triangle( EntityHandle triangle, EntityHandle& newVertex );
    Interface* _mbImpl;

    // this will be used during volume creation
    ErrorCode set_default_neumann_tags();

    ErrorCode chain_able_edge( EntityHandle edge, double min_dot, EntityHandle& next_edge, bool& chainable );

    GeomTopoTool* _my_geomTopoTool;
    bool _t_created;
    bool _smooth;
    bool _initialized;
    // these are initial ranges, that should not change during geometry gimmicks
    // those that are added are changing gtt ranges, but they are not yet "smoothed"
    // when new geometry is created, these ranges are not yet updated
    Range _my_gsets[5];
    // these are used only for smooth evaluations
    // these smooth faces and edges will be initialized after reading the file
    // the maps keep the link between EH in moab (geom sets) and
    //   their corresponding smooth counterparts
    std::map< EntityHandle, SmoothFace* > _faces;
    std::map< EntityHandle, SmoothCurve* > _edges;
    SmoothFace** _smthFace;
    SmoothCurve** _smthCurve;

    Range _piercedTriangles;  // triangles to delete
    Range _newTriangles;
    Range _piercedEdges;                                  // edges to delete
    std::map< EntityHandle, EntityHandle > _brokenEdges;  // this is a map between splitting nodes and edges that
    // are broken on the boundary, by the polyline; the edges will be deleted in the end
    // new edges?
};

}  // namespace moab
#endif /* FBENGINE_HPP_ */