00001 #ifndef _MESH_H_
00002 #define _MESH_H_
00003
00004 #include "Log.h"
00005 #include "fv_float.h"
00006 #include "../../utils/fv_assert.h"
00007 #include "../../include/fv_compiler.h"
00008 #include "../../include/BaseMesh.h"
00009 #include "mmh_intf.h"
00010 #include "aph_intf.h"
00011 #include "elem_tables.h"
00012 #include "BBox3D.h"
00013 #include "Color.h"
00014 #include "ElemId.hpp"
00015 #include "ArrayT.hpp"
00016 #include "MathHelper.h"
00017 #include "Enums.h"
00018
00019
00020
00021 #include<string>
00022 #include <iostream>
00023 #include<map>
00024 #include<string.h>
00025
00026 #define MAX_FIELDS
00027
00028 namespace FemViewer {
00029 class ModelControler;
00030 class Object;
00031 class VtxAccumulator;
00032 class RenderParams;
00033 class CutPlane;
00034 class Accelerator;
00035
00036 template<class T> class Ray;
00037
00038
00039
00040
00041 class Mesh : public BaseMesh
00042 {
00043 friend class ModelControler;
00044
00045 public:
00046
00047
00048 typedef ArrayT<id_t> arBndElems;
00049 typedef std::vector<ElemInfo> arElems;
00050
00051 typedef arBndElems::iterator BndElemsIter;
00052 typedef arBndElems::const_iterator BndElemsConstIter;
00053 typedef arBndElems::reference BndElemsRef;
00054 typedef arBndElems::const_reference BndElemsConstRef;
00055 typedef arElems::iterator arElemsIter;
00056 typedef arElems::const_iterator arElConstIter;
00057
00058 static const int tetra[4][3];
00059 static const int prizm[5][4];
00060 public:
00061
00062 explicit Mesh();
00063 explicit Mesh(const std::string& name_);
00064 virtual ~Mesh();
00065
00066 bool IsInit() const { return (!_arAllElements.empty()); }
00067
00068 public:
00069
00070
00071 const BBox3D& GetMeshBBox3D() const { return( _bbox); }
00072
00073
00074 template<typename T = double>
00075 int GetReferenceCoordinates(int nel,int type,int pdeg,int base,
00076 std::vector<fvmath::CVec3<T> >& coords,
00077 std::vector<short>& indices);
00078 template<typename T>
00079 int GetReferenceCoordinates(int nel,int type,int pdeg,int base,int side,
00080 std::vector<fvmath::CVec3<T> >& coords,
00081 std::vector<short>& indices);
00082 template<typename T = double>
00083 inline int GetElementCoordinates(int nel,int* Nodes,T* Coords) const {
00084 return BaseMesh::Get_el_node_coor(this->idx(),nel,Nodes,Coords);
00085 }
00086
00087 template<typename T = double>
00088 int GetElemenCoordinatesFromNodes(const int* nodes, T* Coord) const {
00089 int num_nno = *nodes++;
00090 int index = 0;
00091 while (num_nno > 0) {
00092 GetNodeCoor(*nodes++,&Coord[index]);
00093
00094 --num_nno;
00095 index += 3;
00096 }
00097 return num_nno;
00098 }
00099 inline int GetElementFaces(int nel,int* Faces,int* Orient) {
00100 return BaseMesh::Get_el_faces(this->idx(),nel,Faces,Orient);
00101 }
00102 inline int GetNextActiveElement(int nel) {
00103 return BaseMesh::Get_next_act_el(this->idx(),nel);
00104 }
00105 inline int GetMaxNodeId(void) const {
00106 return BaseMesh::Get_nmno(this->idx());
00107 }
00108
00109
00110 public:
00111
00112 int Init(const char* name);
00113 int Create(const int type = eSelectionCategory::All);
00114
00115 int Reload();
00116 int Update();
00117 void Reset();
00118
00119 BBox3D GetElemBBox3D (const int nodes[]) const {
00120 mfp_check_debug((nodes[0] == 6 || nodes[0] == 4), "Incorrect number of nodes: %d\n",nodes[0]);
00121 BBox3D bbox;
00122 Vec3d vrtx;
00123 for (int i = 1; i <= nodes[0]; ++i) {
00124 GetNodeCoor(nodes[i],vrtx.v);
00125 bbox += vrtx;
00126 }
00127
00128 return bbox;
00129 }
00130 unsigned GetNumVerticesSelected(int div);
00131 unsigned GetNumIndicesSelected(int div);
00132 bool Render(unsigned int options,Object* hObj,CutPlane* plane=NULL,arBndElems* vbnds=NULL);
00133
00134 private:
00135
00136
00137 eSelectionCategory m_selectType;
00138
00139 arElems _arAllElements;
00140 BBox3D _bbox, _bbox_cut;
00141 size_type _nno, _ned, _nfa, _nel;
00142 size_type _lnel;
00143 size_type _ianno;
00144 Accelerator* _paccel;
00145
00146 public:
00147
00148
00149
00150 size_type GetNumNodes() const { return _nno; }
00151 size_type GetNumEdges() const { return _ned; }
00152 size_type GetNumFaces() const { return _nfa; }
00153 size_type GetNumElems() const { return _nel; }
00154
00155 arElems& GetElems() { return _arAllElements; }
00156 const arElems& GetElems() const { return _arAllElements; }
00157
00158 size_type GetNumActiveNodes() const { return _nno - _ianno; }
00159
00160
00161 BBox3D ExtractMeshBBoxFromNodes(bool do_parallel=false);
00162
00163 int Select(std::vector<CutPlane>& vec_pcpls);
00164
00165 int Select(const bool boundaryOnly = false);
00166
00167 static uint32_t SetFaces(Mesh &rmesh);
00168
00169 unsigned int RenderWireframe(
00170 std::vector<BaseVertex>& out_vertices,
00171 std::vector<unsigned>& out_edge_indices) const;
00172
00173 unsigned int RenderWireframeCuts(const std::vector<CutPlane>& cut_planes,
00174 std::vector<Vertex>& outline_vertices,
00175 std::vector<Origin>& out_origins,
00176 std::vector<unsigned>& out_edge_indices,
00177 std::vector<int>& out_counts) const;
00178
00179
00180
00181 bool RenderWireframeCutted(Object* nObj,CutPlane* plane) const;
00182
00183 int GetBoundaryVertices(std::vector<BaseVertex>& nodes);
00184
00185 size_t GetElementOrigins(std::vector<Origin>& origins);
00186
00187
00188
00189 int GetOriginsOfBoundaryFaces(std::vector<BaseVertex>& origins,
00190 std::vector<BaseVertex>& nodes);
00191
00192 size_t GetVerticesOfCuts(const std::vector<CutPlane>& cut_planes,std::vector<BaseVertex>& vertices);
00193 template<typename T>
00194 inline int GetNodeCoor(int node,T* coords) const
00195 {
00196 return BaseMesh::Get_node_coor(this->idx(),node,coords);
00197 }
00198
00199 inline int GetEdgeNodes(int edge,int* Edge) const
00200 {
00201 return BaseMesh::Get_edge_nodes(this->idx(),edge,Edge);
00202 }
00203
00204 inline int GetFaceoriginf(int ned,int nodes[],float Coords[]) const
00205 {
00206 return 0;
00207 }
00208
00209 inline int GetElementCoordsf(int nel,int nodes[],float Coords[]) const
00210 {
00211 double lCoords[3*MMC_MAXELVNO];
00212 int nno = Get_el_node_coor(this->idx(),nel,nodes,lCoords);
00213 for (int i(0); i < nno; ++i) {
00214 Coords[3*i ] = static_cast<float>(lCoords[3*i]);
00215 Coords[3*i+1] = static_cast<float>(lCoords[3*i+1]);
00216 Coords[3*i+2] = static_cast<float>(lCoords[3*i+2]);
00217 }
00218 return nno;
00219 }
00220
00221 inline int GetElementOriginf(int nel,int nodes[],float Coords[]) const
00222 {
00223 double lCoords[3*MMC_MAXELVNO];
00224 double lOrigin[] = { 0.0, 0.0 ,0.0};
00225
00226
00227 int nno = Get_el_node_coor(this->idx(),nel,nodes,lCoords);
00228
00229 double inv_nno = 1.0 / (double)nno;
00230 for (int i(0); i < nno; ++i) {
00231 lOrigin[0] += lCoords[3*i];
00232 lOrigin[1] += lCoords[3*i+1];
00233 lOrigin[2] += lCoords[3*i+2];
00234
00235 }
00236
00237 Coords[0] = static_cast<float>(lOrigin[0]*inv_nno);
00238 Coords[1] = static_cast<float>(lOrigin[1]*inv_nno);
00239 Coords[2] = static_cast<float>(lOrigin[2]*inv_nno);
00240
00241 return nno;
00242 }
00243
00244 inline int GetElementCoordsd(int nel,int nodes [],double Coords[]) const
00245 {
00246 int nno = Get_el_node_coor(this->idx(),nel,nodes,Coords);
00247 return nno;
00248 }
00249 inline void GetFaceNeigInfo(int Fa,int Fa_neig[]) const {
00250 Get_face_neig(this->idx(),Fa,Fa_neig,NULL,NULL,NULL,NULL,NULL);
00251 }
00252 inline int GetElementFaces(int El,int Faces[],int Orient[]) const {
00253 return Get_el_faces(this->idx(),El,Faces,Orient);
00254 }
00255
00256 inline int GetNodeStatus(int node) const
00257 {
00258 return BaseMesh::Get_node_status(this->idx(),node);
00259 }
00260
00261 inline int GetEdgeStatus(int edge) const
00262 {
00263 return BaseMesh::Get_edge_status(this->idx(),edge);
00264 }
00265 inline int GetElemStatus(int nel) const {
00266 return BaseMesh::Get_el_status(this->idx(),nel);
00267 }
00268
00269 template<typename T>
00270 inline int GetNextActiveElement(T nel = T(0)) const {
00271 return BaseMesh::Get_next_act_el(this->idx(),nel);
00272 }
00273
00274 size_t PackElementCoord(std::vector<fvmath::Vec4<CoordType> >& ElemPrismCoords,
00275 bool onlyboundary = false);
00276
00277 void PackElementPlanes(std::vector<fvmath::Vec4<CoordType> >& ElemPlanes,
00278 bool onlyboundary = false);
00279
00280 static void FillArrayWithElemCoords(const Mesh* pMesh,CoordType ElemCoords[]);
00281
00282 static uint32_t FillArrayWithIndicesOfElemNodes(const Mesh *pMesh,int Indices[]);
00283
00284 static void ConvertNodes(const Mesh *pMesh, float NodeCoords[]);
00285 private:
00286
00287 Mesh(const Mesh&);
00288 Mesh& operator=(const Mesh&);
00289 };
00290
00291
00292 template<>
00293 inline int Mesh::GetNodeCoor<float>(int node,float* coords) const
00294 {
00295 double lcoords[3];
00296 if(BaseMesh::Get_node_coor(this->idx(),node,lcoords) <0) return(-1);
00297 coords[0] = static_cast<float>(lcoords[0]);
00298 coords[1] = static_cast<float>(lcoords[1]);
00299 coords[2] = static_cast<float>(lcoords[2]);
00300 return(1);
00301 }
00302
00303 template<typename T>
00304 int Mesh::GetReferenceCoordinates(int nel,int type,int pdeg,int base_q,std::vector<fvmath::CVec3<T> >& coords,std::vector<short>& indices)
00305 {
00306
00307 const T * refCoords = (type == 4 ? &XlocTetra[0] : &XlocPrizm[0]);
00308
00309 coords.clear();
00310 indices.clear();
00311
00312 if (base_q > APC_BASE_COMPLETE_DG || pdeg == 101)
00313 {
00314 for (int i=0;i<type;i++) {
00315 int kk=3*i;
00316
00317 coords.push_back(fvmath::CVec3<T>((refCoords[kk]),
00318 (refCoords[kk+1]),
00319 (refCoords[kk+2])));
00320 indices.push_back(i);
00321 }
00322
00323
00324
00325
00326 }
00327 else
00328 {
00329
00330 int ptsx, ptsz;
00331 if (base_q == APC_BASE_TENSOR_DG)
00332 {
00333 ptsx = pdeg % 100 + 1;
00334 ptsz = pdeg / 100 + 1;
00335 }
00336 else
00337 {
00338 ptsx = pdeg + 1;
00339 ptsz = pdeg + 1;
00340 }
00341
00342 T dl1 = T(1.0) / (T)ptsx;
00343 T dl2 = dl1;
00344 T dl3 = T(1.0) / (T)ptsz;
00345
00346
00347
00348 int ino = 0;
00349 for (int i=0; i < ptsx; i++)
00350 {
00351 int ptsy = ptsx - i;
00352 for (int j=0; j < ptsy; j++)
00353 {
00354 for (int k=0; k < ptsz; k++)
00355 {
00356 const T x = i*dl1;
00357 const T y = j*dl2;
00358 const T z = 2*k*dl3 - (T)1.0;
00359 const T x1 = x + dl1;
00360 const T y1 = y + dl2;
00361 const T z1 = z + 2*dl3;
00362 for (int itr=0; itr < 2; itr++)
00363 {
00364
00365 if (itr==0 || j<(ptsy-1)) {
00366 if (itr==0) {
00367
00368 coords.push_back(fvmath::CVec3<T>(x,y,z));
00369 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00370 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00371 coords.push_back(fvmath::CVec3<T>(x,y,z1));
00372 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00373 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00374 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00375 ino+=6;
00376 }
00377 else {
00378
00379 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00380 coords.push_back(fvmath::CVec3<T>(x1,y1,z));
00381 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00382 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00383 coords.push_back(fvmath::CVec3<T>(x1,y1,z1));
00384 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00385 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00386 ino+=6;
00387 }
00388 }
00389 }
00390 }
00391 }
00392 }
00393 }
00394
00395 return (int)(indices.size());
00396
00397 }
00398
00399
00400 template<typename T>
00401 int Mesh::GetReferenceCoordinates(int nel,int type,int pdeg,int base_q,int side,std::vector<fvmath::CVec3<T> >& coords,std::vector<short>& indices)
00402 {
00403
00404 coords.clear();
00405 indices.clear();
00406
00407 if (base_q > APC_BASE_COMPLETE_DG || pdeg == 101)
00408 {
00409
00410 const T * refCoords = (type == 4 ? &XlocTetra[0] : &XlocPrizm[0]);
00411 for (int i=0;i<type;i++) {
00412 int kk=3*i;
00413 coords.push_back(fvmath::CVec3<T>(static_cast<T>(refCoords[kk++]),
00414 static_cast<T>(refCoords[kk++]),
00415 static_cast<T>(refCoords[kk ])));
00416 indices.push_back(i);
00417 }
00418 }
00419 else
00420 {
00421
00422 int ptsx, ptsz;
00423 if (base_q == APC_BASE_TENSOR_DG)
00424 {
00425 ptsx = pdeg % 100 + 1;
00426 ptsz = pdeg / 100 + 1;
00427 }
00428 else
00429 {
00430 ptsx = pdeg + 1;
00431 ptsz = pdeg + 1;
00432 }
00433
00434 T dl1 = T(1.0) / (T)ptsx;
00435 T dl2 = dl1;
00436 T dl3 = T(1.0) / (T)ptsz;
00437
00438
00439 fvmath::Vec3<T> v;
00440 int ino = 0, k = 0;
00441 switch(side)
00442 {
00443
00444 case 1: k = ptsz - 1;
00445 case 0:
00446 {
00447 for (int i=0; i < ptsx; i++)
00448 {
00449 int ptsy = ptsx - i;
00450 for (int j=0; j < ptsy; j++)
00451 {
00452 for (int itr=0; itr < 2; itr++)
00453 {
00454 const T x = i*dl1;
00455 const T y = j*dl2;
00456 const T z = 2*k*dl3 - (T)1.0;
00457 const T x1 = x + dl1;
00458 const T y1 = y + dl2;
00459 const T z1 = z + 2*dl3;
00460
00461 if (itr==0 || j<(ptsy-1)) {
00462 if (itr==0) {
00463
00464 coords.push_back(fvmath::CVec3<T>(x,y,z));
00465 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00466 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00467 coords.push_back(fvmath::CVec3<T>(x,y,z1));
00468 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00469 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00470 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00471 ino+=6;
00472 }
00473 else {
00474
00475 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00476 coords.push_back(fvmath::CVec3<T>(x1,y1,z));
00477 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00478 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00479 coords.push_back(fvmath::CVec3<T>(x1,y1,z1));
00480 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00481 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00482 ino+=6;
00483 }
00484 }
00485 }
00486 }
00487 }
00488 } break;
00489 case 2:
00490 {
00491 int j = 0;
00492 for (int i=0; i < ptsx; i++)
00493 {
00494 for (int k=0; k < ptsz; k++)
00495 {
00496 const T x = i*dl1;
00497 const T y = j*dl2;
00498 const T z = 2*k*dl3 - (T)1.0;
00499 const T x1 = x + dl1;
00500 const T y1 = y + dl2;
00501 const T z1 = z + 2*dl3;
00502 coords.push_back(fvmath::CVec3<T>(x,y,z));
00503 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00504 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00505 coords.push_back(fvmath::CVec3<T>(x,y,z1));
00506 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00507 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00508 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00509 ino+=6;
00510 }
00511 }
00512 } break;
00513 case 5:
00514 {
00515 int i = 0;
00516 for (int j=0; i < ptsx; j++)
00517 {
00518 for (int k=0; k < ptsz; k++)
00519 {
00520 const T x = i*dl1;
00521 const T y = j*dl2;
00522 const T z = 2*k*dl3 - (T)1.0;
00523 const T x1 = x + dl1;
00524 const T y1 = y + dl2;
00525 const T z1 = z + 2*dl3;
00526 coords.push_back(fvmath::CVec3<T>(x,y,z));
00527 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00528 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00529 coords.push_back(fvmath::CVec3<T>(x,y,z1));
00530 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00531 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00532 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00533 ino+=6;
00534 }
00535 }
00536 } break;
00537 case 4:
00538 {
00539 for (int i=0,j=ptsx; i < ptsx; i++,j-=i)
00540 {
00541 for (int k=0; k < ptsz; k++)
00542 {
00543 const T x = i*dl1;
00544 const T y = j*dl2;
00545 const T z = 2*k*dl3 - (T)1.0;
00546 const T x1 = x + dl1;
00547 const T y1 = y + dl2;
00548 const T z1 = z + 2*dl3;
00549 coords.push_back(fvmath::CVec3<T>(x,y,z));
00550 coords.push_back(fvmath::CVec3<T>(x1,y,z));
00551 coords.push_back(fvmath::CVec3<T>(x,y1,z));
00552 coords.push_back(fvmath::CVec3<T>(x,y,z1));
00553 coords.push_back(fvmath::CVec3<T>(x1,y,z1));
00554 coords.push_back(fvmath::CVec3<T>(x,y1,z1));
00555 for (int ii=0;ii<6;ii++) indices.push_back(ino+ii);
00556 ino+=6;
00557 }
00558 }
00559 } break;
00560 }
00561 }
00562
00563 return (int)(indices.size());
00564
00565 }
00566
00567 template<>
00568 inline int Mesh::GetElementCoordinates<float>(int nel,int* Nodes,float* Coords) const {
00569 const unsigned dim = 3*MMC_MAXELVNO;
00570 double lcoords[dim];
00571 int result = BaseMesh::Get_el_node_coor(this->idx(),nel,Nodes,lcoords);
00572 if (Coords) {
00573 for (unsigned i(0);i<dim;++i) {
00574 Coords[i] = static_cast<float>(lcoords[i]);
00575 }
00576 }
00577 return result;
00578 }
00579
00580 }
00581
00582 #endif
00583