MeshKit  1.0
CAMALPaver.cpp
Go to the documentation of this file.
00001 #include "meshkit/CAMALPaver.hpp"
00002 #include "meshkit/MeshScheme.hpp"
00003 #include "meshkit/ModelEnt.hpp"
00004 #include "moab/Interface.hpp"
00005 #include "moab/ReadUtilIface.hpp"
00006 #include "moab/Range.hpp"
00007 #include "meshkit/RegisterMeshOp.hpp"
00008 #include "CAMALSurfEval.hpp"
00009 #include "CAMALSizeEval.hpp"
00010 #include "CMLPaver.hpp"
00011 #include <vector>
00012 
00013 namespace MeshKit
00014 {
00015 
00016 moab::EntityType CAMALPaver::meshTps[] = {moab::MBVERTEX, moab::MBQUAD, moab::MBMAXTYPE};
00017 
00018 CAMALPaver::CAMALPaver(MKCore *mk_core, const MEntVector &me_vec)
00019         : MeshScheme(mk_core, me_vec)
00020 {
00021 }
00022 
00023 CAMALPaver::~CAMALPaver()
00024 {
00025 }
00026 
00027 void CAMALPaver::setup_this()
00028 {
00029     // need to constrain all edges to be even
00030   constrain_even();
00031   
00032     // then call setup_boundary, to set up edge meshers
00033   setup_boundary();
00034 
00035   // then ensure that this depends on all bounding edges being meshed,
00036   //   even if the edge meshers were already set up before setup_boundary
00037   ensure_facet_dependencies(false);
00038 }
00039 
00040 void CAMALPaver::execute_this()
00041 {
00042 
00043 #ifdef HAVE_FBIGEOM
00044   if (mentSelection.empty())
00045   {
00046     // create model ents from previous op
00047     create_model_ents_from_previous_ops();
00048     // now look at the latest SizingFunction, and set it or each model ent
00049     int latestIndexSF = 0; // maybe we would need to set it right
00050     for (MEntSelection::iterator sit = mentSelection.begin();
00051         sit != mentSelection.end(); sit++) {
00052         // make a me, for convenience
00053         ModelEnt *me = (*sit).first;
00054         me->sizing_function_index(latestIndexSF); // need to work on this one; how do we know?
00055     }
00056     // now, force setup of this node again, as we have added model entities to it
00057     setup_called(false);
00058     mk_core()->setup(false);
00059     // debug
00060     mk_core()->print_graph();
00061     // it may not be enough, we may have to execute the previous ops, that were just
00062     // created during setup... not very clean code;
00063     mk_core()->execute_before((GraphNode *) this);
00064   }
00065 #endif
00066   for (MEntSelection::iterator sit = mentSelection.begin(); sit != mentSelection.end(); sit++) {
00067       // make a me, for convenience
00068     ModelEnt *me = (*sit).first;
00069 
00070     if(me->get_meshed_state()>=COMPLETE_MESH)
00071       continue;
00072       // create a surface evaluator for this modelent, and a size evaluator
00073     CAMALSurfEval cse(me);
00074 
00075     SizingFunction * sz = mk_core()->sizing_function(me->sizing_function_index());
00076     if (!sz->variable())
00077       sz = NULL; // no function variable
00078 
00079     CAMALSizeEval mesize(me->mesh_interval_size(), sz);
00080           // make sure the size isn't negative
00081       // make sure the size isn't negative
00082     if (mesize.get_size() == -1) mesize.set_size(1.0);
00083     
00084     // assemble bounding mesh
00085     std::vector<moab::EntityHandle> bdy;
00086     std::vector<int> group_sizes, bdy_ids;
00087     me->boundary(0, bdy, NULL, &group_sizes);
00088 
00089       // convert the handles to integers for input to Paver
00090     moab::Range bdy_vrange;
00091     std::vector<double> coords;
00092     me->get_indexed_connect_coords(bdy, NULL, NULL, bdy_ids, coords, &bdy_vrange);
00093 
00094       // now construct the CAMAL mesher, and pass it initial conditions
00095     CMLPaver paver(&cse, &mesize);
00096     bool success = paver.set_boundary_mesh(bdy_vrange.size(), &coords[0], group_sizes.size(), &group_sizes[0], &bdy_ids[0]);
00097     if (!success)
00098       ECERRCHK(MK_FAILURE, "Trouble setting boundary mesh.");
00099 
00100       // ok, now generate the mesh
00101     int num_pts, num_quads;
00102     success = paver.generate_mesh(num_pts, num_quads);
00103     if (!success)
00104       ECERRCHK(MK_FAILURE, "Trouble generating quad mesh.");
00105 
00106     moab::Range &new_ents = (*sit).second;
00107     moab::ErrorCode rval;
00108 
00109       // resize the coords array, then get the coords of the new points
00110     assert(num_pts >= (int)bdy_vrange.size());
00111     if (num_pts > (int)bdy_vrange.size()) {
00112       coords.resize(3*(num_pts-bdy_vrange.size()));
00113       int pts_returned = paver.get_points_buf(coords.size(), &coords[0], bdy_vrange.size());
00114       if (pts_returned != num_pts-(int)bdy_vrange.size())
00115         ECERRCHK(MK_FAILURE, "Number of new points returned from Paver doesn't agree with previous value output.");
00116     
00117         // create the new vertices' entities on the face
00118       rval = mk_core()->moab_instance()->create_vertices(&coords[0], pts_returned, new_ents);
00119       MBERRCHK(rval, mk_core()->moab_instance());
00120     }
00121 
00122       // for quads, pre-allocate connectivity
00123     moab::ReadUtilIface *iface;
00124     rval = mk_core()-> moab_instance() -> query_interface(iface);
00125     MBERRCHK(rval, mk_core()->moab_instance());         
00126 
00127       //create the quads, get a direct ptr to connectivity
00128     moab::EntityHandle starth, *connect;
00129     rval = iface->get_element_connect(num_quads, 4, moab::MBQUAD, 1, starth, connect);
00130     MBERRCHK(rval, mk_core()->moab_instance());
00131 
00132       // read connectivity directly into that array, as int's
00133     int *connecti = (int*) connect;
00134     int quads_returned = paver.get_quads_buf(4*num_quads, connecti);
00135     if (quads_returned != num_quads)
00136       ECERRCHK(MK_FAILURE, "Number of new quads returned from Paver doesn't agree with previous value output.");
00137 
00138       // put vertex handles into an indexible array
00139     std::vector<moab::EntityHandle> bdy_vvec;
00140     std::copy(bdy_vrange.begin(), bdy_vrange.end(), std::back_inserter(bdy_vvec));
00141     std::copy(new_ents.begin(), new_ents.end(), std::back_inserter(bdy_vvec));
00142     
00143       // now convert vertex indices into handles in-place, working from the back
00144     for (int i = 4*num_quads-1; i >= 0; i--) {
00145       assert(connecti[i] >= 0 && connecti[i] < (int)bdy_vvec.size());
00146       connect[i] = bdy_vvec[connecti[i]];
00147     }
00148     
00149       // put new quads into new entity range, then commit the mesh
00150     new_ents.insert(starth, starth+num_quads-1);
00151     me->commit_mesh(new_ents, COMPLETE_MESH);
00152   }
00153 }
00154 
00155 } // namespace MeshKit
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines